WinDBG and Delphi exceptions

When debugging a Delphi XE2 app in WinDBG, NTSD or a related debugger, it is very helpful to be able to display the actual class name and error message from an exception in the debugger.  The following script will do that for you automatically:

sxe -c "da poi(poi(poi(ebp+1c))-38)+1 L16;du /c 100 poi(poi(ebp+1c)+4)" 0EEDFADE

The command can be broken down as follows:

  • sxe adds a filter for an exception event, enabled by default.  sxd would add the filter, disabled.
  • -c tells the debugger to run the quoted commands when the event occurs.
  • da displays an “ANSI” (non-Unicode) string from memory in the debugger
  • ebp+1c is a pointer to the exception record
  • poi(poi(ebp+1c))-38 points to the non-Unicode string returned by TObject.ClassName, internally known as Self.vmtClassName.
  • du displays a Unicode string from memory in the debugger.
  • poi(ebp+1c)+4 is a pointer to the Unicode string for Exception.Message.  As with all Delphi strings, you could go back 4 bytes to get the string length, but for now we limit the length to 100 characters with the /c parameter. 
  • 0EEDFADE is the exception code for a Delphi exception (another example is C0000005 for Access Violation).

These offsets are correct for Delphi XE2.  For Delphi 7, the relevant command is:

sxe -c "da poi(poi(poi(ebp+1c))-2c)+1 L16;da /c 100 poi(poi(ebp+1c)+4)" 0EEDFADE

Other versions of Delphi will have similar offsets, a little spelunking should yield the appropriate offsets pretty quickly!

11 thoughts on “WinDBG and Delphi exceptions

  1. No, I’m sure this would not be right for x64 apps. But that sounds like a good subject for another blog post. I’ll look into it when I get a moment.

  2. Hi Marc,

    You’re right, WinDbg reports a memory access error when filtering the exception for a 64 bit program.

    Anyway thank you again for your post. That’s the first useful thing I read about using WinDbg with Delphi apps 🙂

Leave a Reply to Marc Durdin Cancel reply

Your email address will not be published. Required fields are marked *