5

I've got a weird situation where something is setting the TopMost property of the main MDI form to true. After much trial and error we're pretty sure this must be coming from a third party library but it's not in any places that we would expect.

It would be VERY easy to fix this if we could just set the application to break in the debugger whenever this property was set. However this property is defined by the WinForms libraries so we can't just put a breakpoint in there.

For cases where you're working with a library that you don't have the source code for this would be invaluable but I fear there is no solution to this problem since Data Breakpoints are not supported for managed languages (as far as I know).

So, in C# is there a way that you know of to break when a property gets changed when you don't have access to place a breakpoint in the setter? This could easily solve many edge case issues where things get changed for reasons you can't anticipate.

Mohgeroth
  • 1,617
  • 4
  • 32
  • 47

2 Answers2

8

It is possible to set breakpoints on code you don't own. Since TopMost is a property, all you have to do is putting a breakpoint on the setter.

Just open the "breakpoints" panel in Visual Studio (Debug -> Windows -> Breakpoints), click on "New -> Function Breakpoint" then type:

System.Windows.Forms.Form.set_TopMost

Run your application (make sure the symbol are loaded), and profit.

Note that you also need to make sure that "Just my code" is disabled. Go in Tools -> Options -> Debugging -> General, and uncheck "Enable Just My Code".

Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94
  • Oh I didn't realize that properties were transformed into this, that's awfully convenient! Do you happen to have the knowledge base on this so I can understand how and why it performs this change? – Mohgeroth May 03 '17 at 17:30
  • Also for future reference, does this imply that anytime this property is changed on any instance of this object (Form in this case) that the breakpoint would be hit? – Mohgeroth May 03 '17 at 17:33
  • @Mohgeroth The breakpoint will be hit everytime the setter is called, on any instance. If something directly access the underlying field, the breakpoint won't be hit – Kevin Gosse May 03 '17 at 18:56
  • 1
    @Mohgeroth As for the property being transformed to get_xxx/set_xxx methods, that's just something I discovered from poking around profiling traces and decompiled assemblies. It's a bit hard to find documentation on this, but there's some mention of it in other questions on SO: http://stackoverflow.com/questions/16718772/is-the-method-naming-for-property-getters-setters-standardized-in-il – Kevin Gosse May 03 '17 at 18:58
0
  1. Go to Tools > Options > Debugging > General and uncheck Enable Just My Code checkbox.

  2. Identify which function you need to set breakpoint on. It's not always that obvious - one thing you can do is to write set given property value in code, start debugging, then right click and select Go To Disassembly, you will see listing like this:

disassembly view

So in this case I wanted to set breakpoint on PresentationTraceSources.DataBindingSource.Switch.Level - property change, but I needed to set breakpoint on System.Diagnostics.SourceSwitch.set_Level.

  1. Debug > New Breakpoint > Function Breakpoint.

Type function name where to set breakpoint. In my case it was System.Diagnostics.SourceSwitch.set_Level.

Please notice that you will need to set same breakpoint for each new session.

TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62