Bug 13828 - mdb scoping information is broken
Summary: mdb scoping information is broken
Alias: None
Product: Runtime
Classification: Mono
Component: Debugger ()
Version: unspecified
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Zoltan Varga
Depends on:
Reported: 2013-08-07 14:22 UTC by Jeffrey Stedfast
Modified: 2013-09-06 18:10 UTC (History)
7 users (show)

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

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Jeffrey Stedfast 2013-08-07 14:22:20 UTC
From Alan:

Variable scoping is completely broken with mono 3.2.0 and Xamarin Studio master.

If you ever have two variables with the same name but in different scopes SDB/XS always gives you the wrong value when probing the value of that variable. For example:

try {
    throw new Exception ();
} catch (FileNotFoundException ex) {

} catch (Exception ex) {
    Console.WriteLine (ex);

If you breakpoint the Console.WriteLine XS/sdb will tell you that 'ex' is null. If you rename 'FileNotFoundException ex' to 'FileNotFoundException ex2' then the issue goes away. The same thing happens in this context:

foreach (var v in enumerable) {
    Console.WriteLine (v);
if (foo) {
    foreach (var v in other_enumerable) {
        Console.WriteLine (v);

In the above context you always get the last value from the first enumeration and you do *not* get the real value of 'v' as is in 'other_enumerable'. This happens with both the immediate window and the debugger tooltips.

Follow-up by Zoltan:

This looks like an mcs problem.

For this test program:

using System;
public class A {
	public static int Main (String[] args) {
		foreach (var v in args)
		foreach (var v in args)
		return 0;

The generated .mdb file contains the following (using mcs/tools/mdbdump):

    <method token="0x6000003" signature="System.Int32 A::Main(System.String[])">
        <entry il="0x0" row="10" col="41" file_ref="1" />
        <entry il="0x1" row="11" col="3" file_ref="1" />
        <entry il="0x2" row="11" col="21" file_ref="1" />
        <entry il="0xb" row="11" col="12" file_ref="1" />
        <entry il="0xf" row="11" col="21" file_ref="1" />
        <entry il="0x1c" row="13" col="3" file_ref="1" />
        <entry il="0x1d" row="13" col="21" file_ref="1" />
        <entry il="0x28" row="13" col="12" file_ref="1" />
        <entry il="0x2e" row="13" col="21" file_ref="1" />
        <entry il="0x3f" row="15" col="3" file_ref="1" />
        <entry il="0x47" row="16" col="3" file_ref="1" />
        <entry name="v" il_index="0" scope_ref="0" />
        <entry name="v" il_index="3" scope_ref="0" />
        <entry index="0" start="0xf" end="0xf" />
        <entry index="1" start="0x2e" end="0x2e" />

Notice that both scopes have identical start/end offsets, and the locals refer to the same scope.
Comment 1 Jeffrey Stedfast 2013-08-07 14:25:10 UTC
just filed this bug because a customer has hit this issue as well.
Comment 2 Zoltan Varga 2013-08-07 14:31:19 UTC
I think this only affects some variables, like exceptions/foreach vars, simple user variables seem to work.
Comment 3 Marek Safar 2013-08-07 15:11:22 UTC
The case with foreach and no block just single statement is different case (fixed in master now). But it still does not work even if mdb info is correct.

Test case provided by Alan

using System;
public class A {
	public static int Main (String[] arg)
		var enumerable = "abcd";
		foreach (var v in enumerable) {
			Console.WriteLine (v);

		foreach (var v in enumerable) {
			Console.WriteLine (v);

		return 0;

Generated symbol file

<?xml version="1.0" encoding="utf-8"?>
    <file id="1" name="test-901.cs" checksum="ff4a72459d082fd05a83fc5e06a173a8" />
    <method token="0x6000001" signature="System.Void A::.ctor()">
      <sequencepoints />
      <locals />
      <scopes />
    <method token="0x6000002" signature="System.Int32 A::Main(System.String[])">
        <entry il="0x0" row="4" col="2" file_ref="1" />
        <entry il="0x1" row="5" col="3" file_ref="1" />
        <entry il="0x7" row="6" col="3" file_ref="1" />
        <entry il="0x8" row="6" col="21" file_ref="1" />
        <entry il="0x11" row="6" col="12" file_ref="1" />
        <entry il="0x13" row="6" col="21" file_ref="1" />
        <entry il="0x19" row="6" col="33" file_ref="1" />
        <entry il="0x1a" row="7" col="4" file_ref="1" />
        <entry il="0x1b" row="7" col="12" file_ref="1" />
        <entry il="0x20" row="8" col="3" file_ref="1" />
        <entry il="0x21" row="6" col="21" file_ref="1" />
        <entry il="0x27" row="6" col="21" file_ref="1" />
        <entry il="0x31" row="10" col="3" file_ref="1" />
        <entry il="0x32" row="10" col="21" file_ref="1" />
        <entry il="0x3d" row="10" col="12" file_ref="1" />
        <entry il="0x41" row="10" col="21" file_ref="1" />
        <entry il="0x48" row="10" col="33" file_ref="1" />
        <entry il="0x49" row="11" col="4" file_ref="1" />
        <entry il="0x4b" row="11" col="12" file_ref="1" />
        <entry il="0x50" row="12" col="3" file_ref="1" />
        <entry il="0x51" row="10" col="21" file_ref="1" />
        <entry il="0x5b" row="10" col="21" file_ref="1" />
        <entry il="0x65" row="14" col="3" file_ref="1" />
        <entry il="0x6d" row="15" col="2" file_ref="1" />
        <entry name="enumerable" il_index="0" scope_ref="0" />
        <entry name="v" il_index="1" scope_ref="1" />
        <entry name="v" il_index="4" scope_ref="4" />
        <entry index="0" start="0x7" end="0x31" />
        <entry index="1" start="0x19" end="0x21" />
        <entry index="2" start="0x1a" end="0x20" />
        <entry index="3" start="0x31" end="0x65" />
        <entry index="4" start="0x48" end="0x51" />
        <entry index="5" start="0x49" end="0x50" />
Comment 4 Zoltan Varga 2013-08-12 07:31:08 UTC
How does the last testcase fail ?
Comment 5 Zoltan Varga 2013-08-20 18:26:35 UTC
Comment 6 Rodrigo Kumpera 2013-08-21 12:31:13 UTC
Comment 7 Marek Safar 2013-08-26 04:45:19 UTC
Hmm, it seems to work with master now
Comment 8 Alan McGovern 2013-09-06 18:07:33 UTC
What release of mono should contain this fix? I still experience the bug in the latest release. Mono JIT compiler version 3.2.2 ((no/a0fc6ba Thu Aug 15 15:32:12 EDT 2013)
Comment 9 Rodrigo Kumpera 2013-09-06 18:10:32 UTC
Alan, try 3.2.3.