wherein gdb eats my balls

Can anyone explain to me why gdb hasn't worked properly since 1991, on any platform?

I don't think I ask for much. Just the ability to reliably and repeatedly set breakpoints on functions that (honest, I swear) are included in the executable. Statically even. The ability to actually have a stack left after a SEGV. You know: just the whole reason for a debugger existing at all.

XCode does a nice job of hiding gdb beneath the swaddling of a (surprisingly usable) GUI, but that doesn't change the fact that it's still gdb underneath, and consequently just doesn't fucking work.


Update: All hail the Lazyweb! I got mail from one of the Apple gdb developers who suggested that I un-check the "Load symbols lazily" preference in XCode, and now breakpoints seem to be working fine again. (Apparently this lazy loading is an optimization that really only matters for huge programs, but messes things up if you are using bundles.)

Tags: , , ,

21 Responses:

  1. echristo says:

    Is stabs at the moment on OS X which sucks quite handily. I think it defaults to "-gused" which tries to eliminate unused debug entries, you might want to try "-gfull" to stop that elimination. The next release should have dwarf support which will be a bit better.

  2. kfringe says:

    Can anyone explain to me why gdb hasn't worked properly since 1991, on any platform?

    I never got much past "thread support."

  3. waider says:

    I kinda lost it when someone said, "oh, to get a stack trace you just need to do "thread apply all bt"". WTF? It's the machine's job to know I'm running threaded code and to give me a relevant backtrace, dammit.

    Of course, I'm getting backtraces. From your post it seems like you're not even getting that much.

  4. weev says:

    Switch to idb!

  5. strspn says:

    Works for me, but my version of Mac OS X is so old it might as well be named after a stray cats who got into Jobs's garbage when he was living in poverty at NeXT. Specifics? Are core files turned on? I like the "thread apply all bt" idea; that sounds like the right direction, at least.

  6. dossy says:

    gdb 6.3 works nicely on Solaris 8+ ... but I'm geekcore and use pstack/adb. My debug-fu is strong.

  7. mythrocks says:

    Hello, jwz.

    A lot of the time, you can't set breakpoints in functions because they're inlined by the compiler. That could be why control doesn't stop there.

    But I guess you alreay knew that.

  8. I've been happily using gdb underneath Eclipse's CDT (under linux/x86 mostly) for some time, and it's gotten those two basic features right. I'll hopefully be getting a used mac mini (PPC) this weekend. If I can keep OS/X on it long enough without giving up and switching to Ubuntu, I might give Eclipse/carbon a try...

  9. dasht_brk says:

    A good trick, for some of the problems setting breakpoints, is to set a breakpoint in main, reach that, then set yr other breakpoints. This certainly helps with some dynamic linking issues but I vaguely recall seeing it help with other stuff, too.

    And it hasn't been entirely downhill. I've been delighted to find watchpoints becoming increasingly reliable. I think this is mostly because chip manufacturers made it easier.

    Nevertheless, like much GNU software, GDB seems to have a permanent case of the flakies and to have arrived at a decade+ dead-end in terms of new features and general improvement.

    Part of it can be blamed on the origins ("finis origine pendet"). The original GDB releases from RMS were not exactly an architectural work of art. The thing has wanted a major clean-up for about as long as I've seen the code. Initially it "competed" for hearts and minds by going up against DBX and that's a pretty low bar.

    It's interesting that you pick 1991, though. That's right around when the GNU project began to let itself get shoved out of doing much, oh, actual software development and when corporations started taking over projects. The "compiler tool-chain" (flex, bison, GCC, ld/bfd, gdb) was both the core strength of the original GNU project and the first to fall through a mix of commercially-instigated brain-drain and attacks like EGCS. The FSF didn't exactly resist this -- I gather it was seen as a mostly positive thing since it meant more people writing and using GPLed software. (I worked at the FSF in 1991 and briefly worked at Cygnus a couple years later. While at Cygnus I tried to initiate a big clean-up of GDB but instead found myself in a stupid dog-fight for internal dominance ranking.)

    And so the subsequent course follows from ordinary market dynamics. The tools work best on (certain flavors of) GNU/Linux. The "Enterprise" market that funds most current development doesn't have the option to vote for development tool improvements in a way that would incite spending. It's a big depressing mess of self-foot-shooting of which the needless statis of GDB over these years is but one small example, if you ask me.


    • jwz says:

      I used to use the "main" trick all the time, but lately I find it to no longer be reliable. Sometimes I'm sitting in the frame of a function, and the breakpoints in it are still listed as "pending". Trying to set them by filename/line number doesn't generally help either.

      I picked 1991 because as I recall that's when SunOS 4 gained dynamic linking, and it seems like in the intervening decade and a half, gdb still hasn't recovered from that shock to its system.

      I've yet to ever get a watchpoint to do anything useful; all they ever seem to do is print the message "watchpoint cancelled because expression is no longer valid" (or something like that). What's the point of a watchpoint that can't be used after you leave the current frame?

      It was a real let-down when I discovered that Apple uses gdb. I expected that there would be greener grass over on that hill by now.

      • dasht_brk says:

        Huh. Well, I switch from FreeBSD to Fedora and, wouldn't ya' know, GDB got better. Sigh.

        The only way I've ever used watch points is looking at the contents of a specific address (often counting on the determinism of `malloc'). It's been a lifesaver there a few times but, again, Fedora on whichever flavor of x86 I happen to have.


      • zojas says:

        damn, I was just about to suggest using line numbers to set the breakpoints :)

        the main problem I have with gdb is that if I'm stepping through one thread, sometimes it will suddenly end up in another thread when I hit 'next' and then it usually all falls apart right after that with weird signals.

  10. mayaknife says:

    A couple of things to try, if you haven't already.

    Compile your code with the -ggdb flag which produces some gdb-specific debug info.

    Try adding the -gstabs flag when you build your app (or -gstabs+ if it's C++ code).

  11. I just ran into this myself:

    Set a breakpoint and the code winds up stopping in the middle of the next function called after the one the breakpoint was set on.


  12. phs says:

    Apple's gdb has, for my purposes at least, always bitten a very special brand of ass. For some reason it's completely impossible to make it pass traps and segvs (er, EXC_BAD_ACCESS, whatever) to the debugged process. I think once you've hit one detaching and reattaching "fixes" things, but when you're trying to step through something that uses traps for error handling or a GC that uses mprotected pages for a trigger or write barrier this is damned annoying.

    As an occasional SBCL hacker I find this quite hateful.

    Helpfully they didn't fix this when they moved to Intel.

  13. transgress says:

    i have to say its an id-10-t error, despite the fact that I know you are competent coder. I spend literally over 90% of my day at work in either ida, olly or gdb and I still find gdb the most pleasing.

    But then again, I also prefer at&t syntax which seems to suggest that I prefer pain, even though I find it less ambiguous than intel syntax.

    • cow says:

      > i have to say its an id-10-t error

      Fascinating. I knew <lj user="jwz">'s reader list was impressive, but I didn't realize it included 1986.

    • edouardp says:

      > i have to say its an id-10-t error

      Transgress: Jamie, can I ask you a question?
      Jamie: What is it, Transgress?
      Transgress: A sphincter says what?
      Transgress: I said, a sphincter says what?
      Jamie: You want me to say "what", like I don't get it. Is that it?

  14. fgmr says:

    My first debugger was the apollo domain/os one, and that sure ruined me for anything less.. and gdb is far, far less. I've never been able to use it without quickly getting a headache.

    At work, our core libraries have some code that'll automatically dump out a stack trace on crash. There's a program that can translate the addresses into actual filename+linenumber locations. Between that and a nice logging package, I rarely need a debugger.

    For home stuff.. I just printf. It's sad that technology has gotten worse than what I used fifteen years ago.