« Back to home

Debugging a Debugger Deadlock

While I still use VisualStudio 2005 Team System for most of my development, I want to make sure that cfix works properly with VisualStudio 2008 as well. To test that, I recently started a Windows 2003 Server VM, installed VCExpress 2008 and cfix and attempted to run an example project in the VC debugger. As long as no assertions fired, everything seemed fine. I then altered the example’s source code so that one of the assertion would fail, ran it in the debugger – and waited.

Read more »

cfix 1.1 may experience hangs when used in the VisualStudio 2008 debugger

When used in conjunction with the VisualStudio 2008 debugger, cfix may hang indefinitely as soon as an assertion fails. The reason for this behavior is a Symbol Server-caused deadlock between the debugger and cfix. I am going to discuss the details of this deadlock in a separate post. Until a new version of cfix is available, you can work around this problem as follows: Go to the cfix installation directory and rename or delete symsrv.

Read more »

Thread 0:0 is special

Thread IDs uniquely identify a thread – this certainly holds for user mode threads and should also hold for kernel mode threads. But there is one kind of thread where the ID does not uniquely identify a KTHREAD – the Idle thread. On a uniprocessor system, there is only one Idle thread and this idle thread will have the thread ID 0 (in process 0). On a multiprocessor system, however, Windows creates one Idle thread per CPU.

Read more »

Reaching beyond the top of the stack -- illegal or just bad style?

The stack pointer, esp on i386, denotes the top of the stack. All memory below the stack pointer (i.e. higher addresses) is occupied by parameters, variables and return addresses; memory above the stack pointer must be assumed to contain garbage. When programming in assembly, it is equally easy to use memory below and above the stack pointer. Reading from or writing to addresses beyond the top of the stack is unusual and under normal circumstances, there is little reason to do so.

Read more »

Explicit Symbol Loading with dbghelp

When working with symbols, the default case is that you either analyze the current process, a concurrently running process or maybe even the kernel. dbghelp provides special support for these use cases and getting the right symbols to load is usually easy – having access to the process being analyzed, dbghelp can obtain the necessary module information by itself and will come up with the matching symbols. Things are not quite as easy when analyzing symbols for a process (or kernel) that is not running any more or executes on a different machine.

Read more »

Fun with low level SEH

Most code that uses Structured Exception Handling does this with the help of the compiler, e.g. by using try/except/__finally. Still, it is possible to do everything by hand, i.e. to provide your own exception handlers and set up the exception registration records manually. However, as this entire topic is not documented very well, doing so opens room for all kind of surprises… Although more than 10 years old, the best article on this topic still seems to be Matt Pirtrek’s A Crash Course on the Depths of Win32™ Structured Exception Handling, which I assume you have read.

Read more »

The case of the mysterious JVM x64 crashes

Posted on

To date, I did all my Java development uding 32 bit JVMs. After all, as long as you do not have extreme memory requirements, the 64 bit JVM should not buy you much. Today I installed the Java 6 Update 6 x64 JDK on my Vista x64 machine and tried to run some of my JUnit tests on this VM. With little success: # # An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000772b219b, pid=4188, tid=2272 # # Java VM: Java HotSpot™ 64-Bit Server VM (10.

Read more »

Trace and Watch Data -- How does it work

Posted on

One of the builtin WinDBG commands is wt (Trace and Watch Data), which can be used to trace the execution flow of a function. Given source code like the following: void foo() { } void bar() { } int main() { // Some random code… int a = 1, b = 2; // Call a child function. foo(); // More useless code… a+=b; if ( a == b) a = b; // Call another child function.

Read more »

Walking the stack of the current thread

StackWalk64 provides a convenient and platform-independent way to walk the stack of a thread. Although useful and powerful indeed, it is definitively one of the less trivial to use functions. The additional fact that the MSDN documentation for StackWalk64 is rather light does not make things easier. There is, however, a decent article on CodeProject covering the usage of StackWalk64. Although you can walk the stack of any thread using StackWalk64, this post only deals with walking the current thread’s stack.

Read more »

When HEAP_NO_SERIALIZE heap operations are not quite 'not serialized'

Posted on

While the RTL Heap performs all heap operation in an interlocked manner by default, it can be requested not to serialize operations by passing the HEAP_NO_SERIALIZE flag to HeapCreate or HeapAlloc. In this case, the caller is in charge to provide proper synchronization. As it turns out, things change when Application Verifier heap checks are enabled for this process. To check heap operations, Application Verifier intercepts certain operations. Presumably to protect its own internal data structures, at some points, Avrf enters a critical section, as shown in this stack trace:

Read more »