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!