digitalmars.D.bugs - [Issue 5317] New: Assertion is not work in a function called by std.concurrency.spawn
- d-bugmail puremagic.com (45/45) Dec 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (10/10) Feb 03 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (19/19) Feb 04 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (25/25) May 24 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (26/26) May 25 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (47/47) Jun 04 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (6/6) Jun 04 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
- d-bugmail puremagic.com (28/28) Aug 30 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5317
http://d.puremagic.com/issues/show_bug.cgi?id=5317 Summary: Assertion is not work in a function called by std.concurrency.spawn Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Severity: normal Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: rayerd.wiz gmail.com PST --- // a.d import std.stdio, std.concurrency; void f() { // try // { writeln("1"); assert(false); // } // catch(Throwable t) // { // writeln(t); // throw t; // } } void main() { auto tid = spawn(&f); readln(); } $ dmd a.d 1 <=== Needs assertion failure message here! I found that assertion is not work in a function called by spawn. You will get the following result if you remove comment keywords. $ dmd a.d 1 core.exception.AssertError a(7): Assertion failure -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5317 Sean Kelly <sean invisibleduck.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |sean invisibleduck.org --- This works for me using the current revision. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 03 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5317 PST --- Oh really? import std.stdio, std.concurrency, std.conv; void f() { int a = to!int("2"); assert(a == 1); } void main() { auto tid = spawn(&f); readln(); } Does this code throw AssertError? I was not able to observe such behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 04 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5317 Andrej Mitrovic <andrej.mitrovich gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrej.mitrovich gmail.com 20:15:58 PDT --- I can't reproduce your first test case, but I can reproduce your second one. It seems as if the main thread eats up the exceptions. Maybe it has to do with buffered console output which isn't flushed properly? Here's another test case: import std.stdio, std.concurrency, std.conv, core.thread; void f() { assert(0); } void main() { auto tid = spawn(&f); Thread.sleep( dur!("seconds")( 2 ) ); } If you remove the call to sleep, the assertion will throw. So while the main thread is locked, something is blocking the exceptions from propagating? I've no idea.. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 24 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5317 --- When the assertion isn't propagated, what's likely happening is that the thread instance is being discarded because the thread is complete. If the app terminates quickly enough then it beats the spawned thread to termination and thread_joinAll() finds the Error waiting to be re-thrown. At the moment, D has fairly lax rules for propagating exceptions that caused a thread to terminate--it's assumed that if you care about the result of a thread you'll call join(), which will always re-throw the exception unless told not to. But if you don't retain a reference to the thread then its result will remain unknown. The exception to this rule is that a spawned thread will receive word that its owner has terminated, and linked threads will notify one another on termination. I could retain these uncaught exceptions and re-throw them to the main thread on app termination, but I don't see much utility in it. If something horrible happens in a thread then the user either wants to shutdown the entire app immediately for fear of memory corruption (which increasingly unlikely with thread-local static data), or he wants specific interested parties to be notified that the thread terminated unexpectedly (which is handled by linking via std.concurrency), or he doesn't care. Perhaps I should add a hook so the user can supply an uncaughtExceptionHandler? I'd avoided doing this in the past because it would interact weirdly with the current behavior of join() re-throwing uncaught exceptions, but it's an option. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 25 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5317 12:33:33 PDT --- This might not be directly relevant to this bug report, but I thought I'd share the story anyway. I currently have this in one of my projects: An extern(C) callback is passed to a device driver. The user-code then calls driver.start(), and the driver starts a new high-priority/ISR routine which calls the callback at some predetermined rate. Now, in my main() function I have this (pseudocode): driver.start() scope(exit) driver.stop(); // Calling this before app exit on started drivers is crucial while (engineRunning) { } // shared bool of the engine state That works well for the user thread, if an exception is thrown in the user thread scope exit will be ran and the driver is released. But if in the callback thread an exception is thrown and is uncaught it will shut down my application but it won't call driver.stop(), because it's in a different thread which main doesn't directly know about. I've had this happen to me several times with ASIO Audio drivers. Most of the times, the app will quit but appear frozen in taskbar and the device driver won't get released even if I do a cold-reboot of my soundcard (it's external with its own power source). It then takes a few minutes or a pc-reboot for the driver to actually get released. But worse things have happened, I've had several BSODs as well. It wasn't obvious to me what was going on until I've realized that driver.stop() never gets called. So now my current workaround is to wrap any code in the callback with a try..catch: extern(C) callback(args..) { try { realCallback(args); } catch (Throwable) { engineRunning = false; } } If an exception is thrown the app can call driver.stop() (since the user thread keeps checking the state ofr the shared engineRunning boolean), and then the app can quit safely. Quitting forcefully on any errors might not be the best thing to do. But maybe my use-case is a special one, and this doesn't happen that frequently outside of using device drivers or other types of external resources. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 04 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5317 12:34:49 PDT --- s/taskbar/taskmanager -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 04 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5317 Sean Kelly <sean invisibleduck.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |WONTFIX --- If your API requires a cleanup routine to be run then you can either expect the user to trap any errors and call the cleanup (and break if they fail to do so) or you can provide a failsafe cleanup mechanism like the one you've outlined below. I'm inclined to think that your approach is the right one. Regarding exception propagating in general... I think there are two reasonable default behaviors. One is to do as now where the exception is trapped and re-thrown when join is called, based on the assumption that if a programmer cares about the result of a thread he'll explicitly join it at some point (and holding that reference will prevent premature cleanup of the terminated thread's exception, if any). The other is to terminate the app if an unhanded exception terminates a thread. I'm inclined to favor the former behavior because it puts more control in the hands of the programmer, admittedly at the risk of Bad Things if the app is just poorly written and the unhandled exception is something important. Since std.concurrency provides options for the owner thread to receive a message when spawned threads terminate (via link), I'm going to consider this issue as addressed. If you have specific ideas for how the current behavior could be enhanced, please open a new ticket. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 30 2011