Slashdot Mirror


What Good Linux Debuggers Are There?

David Weekly asks: "I'm programming for a small software company that's got a fair bit of C++ code; we've been using gdb whilst on Linux, but have been a little frustrated by its shortcomings with multithreaded applications and its fumbling multiple inheritance issues. I poked around on the Net and, other than gdb, I was only able to find Etnus' TotalView as a modern, actively-developed Linux debugger. Are there really only two Linux debuggers (that one can take seriously)? How, for instance, do folks who code up Apache modules test them in multithreaded mode? (i.e., not just using '-X'.) I'd love to hear answers more substantive than 'use printf()' and/or 'just use ____, my favorite gdb frontend'."

11 of 69 comments (clear)

  1. Multiple inheritance by gkatsi · · Score: 3, Flamebait

    I have not worked much with threaded applications, but I have encountered the problems with multiple inheritance.

    What I've ended up doing in hard cases (where printf will not help) is create local pointers to the parent classes and examine them from gdb. Once the problem is solved, the extra variables are gone, too.

    Example:
    Base1 *b1 = dynamic_cast[Base1*](this);
    Base2 *b2 = dynamic_cast[Base2*](this);

    (change [] to less-than and greater-than).

    Of course, this will not help when your hierarchy is more than a couple of levels deep and things get even more complicated when the parent class is actually a template argument.

    I hope, however, that this is just a very-hard-to-fix bug in gdb, as opposed to an even deeper design problem (as I think is the case with threaded code). So there might still be hope.

  2. My goodness, You are all illiterate! by djm181 · · Score: 3, Interesting
    Is it just me or did the original poster say that they did not want to hear people say 'use printf' or 'use a gdb frontend'. And how many people replyed saying 'duh ... every tried using a print statement?'

    Please read an entire post before replying.

    Finally, what do I use for multithreaded application debugging? I don't have a tool for once I've cut the code but if you define your system using Finite State Processes then you can use the LTS Analyser to check for deadlocks etc and you can step through a concurrent system generating whatever event you like. It is worth a look, although matching your code to your model is still tricky. And of course you need to learn FSP, but the website above teaches you.

  3. Three bad things about them: by Bastian · · Score: 3, Insightful

    1) You have to dive through the code to insert them and then recompile on every iteration of the debugging process.

    2) You have to dive through the code to remove them and then recompile on every iteration of the debugging process if you don't want to keep getting info for finding bugs you've already fixed every time you run the program.

    3) They clutter up your code and make it much less readable and maintainable.

    and as a super extra bonus for everyone

    4) The only workaround for problems (1) and (2) is fancy use of the preprocessor, which has the unwanted side effect of making (3) even worse!

    1. Re:Three bad things about them: by Outland+Traveller · · Score: 5, Interesting

      Slightly off topic, but the apache project's log4j is the most elegent evolution of the "printk" school of debugging I have seen to date.

      You can log against any backend source you feel like, flat files, syslog, databases, etc. You can remove the logging module entirely at runtime, without paying a performance hit for the debug statements. This saves a lot of jumping back and forth when you're trying to package up a release. If you're stuck without the fund$ for a top-end debugger it's the next best thing. It's for java, but I don't see any reason why the concept couldn't be ported to C++.

  4. Intel's Debugger by dew · · Score: 5, Informative

    [article author] A number of people have thoughtfully suggested trying out Intel's debugger (aka LDB). Unfortunately, from what I found, it looks like LDB has only a subset of gdb functions, and can't even do simple things, like attach to processes. It seems that Intel has given up making their own Linux debugger and has decided to join up with GDB development. That's why I didn't include it. Thanks anyhow to those who did suggest it and thanks to those of you who suggested some other debuggers; I'll take a look at them.

    --

    David E. Weekly
    Code / Think / Teach / Learn
    h4x0r for

  5. ups by dirtydamo · · Score: 3, Informative

    UPS is the only debugger I use anymore! I've never used it in the situations you asked about (multithreaded code etc), but I have generally found it's a very fast and lean debugger. It's also cross-platform, which is nice.

    (The only real downside is its user interface, which isn't too great.)

  6. Sorry, No Good Linux Debuggers by vharron · · Score: 4, Interesting

    It's really quite depressing. From what I can tell, no one makes a quality debugger for Linux. I would pay serious cash for the equivalent of Visual C++ on Linux, but no such product exists. All recent versions of gdb drop core on me every time when trying to attach to a process -- and it's the best debugger available. I'm not doing anything fancy, just some shared libraries and occasionally some threads. Low quality tools are probably costing the Linux community more than anyone can estimate.

    We develop software for Linux and PS2 but all of our code builds on Windows and we spend most of our time working there. I strongly recommend you use a Windows XP/2000 and Visual C++ as your main development environment and port to Linux periodically. You'll save yourself countless hours of misery.

    Good luck,

    Vince Harron

    1. Re:Sorry, No Good Linux Debuggers by rkgmd · · Score: 3, Informative

      You may want to take a look at Borland's Kylix, the linux-native port of Borland's respocted IDE's for C, C++, and Delphi (they claim it supports the same features as windows versions). It comes with a high quality debugger/profiler, and, while not free, a trial version is available.

  7. Asking the wrong question? by jungd · · Score: 3, Insightful

    It seems that the choices for debuggers under Linux are a bit lacking.

    I hate to remember how many hours I've spend using source debuggers - chasing down long call stacks, getting confused about just what was gong on.

    Now however, I haven't used a debugger at all in the last 10 years, under either Windows or Linux. The difference? - Modern software engineering practice.

    Although there are doubtless legitimate cases where a debugger is very useful; my opinion is that for any decient sized C++ codes, the application of a handful of coding techniques is a much better substitute.

    If you're chasing memory problems, use a suitable (zero cost) templated smart pointer implementation - so you can't even compile code that would corrupt memory. Similarly, apropriate abstraction classes for synchonization can also provide all the logging information you'll need to chase down synchnonization issues in parallel codes - and will help avoiding many of them in the first place (research has come a long way since the days of using error-prone primitive semaphores in high-level code).

    I suggest also liberal use of assertions (preconditions, postconditions, invariances) and multi-level logging.

    In my experience, with these tools, bad code that would cause memory corruptions or synthronization deadlocks or race-conditions will just not compile. Any that aren't caught are usually easily seen with the logging output or assertions.

    Hope my suggestions help - even though I didn't address your question. If you want to read more, pickup some books on modern generic programming in C++ and a couple software engineering texts.

    --
    /..sig file not found - permission denied.
    1. Re:Asking the wrong question? by cooldev · · Score: 3, Interesting

      I had a witty response all planned, but let me just be blunt: Are you a masochist? Either that or you're not doing serious C++ development, or you're a manager that doesn't write code.

      My team uses everything you mention, with the addition of some other stuff like automatic memory leak detection and OS-level hooks to detect heap corruption, invalid handle usage, etc. I'm not even sure how your smart pointer template library would detect or prevent all heap corruption bugs, as they aren't always caused by dangling pointers...

      While these techniques and tools are great, even with great programming practices there's no way you can eliminate all bugs this way. People make mistakes.

      So when you're in the initial stages of development you're meaning to tell me that neither you nor anybody on your team makes a mistake where you end up dereferencing a NULL pointer? Or do you try to track it down from the logging instead of taking three seconds to get a call stack with symbols and line number information in a debugger? What about when another component or library crashes or returns an unexpected result; don't you investigate? What about subtle logic flaws that become readily apparent when stepping through the code with a debugger? You can't log everything.

    2. Re:Asking the wrong question? by jungd · · Score: 3, Interesting
      Either that or you're not doing serious C++ development, or you're a manager that doesn't write code.

      Yes, I've been doing serious C++ programming for years (of varying degrees of seriousness :). I am not a manager.

      My team uses everything you mention, with the addition of some other stuff like automatic memory leak detection and OS-level hooks to detectI...

      You won't need automatic memory leak detection if you make it *impossible* to program.

      While these techniques and tools are great, even with great programming practices there's no way you can eliminate all bugs this way. People make mistakes.

      Yes, people make mistakes - that is what the compiler is for (for the most part - of course I'm not claiming it can get *everything*)

      So when you're in the initial stages of development you're meaning to tell me that neither you nor anybody on your team makes a mistake where you end up dereferencing a NULL pointer?

      Correct. The smart-ptr class we use doesn't allow any such thing. Why on earth would you want to allow the concept of pointing to nothing? - it doesn't even make sense. Change your smart-ptr class to not allow initialization or assigmnent from anything but another smart-ptr. The constructor can construct new instances too, so it is impossible to have a pointer point to anything but a valid object. Our smart-ptr also checks the validity of the address with our memory management system before any dereference too - just in case it gets corrupted via some other mechanism - but that is very very rare.

      What about when another component or library crashes or returns an unexpected result; don't you investigate? What about subtle logic flaws that become readily apparent when stepping through the code with a debugger? You can't log everything.

      I admit we typically either have developed all the code in the system (save OS calls), or have control over the source of other libraries - so we can apply the same techniques to them. Not everyone can have that control.

      Check out Andrei Alexandrescu's book on modern C++ design for a half-decient smart-ptr class to use as a starting point.

      --
      /..sig file not found - permission denied.