Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Class should be viable even if cctor is aborted in nested finally clause #7588

@lambdageek

Description

@lambdageek

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:

mono/mono/mini/method-to-ir.c

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions