Bug 31311 - sdb doesn't report unhandled exceptions in static cctors as an unhandled exception
Summary: sdb doesn't report unhandled exceptions in static cctors as an unhandled exce...
Alias: None
Product: Runtime
Classification: Mono
Component: Debugger (show other bugs)
Version: unspecified
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Zoltan Varga
Depends on:
Reported: 2015-06-23 05:21 UTC by Gert Jan Schoneveld
Modified: 2015-07-10 15:44 UTC (History)
5 users (show)

See Also:
Is this bug a regression?: ---
Last known good build:


Description Gert Jan Schoneveld 2015-06-23 05:21:10 UTC
using System;
using System.Collections.Generic;

namespace DictionaryInitBug
	class MainClass
		static Dictionary<string, int> dict = new Dictionary<string, int> {
			{ "A", 1 },
			{ "A", 2 }

		public static void Main (string[] args)
			Console.WriteLine ("finished");

In mono the above app hangs. In MS .NET it finishes, but I would expect an exception because of the duplicate key.

(without the 'static', it does finish without exception)
Comment 1 Marek Safar 2015-06-25 10:02:06 UTC
I cannot reproduce the behaviour with Mono 4.2 or master.

System.TypeInitializationException: The type initializer for 'DictionaryInitBug.MainClass' threw an exception. ---> System.ArgumentException: An item with the same key has already been added.
  at System.ThrowHelper.ThrowArgumentException (ExceptionResource resource) <0x19a9290 + 0x00054> in <filename unknown>:0
  at System.Collections.Generic.Dictionary`2[TKey,TValue].Insert (System.Collections.Generic.TKey key, System.Collections.Generic.TValue value, Boolean add) <0x1bce260 + 0x000f7> 23657 in <filename unknown>:0
  at System.Collections.Generic.Dictionary`2[TKey,TValue].Add (System.Collections.Generic.TKey key, System.Collections.Generic.TValue value) <0x1bcd850 + 0x00033> 23644 in <filename unknown>:0
  at DictionaryInitBug.MainClass..cctor () <0x776ef0 + 0x00067> in <filename unknown>:0
Comment 2 Gert Jan Schoneveld 2015-06-25 10:45:38 UTC
Sorry for the incomplete information. Running from the command line works, but from Xamarin doesn't (Debug nor Release).

I'm using Xamarin Version 5.9.3 (build 1). Xamarin says Mono is version 4.0.1. The process that is hanging in the Terminal is mono-sgen.
Comment 3 Marek Safar 2015-06-26 06:20:07 UTC
It hangs for me only when using XS debugger.
Comment 4 Zoltan Varga 2015-06-26 16:42:33 UTC
This looks like an XS problem, here is the end of the debugger log:
[0xb0215000] Resuming vm, suspend count=0...
[0xa0fa41d4] Resumed.
[0xa0fa41d4] Suspending vm...
[0xa0fa41d4] Interrupting 0xb0101000...
[0xb0101000] Received interrupt while at 0x907a8a0a, treating as suspended.
[0xa0fa41d4] Sent 1 events EXCEPTION(4), suspend=2.
[0xa0fa41d4] Suspended.
[dbg] Command OBJECT_REF(GET_INFO) [40][at=23171].
[dbg]   send class [System.TypeInitializationException]
[dbg] Command TYPE(GET_INFO) [41][at=23171].
[dbg]   recv class [System.TypeInitializationException]
[dbg]   send assembly [mscorlib][console-app.exe][1]
[dbg]   send class [System.SystemException]
[dbg] Command THREAD(GET_FRAME_INFO) [42][at=23172].
Frames for 0x6e4120(tid=a0fa41d4):
[dbg] Command VM(ALL_THREADS) [43][at=2317c].
[dbg] Command OBJECT_REF(GET_INFO) [44][at=2317c].
[dbg]   send class [System.Threading.Thread]
[dbg] Command THREAD(GET_ID) [45][at=2317c].
[dbg] Command THREAD(GET_NAME) [46][at=2317c].
So XS gets the exception event, but it doesn't enter paused mode.
Comment 5 David Karlaš 2015-06-29 02:39:58 UTC

XS hangs because Thread.GET_FRAME_INFO.Length == 0 and can't get access to Frame, which is used for evaluating values... Is it possible to to get frames also if exceptions happen before Main() method is called?

If not... I can fix XS to better handle cases with FrameCount==0...
Comment 6 Zoltan Varga 2015-07-07 17:25:09 UTC
Is XS supposed to stop when the application throws an exception ? If I add an exception catchpoint, this works fine.
Comment 7 Zoltan Varga 2015-07-07 17:57:14 UTC
So what happens is that an exception is thrown, the runtime catches it, and turns it into a TypeInitializationException, that exception is thrown before Main() is entered, and that becomes an unhandled exception. But the original throw site is gone by the time this happens, so the runtime cannot stop there.

Note You need to log in before you can comment on or make changes to this bug.