-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Description
Consider the following code (lambdageek@144c3df):
public static bool got_to_the_end_of_outer_finally = false;
public static bool got_to_the_end_of_inner_finally = false;
class StaticConstructor6 {
static StaticConstructor6 ()
{
try {
Setup6 ();
} finally {
Driver.got_to_the_end_of_outer_finally = true;
}
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void Setup6 () {
try {
} finally {
Driver.sema1.Release ();
Thread.Sleep (1000); /* hopefully we get woken up here */
Driver.got_to_the_end_of_inner_finally = true;
}
}
}If a thread running the cctor StaticConstructor6 is aborted by a call to thread.Abort() when it is in the finally block in Setup6, we should get to the end of both finally clauses and the class StaticConstructor6 should be viable.
But that doesn't happen. Instead the thread is self-aborted (which bypasses the abort protection from mono_runtime_class_init_full and StaticConstruct6 is marked as not viable.
The reason is because the main thread ends up calling mono_install_handler_block_guard which sets a flag on the child thread at the end up the inner finally block, which causes the child thread to self-abort:
Lines 11543 to 11546 in 8c3d7c8
| NEW_BBLOCK (cfg, dont_throw); | |
| MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, abort_exc->dreg, 0); | |
| MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, dont_throw); | |
| mono_emit_jit_icall (cfg, mono_thread_self_abort, NULL); |
This fails in both with coop and async suspend.