Mike Stall's .NET Debugging Blog

Notes on Managed Debugging, ICorDebug, and random .NET stuff

Browse by Tags

Tagged Content List
  • Blog Post: Virtual code execution via IL interpretation

    As Soma announced, we just shipped VS2010 Beta1 . This includes dump debugging support for managed code and a very cool bonus feature tucked in there that I’ll blog about today. Dump-debugging (aka post-mortem debugging) is very useful and a long-requested feature for managed code. The downside is that...
  • Blog Post: Managed Dump debugging support for Visual Studio and ICorDebug

    This is the longest I've gone without blogging, but our PDC announcements have stuff way too cool to stay quiet about. If you saw PDC , you've head that the CLR Debugging API, ICorDebug, will support dump-debugging . This enables any ICorDebug-based debugger (including Visual Studio and MDbg) to debug...
  • Blog Post: Breaking changes in ICorDebug from 1.1 to 2.0.

    Here are some random notes about specific ICorDebug breaking changes between .NET v1.1 (Everett) and .NET 2.0 (Whidbey). (I came across these as I was cleaning out old documents in preparation for my upcoming move). This would have been more timely 2 years ago, but better late than never. This can be...
  • Blog Post: Things that what work in Native-debugging that don't work in Interop-debugging.

    Interop-debugging (mixed-mode) is managed + native debugging combined. Well, sort of. Native and managed debugging have very different paradigms. Native debugging tends to own the whole process, while managed debugging tends to require control of the whole process while only exposing a managed view to...
  • Blog Post: Debugger.Break()

    System.Diagnostics.Debugger.Break() is a BCL method that causes a program to issue a User Breakpoint when run under the debugger. This translates to a Break() debug event on ICorDebugManagedCallback. (Not to be confused with Breakpoint(), which corresponds to actual breakpoints. Yeah, we could have given...
  • Blog Post: ICorDebugFunction is 1:1 with the IL

    In CLR 1.0, there was a simple invariant between IL code blob, and native code blob. It was either 1:0 if the code wasn't jitted, or 1:1 if it was. Method tokens (module scope, mdMethodDef) were also 1:1 with the IL blobs. 1:1 is a nice relationship. Each side can just point to the other without needing...
  • Blog Post: ICorPublish does not cross the 32/64 bit boundary

    I mentioned earlier that ICorDebug does not cross the 32/64 boundary . If you want to debug a 32-bit managed app, you need to use a 32-bit version of the ICorDebug interfaces (or Mdbg). If you want to debug a 64-bit managed app, you need a 64-bit savy debugger. When you debug a 64-bit managed app in...
  • Blog Post: UpdateModuleSysmbols comes on attach

    I forgot about UpdateModuleSysmbols when I described the fake debug events sent on attach . This event is sent after LoadModule and is what delivers the symbols for dynamically generated code. This lets you debug code generated with ref.emit when you attach to a process. Note that if the debuggee only...
  • Blog Post: Tips for writing an Interop Debugger

    I've had a growing number of people inquire about how to write an interop-debugger with ICorDebug. I strongly advise anybody considering writing an interop-debugger to reconsider for reasons listed here . However, for those who can not be dissuaded, and promise to do something really really cool, here...
  • Blog Post: You don't want to write an interop debugger.

    I've had a growing number of people inquire about how to write an interop-debugger with ICorDebug. My goal here is to discourage you from doing that. (This reminds me of one of my college classes. On day one, the acting-Prof launched into a great sermon "Why you should drop this class now". It turned...
  • Blog Post: Fake attach event ordering

    When you attach to a managed debuggee (via ICorDebug::DebugActiveProcess), ICorDebug generates a set of fake events designed to bring the debugger up to the current state. The motivation is that it pumps the debugger just as if the debugger was always attached. Native debugging does the same thing. ...
  • Blog Post: LCG + Debuggability, and your feedback

    I mentioned earlier that you can debug Reflection.Emit code . Unfortunately, Ref.Emit code can't be unloaded unless you unload the entire appdomain. I wanted to lay out the current landscape, and then get feedback about possible solutions. In Whidbey, we added Light Weight CodeGen (LCG) , which are...
  • Blog Post: ICorDebugValue vs. System.Object

    System.Object represents a managed object within a process. ICorDebugValue is the debugger's representation of a System.Object within the debuggee process. The key here is that the debugger and debuggee processes are ideally fully isolated from each other. For example They could both be running...
  • Blog Post: LoadClass events are usually meaningless

    ICorDebug notifies a debugger when a managed class is loaded via LoadClass debug event. For dynamic-modules, this is useful because it tells you that you just baked a new type and so may have new code to bind breakpoints in (see here for debugging ref-emit ). But for everything else, this is useless...
  • Blog Post: An example of an API versioning problem.

    Here's an example of an API versioning problem. In general: Anytime you take two separate concepts and tie them together based off some current implementation assumption, you're going to get trouble when that assumption is broken. The specific example : You currently (as of .NET 2.0) can't unload...
  • Blog Post: Empty implementation of ICorDebugManagedCallback

    I have to implement the ICorDebugManagedCallback interfaces. I wrote up a stub implementation (that just E_NOTIMPLs all the methods) and am posting it here for reference. It's pretty tedious, so I'll post it here and then never have to write that again. As a language design point, it's definitely...
  • Blog Post: You can't cast from a pointer to a managed object in the debugger

    During native debugging, it's common to cast a raw pointer value to a given type. Eg, in the expression window, do: (Foo*) 0x12345; You may have noticed that you can't do this in managed code. This is a restriction at the ICorDebug (CLR) level. Some of the motivations for this are: Appdomains...
  • Blog Post: Managed vs. Native debugging APIs

    FxCop has a great rule ( UseManagedEquivalentsOfWin32Api ) to tell you about managed APIs that exist instead of trying to pinvoke out. I'm writing a native debugger in managed code (more on this later), and FxCop was telling me to use the managed debugging APIs instead of pinvoke out to the native...
  • Blog Post: Debugger.Log vs. OutputDebugString

    Both Debugger.Log and OutputDebugString have some key similarities: The both log string for debugging purposes Both have thread-affinity. (The debugger can find out which thread logged) Data is piped through with no additional semantics in the debugger pipeline. But they have some key...
  • Blog Post: Stop the debuggee to poke at it

    In ICorDebug, most operations are only available when the debuggee is stopped. (This was asked here ). Many things will fail with CORDBG_E_PROCESS_NOT_SYNCHRONIZED if you call them when the process is running. The motivation is: 1) Correctness : trying to query a running debuggee is not safe and may...
  • Blog Post: The stop count and trivia

    ICorDebug maintains a stop-count, and so if you call ICorDebugProcess::Stop() twice in a row, the 1st stop does the real asynchronous-break , and the 2nd stop is basically a nop that just increments a counter. You'll then need to call ICorDebugProcess::Continue() twice. The first Continue() call just...
  • Blog Post: Trivia about Set-next-Statement (SetIp)

    The poor-man's version of Set-Next-Statement (aka, SetIp) is to just forcibly set the instruction pointer register (eip on x86) to the instruction you want to execute next. However, this naive approach has several problems that ICorDebug's SetIp solves: - the naive approach doesn't update variable homes...
  • Blog Post: What to expect when you Attach, Async-Break

    Don't assume that if you have a thread doing a spin-wait, that you can attach / asynchronously-break ("async-break") and your debugger will immediately stop at the spin-wait. When you attach to a debuggee or async-break while debugging, the debuggee's threads could be anywhere. Even if you attach...
  • Blog Post: Doing Detach with ICorDebug

    Detaching a managed-debugger is somewhat complicated at the ICorDebug API level. In a perfectly-friendly API, you could just call "ICorDebugProcess::Detach" and be done with it. With managed-debugging, there are two main constraints and the hresults (in parenthesis) that you'll get for violating them...
  • Blog Post: Jan is on MSDN TV talking about MDbg

    Jan Stranik is on MSDN TV talking about MDbg , the managed-debugging sample written in C#. See the video here . Jan wrote most of MDbg, and handle a lot of hard problems about getting a working debugger in managed code. He gives a brief overview of managed-debugging and of Mdbg's architecture, including...
Page 1 of 3 (73 items) 123