digitalmars.D.learn - Unittest hangs on completion
- David Zhang (11/11) Dec 29 2016 Hi,
- Stefan Koch (3/14) Dec 29 2016 It would be very helpful if you could provide example code that
- David Zhang (6/8) Dec 29 2016 I'd love to, but I'm not actually sure just what it is that
- David Zhang (14/23) Dec 29 2016 Ok, so after further fiddling, it seems to originate from here:
- Steven Schveighoffer (4/14) Dec 29 2016 Where does the "All unit tests have been completed successfully."
- David Zhang (12/16) Dec 29 2016 I should have mentioned that I use dub then, shouldn't I? Anyway,
- Steven Schveighoffer (14/29) Dec 29 2016 Looks like that comes from here:
- David Zhang (8/21) Dec 29 2016 Huh, shouldn't this problem have manifested itself earlier then?
- Steven Schveighoffer (7/31) Dec 30 2016 This is one of those very fragile and seemingly random types of things.
- David Zhang (5/10) Dec 30 2016 So, what should I do with it? I'd submit a bug report, but I
- Steven Schveighoffer (5/13) Dec 30 2016 Can you debug and see where it's hanging?
- Seb (7/18) Dec 30 2016 Dustmite (https://github.com/CyberShadow/DustMite) is your friend!
- David Zhang (12/32) Dec 30 2016 There wouldn't happen to be an alternative on windows without
- Steven Schveighoffer (7/9) Dec 30 2016 What is actually happening is that the D main function returns. Then the...
- David Zhang (24/31) Dec 30 2016 I've tried manually reducing the code to find the problem. This
- David Zhang (17/17) Dec 30 2016 Extracting everything into a main() also causes the application
- rikki cattermole (18/34) Dec 30 2016 As it should, current is never reassigned.
- David Zhang (5/22) Dec 30 2016 Thanks for your response. So next is never null, and thus there
- rikki cattermole (7/31) Dec 30 2016 No, my understand is thus:
- David Zhang (3/10) Dec 30 2016 Huh, alright. I see what you mean. I'll keep this in mind.
- Steven Schveighoffer (15/40) Jan 01 2017 This is correct. Rewriting the code as rikki has would be correct code.
Hi, I've noticed recently, that whenever I unittest, it program hangs either at the very end, or right before they start. When using vanilla unit tests, the program appears to hang after the "All unit tests have been completed successfully." message, and I have to force to program to exit. However, when I use unit-threaded for my unit testing, it gets to the "Running unit tests in dirs ["."]" and then refuses to do anything more. Strangely enough, sometimes commenting out one or two tests seems to fix the issue with unit-threaded, only to resurface when I write a new test. Just what is going on?
Dec 29 2016
On Thursday, 29 December 2016 at 20:27:21 UTC, David Zhang wrote:Hi, I've noticed recently, that whenever I unittest, it program hangs either at the very end, or right before they start. When using vanilla unit tests, the program appears to hang after the "All unit tests have been completed successfully." message, and I have to force to program to exit. However, when I use unit-threaded for my unit testing, it gets to the "Running unit tests in dirs ["."]" and then refuses to do anything more. Strangely enough, sometimes commenting out one or two tests seems to fix the issue with unit-threaded, only to resurface when I write a new test. Just what is going on?It would be very helpful if you could provide example code that triggers that behavior.
Dec 29 2016
On Thursday, 29 December 2016 at 20:33:33 UTC, Stefan Koch wrote:It would be very helpful if you could provide example code that triggers that behavior.I'd love to, but I'm not actually sure just what it is that breaks it. I can provide the git repo for one of them though though: https://gitlab.com/Straivers/Weave https://gitlab.com/Straivers/Weave.git
Dec 29 2016
On Thursday, 29 December 2016 at 20:50:54 UTC, David Zhang wrote:On Thursday, 29 December 2016 at 20:33:33 UTC, Stefan Koch wrote:Ok, so after further fiddling, it seems to originate from here: [from the list class] safe unittest { class A { int foo; } auto list = new List!A(); list ~= [new A, new A, new A]; assert(list.findElement(null).result == null); } However, commenting it out, and replacing it with another block (the test immediately below it, causes it to hang too, or error out and crash without any error message.It would be very helpful if you could provide example code that triggers that behavior.I'd love to, but I'm not actually sure just what it is that breaks it. I can provide the git repo for one of them though though: https://gitlab.com/Straivers/Weave https://gitlab.com/Straivers/Weave.git
Dec 29 2016
On 12/29/16 3:27 PM, David Zhang wrote:Hi, I've noticed recently, that whenever I unittest, it program hangs either at the very end, or right before they start. When using vanilla unit tests, the program appears to hang after the "All unit tests have been completed successfully." message, and I have to force to program to exit. However, when I use unit-threaded for my unit testing, it gets to the "Running unit tests in dirs ["."]" and then refuses to do anything more. Strangely enough, sometimes commenting out one or two tests seems to fix the issue with unit-threaded, only to resurface when I write a new test. Just what is going on?Where does the "All unit tests have been completed successfully." message come from? That's not standard D, which prints nothing. -Steve
Dec 29 2016
On Friday, 30 December 2016 at 00:44:50 UTC, Steven Schveighoffer wrote:Where does the "All unit tests have been completed successfully." message come from? That's not standard D, which prints nothing. -SteveI should have mentioned that I use dub then, shouldn't I? Anyway, this is what I get: C:\Users\David\Projects\weave>dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86. weave ~master: building configuration "__test__library__"... Linking... Running .\bin\__test__library__.exe All unit tests have been run successfully.
Dec 29 2016
On 12/29/16 7:49 PM, David Zhang wrote:On Friday, 30 December 2016 at 00:44:50 UTC, Steven Schveighoffer wrote:Looks like that comes from here: https://github.com/dlang/dub/blob/master/source/dub/dub.d#L577 I have serious doubts that this is the correct way to run tests, as share ctors are supposed to have run BEFORE unit tests are allowed to. It's quite possible (and likely) that unit tests are running before critical other shared ctors have completed, which is why something isn't working. In any case, it looks like the unit tests have run, and run successfully, and then main has run, and then it's the teardown of the runtime that's hanging. I'm not 100% certain, because I don't know exactly how this code comes into play -- it's a string in this file. -SteveWhere does the "All unit tests have been completed successfully." message come from? That's not standard D, which prints nothing.I should have mentioned that I use dub then, shouldn't I? Anyway, this is what I get: C:\Users\David\Projects\weave>dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86. weave ~master: building configuration "__test__library__"... Linking... Running .\bin\__test__library__.exe All unit tests have been run successfully.
Dec 29 2016
On Friday, 30 December 2016 at 01:25:50 UTC, Steven Schveighoffer wrote:Looks like that comes from here: https://github.com/dlang/dub/blob/master/source/dub/dub.d#L577 I have serious doubts that this is the correct way to run tests, as share ctors are supposed to have run BEFORE unit tests are allowed to. It's quite possible (and likely) that unit tests are running before critical other shared ctors have completed, which is why something isn't working. In any case, it looks like the unit tests have run, and run successfully, and then main has run, and then it's the teardown of the runtime that's hanging. I'm not 100% certain, because I don't know exactly how this code comes into play -- it's a string in this file. -SteveHuh, shouldn't this problem have manifested itself earlier then? Why only now? I don't remember this happening previously. At the very least I'm pretty sure I first encountered it last week. Unless something in DMD was patched? But then there'd be no way I'm the only one encountering this problem, and there don't appear to be any issues on github's tracker.
Dec 29 2016
On 12/29/16 8:33 PM, David Zhang wrote:On Friday, 30 December 2016 at 01:25:50 UTC, Steven Schveighoffer wrote:This is one of those very fragile and seemingly random types of things. A change in code, a change in linker order, maybe even random chance, can cause it to fail or not.Looks like that comes from here: https://github.com/dlang/dub/blob/master/source/dub/dub.d#L577 I have serious doubts that this is the correct way to run tests, as share ctors are supposed to have run BEFORE unit tests are allowed to. It's quite possible (and likely) that unit tests are running before critical other shared ctors have completed, which is why something isn't working. In any case, it looks like the unit tests have run, and run successfully, and then main has run, and then it's the teardown of the runtime that's hanging. I'm not 100% certain, because I don't know exactly how this code comes into play -- it's a string in this file.Huh, shouldn't this problem have manifested itself earlier then? Why only now? I don't remember this happening previously.At the very least I'm pretty sure I first encountered it last week. Unless something in DMD was patched? But then there'd be no way I'm the only one encountering this problem, and there don't appear to be any issues on github's tracker.It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it. -Steve
Dec 30 2016
On Friday, 30 December 2016 at 14:12:35 UTC, Steven Schveighoffer wrote:[snip] It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it. -SteveSo, what should I do with it? I'd submit a bug report, but I don't know how to isolate the bug, and thus where to submit it. Really, I'd just be happy knowing if it's my code or not.
Dec 30 2016
On 12/30/16 1:03 PM, David Zhang wrote:On Friday, 30 December 2016 at 14:12:35 UTC, Steven Schveighoffer wrote:Can you debug and see where it's hanging? Note that you can use dub -v I believe to see all the lines being executed by the dub process. -Steve[snip] It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it.So, what should I do with it? I'd submit a bug report, but I don't know how to isolate the bug, and thus where to submit it. Really, I'd just be happy knowing if it's my code or not.
Dec 30 2016
On Friday, 30 December 2016 at 18:03:44 UTC, David Zhang wrote:On Friday, 30 December 2016 at 14:12:35 UTC, Steven Schveighoffer wrote:Dustmite (https://github.com/CyberShadow/DustMite) is your friend! Specifically with a timeout command (e.g. https://github.com/CyberShadow/DustMite/wiki/Running-commands-with-a-timeout) and checking whether your reduced code is still timing out (exit code of timeout is 124). If you set it to sth. reasonable (e.g. 10s) and use multiple threads (e.g. -j32) it shouldn't take that long to have a reduced code example.[snip] It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it. -SteveSo, what should I do with it? I'd submit a bug report, but I don't know how to isolate the bug, and thus where to submit it. Really, I'd just be happy knowing if it's my code or not.
Dec 30 2016
On Friday, 30 December 2016 at 20:59:30 UTC, Seb wrote:On Friday, 30 December 2016 at 18:03:44 UTC, David Zhang wrote:There wouldn't happen to be an alternative on windows without installing cygwin would there? I don't have access to a linux machine at the moment. Steven, the process hangs after the "All unit tests have been successfully", after which the process is supposed to exit immediately. -- Running .\bin\__test__library__.exe All unit tests have been run successfully. ^C --On Friday, 30 December 2016 at 14:12:35 UTC, Steven Schveighoffer wrote:Dustmite (https://github.com/CyberShadow/DustMite) is your friend! Specifically with a timeout command (e.g. https://github.com/CyberShadow/DustMite/wiki/Running-commands-with-a-timeout) and checking whether your reduced code is still timing out (exit code of timeout is 124). If you set it to sth. reasonable (e.g. 10s) and use multiple threads (e.g. -j32) it shouldn't take that long to have a reduced code example.[snip] It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it. -SteveSo, what should I do with it? I'd submit a bug report, but I don't know how to isolate the bug, and thus where to submit it. Really, I'd just be happy knowing if it's my code or not.
Dec 30 2016
On 12/30/16 4:31 PM, David Zhang wrote:Steven, the process hangs after the "All unit tests have been successfully", after which the process is supposed to exit immediately.What is actually happening is that the D main function returns. Then the D runtime tears down everything, including joining all threads, running all module static dtors, terminating the GC, etc. Then it returns to the OS the exit code. So it's likely somewhere in there that it's hanging. -Steve
Dec 30 2016
On Friday, 30 December 2016 at 22:42:07 UTC, Steven Schveighoffer wrote:What is actually happening is that the D main function returns. Then the D runtime tears down everything, including joining all threads, running all module static dtors, terminating the GC, etc. Then it returns to the OS the exit code. So it's likely somewhere in there that it's hanging. -SteveI've tried manually reducing the code to find the problem. This is what I've got. I'm not sure how to reduce it further. class Foo { ~this() { S* next, current; next = current = _foo; while (next) { next = current.next; theAllocator.dispose(current); } } void insert(Range)(Range range) { foreach (e; range) _foo = theAllocator.make!S(_foo); } S* _foo; struct S { S* next; } } unittest { auto list = new Foo(); list.insert([1, 2, 3, 4]); }
Dec 30 2016
Extracting everything into a main() also causes the application to hang. ie: struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next, current; next = current = _foo; while (next) { next = current.next; theAllocator.dispose(current); }
Dec 30 2016
On 31/12/2016 2:52 PM, David Zhang wrote:Extracting everything into a main() also causes the application to hang. ie: struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next, current; next = current = _foo; while (next) { next = current.next; theAllocator.dispose(current); }As it should, current is never reassigned. You only need one var, next. Of course I didn't read the entire thread chain so, I'm probably missing something. import std.experimental.allocator; void main() { struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next; next = _foo; while(next !is null) { auto nextT = next.next; theAllocator.dispose(next); next = nextT; } }
Dec 30 2016
On Saturday, 31 December 2016 at 02:03:07 UTC, rikki cattermole wrote:As it should, current is never reassigned. You only need one var, next. Of course I didn't read the entire thread chain so, I'm probably missing something. import std.experimental.allocator; void main() { struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next; next = _foo; while(next !is null) { auto nextT = next.next; theAllocator.dispose(next); next = nextT; } }Thanks for your response. So next is never null, and thus there is an infinite loop, correct? If so, why does dub indicate that all tests are complete?
Dec 30 2016
On 31/12/2016 3:32 PM, David Zhang wrote:On Saturday, 31 December 2016 at 02:03:07 UTC, rikki cattermole wrote:No, my understand is thus: next = current.next; theAllocator.dispose(current); When current is deallocated, current is pointing to free'd memory. After that point it should be segfaulting when you try to access it *I think*.As it should, current is never reassigned. You only need one var, next. Of course I didn't read the entire thread chain so, I'm probably missing something. import std.experimental.allocator; void main() { struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next; next = _foo; while(next !is null) { auto nextT = next.next; theAllocator.dispose(next); next = nextT; } }Thanks for your response. So next is never null, and thus there is an infinite loop, correct? If so, why does dub indicate that all tests are complete?
Dec 30 2016
On Saturday, 31 December 2016 at 02:36:01 UTC, rikki cattermole wrote:No, my understand is thus: next = current.next; theAllocator.dispose(current); When current is deallocated, current is pointing to free'd memory. After that point it should be segfaulting when you try to access it *I think*.Huh, alright. I see what you mean. I'll keep this in mind.
Dec 30 2016
On 12/30/16 9:32 PM, David Zhang wrote:On Saturday, 31 December 2016 at 02:03:07 UTC, rikki cattermole wrote:This is correct. Rewriting the code as rikki has would be correct code. However, I would also caution about your original code that deallocates inside a destructor. You cannot access nor try to free reference members of a GC-allocated class inside the destructor. It's explicitly cautioned against here: http://dlang.org/spec/class.html#destructors "Furthermore, the order in which the garbage collector calls destructors for unreference objects is not specified. This means that when the garbage collector calls a destructor for an object of a class that has members that are references to garbage collected objects, those references may no longer be valid. This means that destructors cannot reference sub objects."As it should, current is never reassigned. You only need one var, next. Of course I didn't read the entire thread chain so, I'm probably missing something. import std.experimental.allocator; void main() { struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next; next = _foo; while(next !is null) { auto nextT = next.next; theAllocator.dispose(next); next = nextT; } }Thanks for your response. So next is never null, and thus there is an infinite loop, correct?If so, why does dub indicate that all tests are complete?Because dub is running the tests and then running your main. Unit tests run before main does. -Steve
Jan 01 2017