Mike Stall's .NET Debugging Blog

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

Browse by Tags

Tagged Content List
  • Blog Post: Why are you caching data?

    There are multiple reasons to cache data. For example, are you caching because of a performance issue of because of a correctness issue? Know which, and comment it at the spot doing the cache. If it's performance, the idea is that you have some expensive operation, and you save the results so that you...
  • Blog Post: Why threading is hard

    Anybody who says "I can write correct multi threaded code" probably should be saying "I don't test my multi-threaded code". It is very difficult to write correct multi-threaded code. One way to appreciate this is various "find-the-bug" pop quizzes that occasionally come up. Another approach that I'll...
  • Blog Post: Simple Tool for text substitution plus Design questions

    I wrote a simple C# app to do text substitution. It takes a (key,value) mapping and then replaces any keys in between {% ... %} with their value. It's a really trivial app. But it also quickly opens a Pandora's box of design questions. It takes an xml file that provides the (key,value) , such as values...
  • Blog Post: Making "Required properties" less annoying

    Be wary of "required" properties that must be explicitly set correctly in order for the object to function (especially if it's not obvious). I recently got burned by this, and it's certainly a frustrating problem to diagnose. In my case, the function didn't give an error and just silently nop instead...
  • Blog Post: Questions you should ask before using a callback / delegate

    I just got burned by using callbacks in a multi-threaded app. I've rewritten the part to avoid callbacks, but for my good-deed-of-the-day, I wanted to issue a word of warning. Before you can safely use a callback / delegate / virtual function, particularly in multi-threaded code, you should answer...
  • Blog Post: How to start a console app in a new window, the parent's window, or no window

    The ProcessStartInfo.CreateNoWindow property says "Gets or sets a value indicating whether to start the process in a new window." and later " true to start the process without creating a new window to contain it; otherwise, false . The default is false " But that's misleading and wrong because it's meaning...
  • Blog Post: How can you force clients to use your APIs properly?

    It's tough to make a client use your API correctly. It's especially tough to get clients to not do things that appear to work 90% of the time, but aren't correct and break down in that remaining 10%. It's even harder for things that work 100% of the time in the current version but may break in the future...
  • 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: Passing Property values by reference

    I was wondering how well properties were integrated into C#. For example, C# lets you use += with the properties. It's easy enough to convert: MyProperty += 4 to MyProperty = MyProperty + 4 However, C# won't let you pass a property in as a ref parameter. For example: void PassIntByRef(ref int x) ...
  • Blog Post: Design Implications from boring details

    You can discern a lot of information about an API from what appear to be subtle or irrelevant details For example, each ICorDebug object has a logical parent. (See here for a brief explanation of the different ICorDebug interfaces). Here's a chart: ICorDebugProcess ICorDebugThread ICorDebugChain...
  • Blog Post: What to do with a feature that only works 90% of the time?

    Imagine when you're designing a feature if there was an operation that was very useful 90% of the time; but the other 10% of the time it was provably and innately unsafe (either crashed, deadlocked, or gave back garbage). By "innately unsafe", I mean there's some intrinsic quality about the feature's...
  • Blog Post: Our policy on policy

    ... is that we don't want the platform making policy decisions. In general, any time the platform makes an arbitrary policy decision, half of our clients will think it's the wrong one. This why we're trying to shift our architecture focus to enabling features instead of directly implementing them . ...
  • Blog Post: Document properties that don't round-trip.

    I personally think most API documentation is lame and either leaves critical behavior qualities unspecified, or don't comment when standard assumptions may be broken. One example is not documenting object lifespans . Another example is that you'd normally expect setting a property and then immediately...
  • Blog Post: Enable vs. Implement

    There's a key distinction between a platform (like the CLR debugging services) enabling a scenario instead of actually implementing the scenario. Implementing a scenario means we provide specific functionality for a scenario. For example, the CLR debugging services provide explicit breakpoints and...
  • Blog Post: Types of Names

    We've had some design discussions where we've come across 4 types of string names. These terms came mostly from discussing debugging symbols, but they extend to naming in general. Type Example for function Example for filename Fully qualified names (FQN): An FQN is a well...
  • Blog Post: How should a generic method be displayed?

    I've heard several different opinions about how the debugger should display a generic method in the callstack. Say you have a method Class<T>::Method<S>(...). Say you have 3 instances, of with (T=int, S=string), (T=int, S=object), and (T=float, S=object). What's more natural display? 1.)...
  • Blog Post: Simple example of an API design flaw.

    Here’s a simple example of an API design flaw in ICorDebug. (ICorDebug is the API that Visual Studio / MDbg and other debuggers use to debug managed code). Here’s the background knowledge: 1) When a thread first executes actual IL (whether jitted or ngenned) code, ICorDebug issues an ICorDebugManagedCallback...
  • Blog Post: Source-level step-in is not well defined.

    One of the things that causes us grief is that source-level step-in (F11 in VS) is not a well-defined operation. Some examples : Consider the following call to static method foo: MyClass.foo(...); Now offhand, you'd expect the step-in to land in the method MyClass.foo(). But what if that invokes a class...
  • Blog Post: Clearly Document Object Lifespans

    I’ve started commenting on API design lessons we’ve learned from mistakes in ICorDebug. I previously blogged about dangers of doing complicated work in IUnknown::Release or C++ destructors. Another API design point is [update: include 2nd half of sentence]: Clearly describe object lifespans in terms...
  • Blog Post: Don’t do “complicated” work in Release().

    BradA has been talking about API design guidelines, which reminds me of a bunch of subtle API design lessons we’ve learned from mistakes made in ICorDebug. I’ve started a list and it’s depressingly long. As I blog about these, I’ll pull samples from ICorDebug, but you don’t need to know ICorDebug to...
  • Blog Post: Debugging any .Net language

    The CLR is a cross-language platform, so it follows the CLR-debugging services are also cross-language. This means any 3 rd -party can write their own managed debugger, and that can debug any managed app produced by any 3 rd -party compiler. (This holds true provided we’re talking about debugger-only...
  • Blog Post: Hardmode vs. Softmode

    User-mode debugging can be split into 2 models: Hardmode and Softmode. Hardmode means using the native debugging APIs. This means all threads are stopped by the OS at each debug event and there’s no helper-thread . The debugger does not need to run any code in the debuggee’s process. Softmode means not...
  • Blog Post: Why you can’t do Edit-and-Continue on Dynamically generated code

    I gave a brief example of how you can debug dynamically generated code (e.g., code generated via Reflection.Emit). Jamie Cansdale observed that you can’t use EnC with dynamically generated code. This was a conscious choice. Here are some reasons for it: It was not a core EnC scenario . For v2.0...
  • Blog Post: What is Interop-Debugging?

    (This is an excerpt from an internal document I wrote explaining what is Interop-Debugging (aka Mixed Mode) and how does it work under the covers) General Debugging background. When a process is being debugged, it generates debug-events which a debugger can listen and respond to. These events include...
  • Blog Post: You can’t attach 2 debuggers to 1 process

    For both managed-only and native-only debugging, you can only attach 1 debugger to a process. Why? The native debugger steals debug events from underneath the managed debugger. This confuses the managed-debugger and will cause it to crash. The native debugger has no way of coordinating with the managed...
Page 1 of 2 (30 items) 12