Thread: [GD-General] problems while debugger is attached
Brought to you by:
vexxed72
From: Andras B. <and...@gm...> - 2006-07-23 19:49:22
|
I have a strange bug, where if I'm running the program without the debugger attached (CTRL-F5 in VS), the program would run correctly both in debug and release builds. But when I run the program with F5, so the debugger is attached, then it blocks on a function call and never returns. If I put a breakpoint before this call, and step through it, then everything seems to work fine, and the function returns as expected.. Could this be a deadlocking problem? Any ideas why attaching a debugger makes any difference? And hints on how to debug this? Thanks, Andras |
From: Chris C. <can...@gm...> - 2006-07-23 20:18:12
|
I've had this many times when coding in a multi-threaded environment. What will be happening is the attachment of the debugger is enough to skew the timings of the function calls so that a race condition is exposed. When you say 'blocks on a function call and never returns', what function call are you talking about? A system call or one of your own functions? If its one of your own functions thats blocking, its a bit easier to debug, because you can introduce logging around it. A system call is a harder to diagnose - usually the sub-system the system call is dealing with has some internal blocking, but its harder to figure out where the race condition is coming from. Before I started using test driven development for these things, I could spend ages beating my head against weird behaviour like that. The most effective solution I found for debugging strange race conditions was to introduce sleeps of random and significant duration around the system, to exacerbate any problems which don't show up unless locks are held for a long while. Combine that with logging around lock acquisition/releases so you can see what was going on immediately prior to the deadlock, without having to use breakpoints. Breakpoints don't help at all in these cases, because they screw up the timing, and the nature of debuggers is often to suspend other threads entirely when single-stepping through a thread - often making the problem disappear entirely. ChrisC On 23/07/06, Andras Balogh <and...@gm...> wrote: > I have a strange bug, where if I'm running the program without the > debugger attached (CTRL-F5 in VS), the program would run correctly both in > debug and release builds. But when I run the program with F5, so the > debugger is attached, then it blocks on a function call and never returns. > If I put a breakpoint before this call, and step through it, then > everything seems to work fine, and the function returns as expected.. > > Could this be a deadlocking problem? Any ideas why attaching a debugger > makes any difference? And hints on how to debug this? > > Thanks, > > > > Andras > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=557 > |
From: Noel L. <nl...@co...> - 2006-07-23 22:32:42
|
On 7/23/06, Chris Chapman <can...@gm...> wrote: > Before I started using test driven development for these things, I > could spend ages beating my head against weird behaviour like that. Chris, I'm curious about how test-driven development helped with situations like that. Is it because you simply don't use the debugger as much, or because it helps avoid those race conditions somehow? When I apply test-driven development it's at a very small scale (function or class), so none of the tests actually deal with multiple threads, inter-process communication, etc (the functional tests do though). So that's one situation where I haven't found TDD to help much with and I was very curious about your comment. --Noel |
From: Megan F. <sha...@gm...> - 2006-07-23 21:29:37
|
It may or may not be your problem, but I've had many cases where, due to the debugger assigning consistent values to uninitialized variables, the application fails - but if I allow those to remain uninitialized in release mode, it simply functions (on certain machines). In general, that's the first thing I go looking for when I have a problem that shows in debug mode but not in release. Usually, it ends up being me having somehow handed a function a bad pointer to nothing, rather than the structure I intended to send. On 7/23/06, Andras Balogh <and...@gm...> wrote: > I have a strange bug, where if I'm running the program without the > debugger attached (CTRL-F5 in VS), the program would run correctly both in > debug and release builds. But when I run the program with F5, so the > debugger is attached, then it blocks on a function call and never returns. > If I put a breakpoint before this call, and step through it, then > everything seems to work fine, and the function returns as expected.. > > Could this be a deadlocking problem? Any ideas why attaching a debugger > makes any difference? And hints on how to debug this? > > Thanks, > > > > Andras > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=557 > -- -Megan Fox Idyllon, LLC http://shalinor.circustent.us/megan/resume/ |
From: Andras B. <and...@gm...> - 2006-07-23 23:08:50
|
Running with the debugger attached does not mean that I'm running a debug build. I can attach the debugger to any process, it does not matter how it was built. And this bug happens in both debug and release builds, so my guess is that it's not an uninitialized variable problem. Thanks, Andras On Sun, 23 Jul 2006 15:29:34 -0600, Megan Fox <sha...@gm...> wrote: > It may or may not be your problem, but I've had many cases where, due > to the debugger assigning consistent values to uninitialized > variables, the application fails - but if I allow those to remain > uninitialized in release mode, it simply functions (on certain > machines). In general, that's the first thing I go looking for when I > have a problem that shows in debug mode but not in release. Usually, > it ends up being me having somehow handed a function a bad pointer to > nothing, rather than the structure I intended to send. > > On 7/23/06, Andras Balogh <and...@gm...> wrote: >> I have a strange bug, where if I'm running the program without the >> debugger attached (CTRL-F5 in VS), the program would run correctly both >> in >> debug and release builds. But when I run the program with F5, so the >> debugger is attached, then it blocks on a function call and never >> returns. >> If I put a breakpoint before this call, and step through it, then >> everything seems to work fine, and the function returns as expected.. >> >> Could this be a deadlocking problem? Any ideas why attaching a debugger >> makes any difference? And hints on how to debug this? >> >> Thanks, >> >> >> >> Andras |
From: Andras B. <and...@gm...> - 2006-07-23 23:08:51
|
The function call in question is a call into a 3rd party library (ECW). = I = have the sources and the .pdb, so I can step inside, and see what's goin= g = on, but of course, when I do that, it works fine. Hmm, this gave me an idea: When I'm running the program without = breakpoints, I can still stop the execution of the process at any time. = = Now, Is there any way I could tell what the current instrucion pointer i= s, = for each of my threads? That way, I could at least see, where exactly th= e = execution is stalled. Thanks, Andras On Sun, 23 Jul 2006 14:18:10 -0600, Chris Chapman <can...@gm...= > = wrote: > I've had this many times when coding in a multi-threaded environment. > What will be happening is the attachment of the debugger is enough to > skew the timings of the function calls so that a race condition is > exposed. > > When you say 'blocks on a function call and never returns', what > function call are you talking about? A system call or one of your own > functions? If its one of your own functions thats blocking, its a bit > easier to debug, because you can introduce logging around it. A system= > call is a harder to diagnose - usually the sub-system the system call > is dealing with has some internal blocking, but its harder to figure > out where the race condition is coming from. > > Before I started using test driven development for these things, I > could spend ages beating my head against weird behaviour like that. > The most effective solution I found for debugging strange race > conditions was to introduce sleeps of random and significant duration > around the system, to exacerbate any problems which don't show up > unless locks are held for a long while. Combine that with logging > around lock acquisition/releases so you can see what was going on > immediately prior to the deadlock, without having to use breakpoints. > Breakpoints don't help at all in these cases, because they screw up > the timing, and the nature of debuggers is often to suspend other > threads entirely when single-stepping through a thread - often making > the problem disappear entirely. > > ChrisC > > On 23/07/06, Andras Balogh <and...@gm...> wrote: >> I have a strange bug, where if I'm running the program without the >> debugger attached (CTRL-F5 in VS), the program would run correctly bo= th = >> in >> debug and release builds. But when I run the program with F5, so the >> debugger is attached, then it blocks on a function call and never = >> returns. >> If I put a breakpoint before this call, and step through it, then >> everything seems to work fine, and the function returns as expected..= >> >> Could this be a deadlocking problem? Any ideas why attaching a debugg= er >> makes any difference? And hints on how to debug this? >> >> Thanks, >> >> >> >> Andras >> >> ---------------------------------------------------------------------= ---- >> Take Surveys. Earn Cash. Influence the Future of IT >> Join SourceForge.net's Techsay panel and you'll get the chance to sha= re = >> your >> opinions on IT & business topics through brief surveys -- and earn ca= sh >> http://www.techsay.com/default.php?page=3Djoin.php&p=3Dsourceforge&CI= D=3DDEVDEV >> _______________________________________________ >> Gamedevlists-general mailing list >> Gam...@li... >> https://lists.sourceforge.net/lists/listinfo/gamedevlists-general >> Archives: >> http://sourceforge.net/mailarchive/forum.php?forum_id=3D557 >> > > ----------------------------------------------------------------------= --- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to shar= e = > your > opinions on IT & business topics through brief surveys -- and earn cas= h > http://www.techsay.com/default.php?page=3Djoin.php&p=3Dsourceforge&CID= =3DDEVDEV > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=3D557 |
From: Alen L. <ale...@cr...> - 2006-07-24 06:39:42
|
Hi Andras, Don't know if this helps, or not, but perhaps you should be aware that the debugger usually routes all exceptions through it. When an exception occurs, the debugger is the first one to catch it, and only then is it passed on. Don't know how that could influence your app, but then again, I don't know what you're doing in it. One more thing to note is that apps tend to run a tad slower when the ran from the debugger (last checked like 5 years ago, on VC6, don't know if the rule still applies). Seems like it might be intercepting something more that just exceptions, but I didn't bother to check what exactly causes this. It certainly does catch dll loads and thread creation/deletion, etc. Cheers, Alen Andras wrote: > The function call in question is a call into a 3rd party library (ECW). I > have the sources and the .pdb, so I can step inside, and see what's going > on, but of course, when I do that, it works fine. > Hmm, this gave me an idea: When I'm running the program without > breakpoints, I can still stop the execution of the process at any time. > Now, Is there any way I could tell what the current instrucion pointer is, > for each of my threads? That way, I could at least see, where exactly the > execution is stalled. > Thanks, > Andras > On Sun, 23 Jul 2006 14:18:10 -0600, Chris Chapman <can...@gm...> > wrote: >> I've had this many times when coding in a multi-threaded environment. >> What will be happening is the attachment of the debugger is enough to >> skew the timings of the function calls so that a race condition is >> exposed. >> >> When you say 'blocks on a function call and never returns', what >> function call are you talking about? A system call or one of your own >> functions? If its one of your own functions thats blocking, its a bit >> easier to debug, because you can introduce logging around it. A system >> call is a harder to diagnose - usually the sub-system the system call >> is dealing with has some internal blocking, but its harder to figure >> out where the race condition is coming from. >> >> Before I started using test driven development for these things, I >> could spend ages beating my head against weird behaviour like that. >> The most effective solution I found for debugging strange race >> conditions was to introduce sleeps of random and significant duration >> around the system, to exacerbate any problems which don't show up >> unless locks are held for a long while. Combine that with logging >> around lock acquisition/releases so you can see what was going on >> immediately prior to the deadlock, without having to use breakpoints. >> Breakpoints don't help at all in these cases, because they screw up >> the timing, and the nature of debuggers is often to suspend other >> threads entirely when single-stepping through a thread - often making >> the problem disappear entirely. >> >> ChrisC >> >> On 23/07/06, Andras Balogh <and...@gm...> wrote: >>> I have a strange bug, where if I'm running the program without the >>> debugger attached (CTRL-F5 in VS), the program would run correctly both >>> in >>> debug and release builds. But when I run the program with F5, so the >>> debugger is attached, then it blocks on a function call and never >>> returns. >>> If I put a breakpoint before this call, and step through it, then >>> everything seems to work fine, and the function returns as expected.. >>> >>> Could this be a deadlocking problem? Any ideas why attaching a debugger >>> makes any difference? And hints on how to debug this? >>> >>> Thanks, >>> >>> >>> >>> Andras >>> >>> ------------------------------------------------------------------------- >>> Take Surveys. Earn Cash. Influence the Future of IT >>> Join SourceForge.net's Techsay panel and you'll get the chance to share >>> your >>> opinions on IT & business topics through brief surveys -- and earn cash >>> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV >>> _______________________________________________ >>> Gamedevlists-general mailing list >>> Gam...@li... >>> https://lists.sourceforge.net/lists/listinfo/gamedevlists-general >>> Archives: >>> http://sourceforge.net/mailarchive/forum.php?forum_id=557 >>> >> >> ------------------------------------------------------------------------- >> Take Surveys. Earn Cash. Influence the Future of IT >> Join SourceForge.net's Techsay panel and you'll get the chance to share >> your >> opinions on IT & business topics through brief surveys -- and earn cash >> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV >> _______________________________________________ >> Gamedevlists-general mailing list >> Gam...@li... >> https://lists.sourceforge.net/lists/listinfo/gamedevlists-general >> Archives: >> http://sourceforge.net/mailarchive/forum.php?forum_id=557 > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=557 -- Alen |
From: Chris C. <can...@gm...> - 2006-07-24 09:26:38
|
Visual Studio does let you do this, although I'll stress again that its behaviour when execution is supposedly frozen and single stepping is not clear or obvious. Under the Debug menu there should be a 'Threads...' item (its a window in VS.NET), which should show you all the currently running threads and the function in which their IP is currently. Usually when you look at it you just see windows DLLs though, as most often its a low level system call which yields the thread. You can switch context to each thread and look at its call stack to find some interesting results though. On 24/07/06, Andras Balogh <and...@gm...> wrote: > The function call in question is a call into a 3rd party library (ECW). I > have the sources and the .pdb, so I can step inside, and see what's going > on, but of course, when I do that, it works fine. > > Hmm, this gave me an idea: When I'm running the program without > breakpoints, I can still stop the execution of the process at any time. > Now, Is there any way I could tell what the current instrucion pointer is, > for each of my threads? That way, I could at least see, where exactly the > execution is stalled. > > Thanks, > > > Andras > > > On Sun, 23 Jul 2006 14:18:10 -0600, Chris Chapman <can...@gm...> > wrote: > > > I've had this many times when coding in a multi-threaded environment. > > What will be happening is the attachment of the debugger is enough to > > skew the timings of the function calls so that a race condition is > > exposed. > > > > When you say 'blocks on a function call and never returns', what > > function call are you talking about? A system call or one of your own > > functions? If its one of your own functions thats blocking, its a bit > > easier to debug, because you can introduce logging around it. A system > > call is a harder to diagnose - usually the sub-system the system call > > is dealing with has some internal blocking, but its harder to figure > > out where the race condition is coming from. > > > > Before I started using test driven development for these things, I > > could spend ages beating my head against weird behaviour like that. > > The most effective solution I found for debugging strange race > > conditions was to introduce sleeps of random and significant duration > > around the system, to exacerbate any problems which don't show up > > unless locks are held for a long while. Combine that with logging > > around lock acquisition/releases so you can see what was going on > > immediately prior to the deadlock, without having to use breakpoints. > > Breakpoints don't help at all in these cases, because they screw up > > the timing, and the nature of debuggers is often to suspend other > > threads entirely when single-stepping through a thread - often making > > the problem disappear entirely. > > > > ChrisC > > > > On 23/07/06, Andras Balogh <and...@gm...> wrote: > >> I have a strange bug, where if I'm running the program without the > >> debugger attached (CTRL-F5 in VS), the program would run correctly both > >> in > >> debug and release builds. But when I run the program with F5, so the > >> debugger is attached, then it blocks on a function call and never > >> returns. > >> If I put a breakpoint before this call, and step through it, then > >> everything seems to work fine, and the function returns as expected.. > >> > >> Could this be a deadlocking problem? Any ideas why attaching a debugger > >> makes any difference? And hints on how to debug this? > >> > >> Thanks, > >> > >> > >> > >> Andras > >> > >> ------------------------------------------------------------------------- > >> Take Surveys. Earn Cash. Influence the Future of IT > >> Join SourceForge.net's Techsay panel and you'll get the chance to share > >> your > >> opinions on IT & business topics through brief surveys -- and earn cash > >> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > >> _______________________________________________ > >> Gamedevlists-general mailing list > >> Gam...@li... > >> https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > >> Archives: > >> http://sourceforge.net/mailarchive/forum.php?forum_id=557 > >> > > > > ------------------------------------------------------------------------- > > Take Surveys. Earn Cash. Influence the Future of IT > > Join SourceForge.net's Techsay panel and you'll get the chance to share > > your > > opinions on IT & business topics through brief surveys -- and earn cash > > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > > _______________________________________________ > > Gamedevlists-general mailing list > > Gam...@li... > > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > > Archives: > > http://sourceforge.net/mailarchive/forum.php?forum_id=557 > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=557 > |
From: Andras B. <and...@gm...> - 2006-07-25 02:53:40
|
Thanks for all the good advice! I've found the cause of the problem: Using the threads window, I quickly found out that the thread in question was always waiting on a simple ReadFile call. There was no deadlock, it was just awfully slow. It turned out that I've left a conditional breakpoint somewhere in the code, that never actually got hit, but slowed down this thread to a crawl. Andras |
From: Chris C. <can...@gm...> - 2006-07-24 09:47:33
|
There was a thread on one of the dev lists a while back about test driven development, and a lot of arguing back and forth about exactly what constituted a unit test versus a system test. I sort of felt it missed the point entirely, which is just to test the code in ways that might break! I treat test driven development as a way of thinking, where while (or preferrably before) you are developing code, you also write tests to exercise your code and make sure it does what you'd expect. Multi-threaded code, unless written very tightly and cleanly, is only testable at the functional level. I try to make my tests as cruel as possible. In the case of multi-threaded bits of code, I have taken to writing tests which substitute the lock/unlock classes for test versions which introduce random but non-trivial delays before and after locks. Then I take a section of the system and run it through its paces, multiple times. Solid multi-threaded code should never fail, or do anything unexpected, even in the presence of massive delays on any particular part of the code. The worst that should happen is that the system slows to a crawl, but the output should still be sensible. For example, we had a GUI thread, which dealt with overlaying informational display over a 3D system (NB: this wasn't in games, I've yet to work for a games company with a decent TDD setup). It was interleaved with rendering, but disconnected in terms of update frequency, and also had to be interleaved with data access from an underlying system. So I replaced the underlying system and renderer threads with a mock version which simply locked and unlocked as if it were doing work, but actually did nothing, and subbed in the test locking class. Then the test ran through a pre-determined set of operations. The randomness was seeded, so deterministic; however you couldn't predict what would be happening when. The test got repeated 10 times without re-seeding the randomness. Admittedly, it only found one bug the whole time I used it (deep in one of the GUI sub-classes there was an else case which didn't free a locked resource), but it was a bug which would only have shown up in the real system (it would only get hit if the lock was held by something else mid-way through the function being called). All of this is just an extension of how I took to debugging live race conditions - by introducing random length lock/unlock delays. Obviously in a live build thats a real pain in the neck - imagine trying to play a game where the framerate spiked massively and randomly, in an effort to repro a bug. When I did do that, I ended up tying it to a debug button combo toggling a flag to make the locks start misbehaving. In most cases, as soon as you set the random delay flag, a few frames later the build would hang, and I could go look at the locking logs to see which resource was deadlocked, and what the history was. TDD gives you a way to do the same test, but without the unpredictability of recreation steps. ChrisC Black Company Studios On 23/07/06, Noel Llopis <ll...@co...> wrote: > On 7/23/06, Chris Chapman <can...@gm...> wrote: > > Before I started using test driven development for these things, I > > could spend ages beating my head against weird behaviour like that. > > Chris, > > I'm curious about how test-driven development helped with situations > like that. Is it because you simply don't use the debugger as much, or > because it helps avoid those race conditions somehow? > > When I apply test-driven development it's at a very small scale > (function or class), so none of the tests actually deal with multiple > threads, inter-process communication, etc (the functional tests do > though). So that's one situation where I haven't found TDD to help > much with and I was very curious about your comment. > > > --Noel > |