views:

370

answers:

4
+2  Q: 

Debugger question

I have a bug I am chasing (I think its a deadlock). When I run the code it hangs without the debugger flagging an error, so after a while I try pressing the pause (break all) button. The debugger then reports "The process appears to be deadlocked...". I then can see that all the threads are held up at lines saying EnterCriticalSection except for one which is already inside a critical section. When I look at the thread that is inside the C.S. with the debugger I see a green arrow, accompanied by a tiny blue circle pointing at a line with GetWindowText... as below:

// stuff A
{
    GetWindowText(editwin[a].child_window_handle,existing_text,MAX_TEXT_SIZE-1);
}
// stuff B

If I hover the mouse over the green arrow I see the text "this is the next statement to execute when this thread returns from the current function". Now this has stumped me because I don't know if it means that it is stuck inside "stuff A" and is waiting to come back or its stuck inside GetWindowText and has somehow got stuck inside that. The arguments to GetWindowText all look sensible to me. If I click on "step into" I get the message "Unable to step. The process has been soft broken".

EDIT: stuff A is in fact the statement:

if (buf_ptr != NULL)
A: 

Assuming your question is "Is this normal", then yes, the debugger usually shows the statement after the one stuck on a critical section.

Kim Gräsman
+4  A: 

Usually a green arrow beside a line of code means "this is the next line that would be executed, if not for the fact we're stuck somewhere in a deeper stack frame." However, VS makes it impossible to say for sure based on the info provided so far...

[EDIT - of course, deep knowledge of Win32 can provide a very good guess - see the answer by "mos" for a likely explanation based on the GetWindowText() API's known pitfalls]

As mentioned, what Visual Studio shows you is sometimes misleading. To get a closer view of exactly what is happening you need to turn off some non-helpful "features" that VS enables by default. In Tools -> Options -> Debugging -> General, make sure:

  • Enable address-level debugging = ON
  • Enable Just My Code = OFF
  • Enable Source Server support = ON

This should allow you to:

1) break on / step over / etc the exact instruction that's causing the deadlock

2) see the full stack trace up to that point, regardless of module(s)

3) see source code whenever available, assuming your symbol & source servers are configured correctly

Richard Berg
Nice, that's heaps of info I didn't know!
Kim Gräsman
"Enable Source Server support" does not seem to be an option :-(BTW, please see my edit of my original question.
Mick
Richard Berg
I can't find a "general development" box to click :-( could you be more specific about where to find it.
Mick
It's one of the choices the very first time you run VS after installation, along with "web developer", "C++ developer", etc. You can reset things with the /resetuserdata parameter but that will kill all your other settings. If you simply want to see all the available options in the dialog, there should be a checkbox somewhere on the border. (we're talking about VS2008 SP1 right?)
Richard Berg
+4  A: 

Your problem is that GetWindowText actually sends a message to the other window and waits for it to return. If that window is owned by another thread that is waiting for a critical section, GetWindowText will wait forever.

You're stuck inside GetWindowText, and have created a deadlock.

mos
+1 for that. My bet is that the OP is doing some work in the GUI thread, rather than using a separate worker thread. In this case, the GUI thread probably got stuck, and calling it caused the deadlock. @Mick - take a look at the stack trace of all threads, and look for the one running the message loop. If it's waiting on the critical section, that's your problem.
eran
+1. good under-the-hood knowledge of Win32 beats fancy debugging techniques anytime!
Richard Berg
Spot on. Your answer explains everything. Thanks.
Mick
+2  A: 

As the previous responses suggest, your code is stuck inside "Stuff A".

Can I suggest another tool for your tool-belt?

I usually find it much easier to debug native synchronization problems using WinDbg. just launch your program in WinDbg, point to the correct symbols and all the info will be right there for your investigation using the !locks, !cs and k commands.

If you're new to WinDbg, you'll find that the internet is full with information about it. I recommend reading Advanced Windows Debugging as well.

It's a little bit difficult to start, comparing to the user friendly VS Debugger but every minute you'll invest in learning how to use it will save you hours of debugging further down the road.

Moshe Levi
+1 for the best debugging book ever written
Richard Berg