Slashdot Mirror


Pet Bugs II - Debugger War Stories

AlphaHelix queries: "A few weeks back there was an article on Pet Bugs, where people were asked about their favorite bugs. I have a different sort of question: what was your greatest debugging challenge? I've been debugging for a long time, from analog circuits all the way up to multi-kLOC multithreaded servers, and I have some pretty grisly war stories, like the time I debugged a problem in a third-party DLL in machine code because the client didn't have the source for it (yay open source.) What was your greatest debugging triumph?" The first time Slashdot did this it was more about bugs that you had encountered (and may not have solved), this one is about bugs in your own projects code and the trials and tribulations you had to go thru to get them fixed.

8 of 121 comments (clear)

  1. Re:String equality in Java by shemnon · · Score: 2, Informative
    but be careful,
    x.equals("anything")
    can cause null pointer exceptions. Never count on a param being passed in as never null no matter how well you document that fact.
    (x != null) && (x.equals("anything"))
    is a common code pattern, but did you know that equals() already checks for null? So you are checking twice?
    "anything".equals(x)
    is a quick way to code it, both because it takes less code space and less instructions are executed.

    Now if you used constants instead of free strings you would have been ok....

    static final String ANYTHING = "anything; /*...*/
    String x = ANYTHING;
    if (x == ANYGHING) { /*...*/ }

    --
    --Shemnon
  2. Re:Debug versus release bug by codexus · · Score: 5, Informative

    Never trust M$? I'm sorry but it's clearly documented that the asserts are stripped from the release code. The macro to use for code you want to check in debug mode but still execute in release mode is VERIFY()

    I'm no fan of Microsoft, but it's a bit easy to blame them for your own mistakes.

    --
    True warriors use the Klingon Google
  3. Simple, Obvious, NOT! by renehollan · · Score: 4, Informative
    PUSH SP does NOT do the same thing on 8086 and 80286 architectures: in one case it pushes the stack pointer value before decrementing it, and in the other case it pushes it after decrementing it.

    I got stung by that on a Friday before a long weekend in 1984 or 1985. A dirty INT21 hook I was applying to DOS worked on ATs but not on XTs (or was it the other way around?). I had set up a structure on the stack and needed to pass its address to a higher language (prolly K&R C) routine, so PUSH SP seamed like the right thing to do.

    Hardly a complex bug, but one where it is non-obvious that a 286 is not a superset of an 86.

    Then there was the time I had to download a patch to over a thousand embedded controllers spread over a whole country whose problem was that downloading didn't work.... a truck roll to wach one was not an option. But, that's another story (bootstrapping the fix was horrendously more complex that finding the bug).

    --
    You could've hired me.
  4. Re:Debug versus release bug by ComputerSlicer23 · · Score: 4, Informative
    Hmmm, you broke the rules from the MS Press books. Both "Writing Solid Code", and "Code Complete" mentions specifically to never ever have code with side affects inside of an assert statement (more generally no side affects in debugging code). Both outstanding books, that have lead me down the path so I don't have war stories about debugging anymore. That and I don't do embedded programming anymore.

    Good books, MS tools are weird mainly because I like my commandline a bit too much, but they publish some damn fine books about programming.

    This is also a case of found easily by reading the output of gcc -E, you best friend when debugging code that has macro's anywhere near it.

    I had never changed a flag that said I wanted it to strip them, so I assumed it wouldn't. Never trust M$

    I hate to post a flame, but RTFM. On every compiler or tool you ever use, spend several days reading the manual and all associated docs you can find. Knowing how the compiler works, and how all the tools work is a hallmark of all the finest programmers I know. I used VC++ a handful of times 5 year ago, and I could have told you the asserts were stripped in from release mode. All you have to do is look at the full list of options it puts on the command line. That's relatively easy to find in the menuing system on VC 4.0 (the only version I used). The -DNDEBUG=1 flag turns off asserts.

    Kirby

    PS: Other then the keyboard and mouse I use, I haven't used a Microsoft product on a daily basis in years. It's about craftsmanship, and knowing your tools.

  5. Re:Multi-threading by ssun · · Score: 2, Informative

    Take a look at VeriSoft, "a tool for software developers and testers of concurrent/reactive/real-time systems."
    http://www.bell-labs.com/project/verisoft/

  6. Re:Multi-threading by hotpotato · · Score: 2, Informative

    For those working in the comfy Java world, there's JProbe Threadalyzer . It can detect deadlocks, race-conditions, and other such niceties, and display them visually.

  7. Re:String equality in Java by sir99 · · Score: 2, Informative
    The JVM instantiates a NullPointerException and propagates it up the call stack.... In C, dereferencing a bad pointer is like pissing on an electric fence. It's nondeterministic. You're not running bytecode- that's real machine code.
    Don't be ridiculous. Machine code vs. bytecode is irrelevant. On POSIX systems, dereferencing a null pointer causes a SIGSEGV signal to be sent to the process. SIGSEGV is catchable, so it would be fairly trivial to simply throw your own nullpointer exception in C++, or to integrate it with whatever exception mechanism you may have built in to your C program. I suppose you could even set SIGSEGV to be ignored, but POSIX says that the result is undefined (could be a fun source of bizarre program failure :-)
    --
    The ocean parts and the meteors come down
    Laid out in amber, baby.
  8. Re:String equality in Java by Anonymous Coward · · Score: 1, Informative

    Java does _not_ guarantee that. It does guarantee that for the special case of a = "hello", b = a, then b == a.

    Once you realise that Strings are Objects, all Objects are by reference (essentially any variable that is a subtype of Object is a pointer^H^Hreference), it makes perfect sense. == is a reference comparison, = is a reference assignment - so a and b point to the same string object.

    This also has implications for function calls. Java is NOT a pass-by-reference language, but a pass-reference-by-value. For the most part, these are effectively the same thing, with one major difference. If I

    baz () {
    bar = "hello" ;
    foo(bar);
    [more code]...;
    }

    in java , the call to the foo method CANNOT change bar to point to a different object in the enclosing scope [more code] in baz(), but it can modify the object bar points to. In a true pass-by-reference language, foo could change bar to point to a different object, and the change would afffect [more code] i.e. it can modify bar itself...

    This is a subtle distinction, and one that can catch people out in Java and Lisp.