Slashdot Mirror


New & Revolutionary Debugging Techniques?

An anonymous reader writes "It seems that people are still using print statements to debug programs (Brian Kernighan does!). Besides the ol' traditional debugger, do you know any new debugger that has a revolutionary way to help us inspect the data? (don't answer it with ddd, or any other debugger that got fancy data display), what I mean is a new revolutionary way. I have only found one answer. It seems that Relative Debugging is quite neat and cool."

351 comments

  1. Exceptions by AKAImBatman · · Score: 3, Interesting

    Java Exceptions *were* a revolution in debugging. Java stack traces tell you the exact line number something went wrong, and the path taken to get there. More often than not, that's plenty of information to track down the bug and fix it. No need to load a debugger.

    1. Re:Exceptions by Anonymous Coward · · Score: 3, Insightful

      Sometimes something goes wrong WITHOUT causing an exception. Those are the bugs hard to find.

    2. Re:Exceptions by bdash · · Score: 3, Insightful

      Java Exceptions *were* a revolution in debugging.

      Because everyone knows that Java invented exception handling...

    3. Re:Exceptions by Anonymous Coward · · Score: 0

      What? You're saying every bug produces a crash at precisely the location that the bug occurs?

    4. Re:Exceptions by Morgahastu · · Score: 1

      Perhaps but making your program rely on catching execeptions to handle bugs isn't very good. And adding a bunch of try and catches when you experience a bug to try and find it really does take a long time.

    5. Re:Exceptions by eyeye · · Score: 3, Funny

      Line numbers? What next.. fire?

      --
      Bush and Blair ate my sig!
    6. Re:Exceptions by Delirium+Tremens · · Score: 3, Informative

      Java invented the dynamic analysis and handling of stack traces, not just exceptions.
      If you are into dynamic analysis and recovery of exceptions -- that is, self-healing software --, that is a very powerful tool.

    7. Re:Exceptions by bdash · · Score: 3, Informative

      Java invented the dynamic analysis and handling of stack traces, not just exceptions.

      Where is your evidence that Java "invented" this? I have seen several other languages that are at least as old as Java that contain this feature, so some facts wouldn't go astray...

    8. Re:Exceptions by Tim+Browse · · Score: 1

      Heh...that's set me up for the day! Thanks :)

      "Get on that teletext!"

    9. Re:Exceptions by mattgreen · · Score: 1

      I fail to see how stack traces are self-healing software. The program still crashes, self-healing implies that it would somehow get around the error and continue execution at some point.

    10. Re:Exceptions by smallpaul · · Score: 1

      Python had this feature in around 1992, long before Java was called Java or was public.

    11. Re:Exceptions by Anonymous Coward · · Score: 0
      This has been done for ages in (carrier-grade) embedded system. Walking back the stack and compare the each stack frame with the run-time symbol table is TRIVIAL. I've done that (in C) years ago. that how the debugger work with core-dumps, except that you do that at runtime. Nowaday, you rarely need to do that manually since most modern embedded oses have that facility built-in.

      Just look at the ABIs. All of them were designed so that you can walk the stack at run-time. And most of them predate Java for decades.

      The only revolutionary thing from Java is its ability to attract a humongous number of (technologically-blind) zealots.

    12. Re:Exceptions by smallpaul · · Score: 2, Informative

      Java invented the dynamic analysis and handling of stack traces, not just exceptions.

      Python has the same feature and Python is older than Java. It would take some effort to prove that Python had introspection of stack traces before Java did, but it seems quite likely to me. And it seems even more likely that some variant of Lisp had it long before Python.

    13. Re:Exceptions by bdash · · Score: 1

      A quick look at the Python sources reveals a file named traceback.c that contains the "traceback implementation". The earliest revision in Sourceforge's CVS repository is dated Thu Dec 20 15:06:10 1990 UTC.

      I would be interested to hear when Java developed similar features.

    14. Re:Exceptions by dark404 · · Score: 1
      He's talking about Try-Catch-Throws which are part of the Java exception system.
      Try {
      // code that may crash
      } Catch (Exception e) { // or a specific type of exception
      // code that will handle the exception
      }
      or if you aren't handling the exception in the method
      public void doSomething() throws typeofexception {
      // code that may generate an exception
      }
    15. Re:Exceptions by smallpaul · · Score: 2, Informative

      I'm looking at the source code for Python 1.1. It has a function called "extract_tb" which generates a list that you can manipulate and handle from a traceback. According to the changelog, that feature was added in 1994, the year before Java was released. I would bet money that the feature is much, much older than Python.

    16. Re:Exceptions by bigjocker · · Score: 2, Interesting

      Care to name one of them? That is, one programming language, invented prior to Java, that includes detailed exception handling and execution stack traces that show source file name and line numbers (this implies that the language must have native multithread capabilities).

      --
      Life isn't like a box of chocolates. It's more like a jar of jalapenos. What you do today, might burn your ass tomorrow.
    17. Re:Exceptions by bdash · · Score: 2, Informative

      Care to name one of them?
      See this post for a concrete example of such a language. It would be nice to see some evidence of a) when Java grew these features, and b) that it was the first language to have such features.

      this implies that the language must have native multithread capabilities
      Huh? What does threading have to do with exception handling? The two are almost completely unrelated, and the presence of one feature in a language in no way requires nor implies the presence of the other.

    18. Re:Exceptions by WWE-TicK · · Score: 1

      I'm not sure how this is supposed to be "self-healing". If the exception isn't handled by somebody, you get a program crash. And this mechanism certainly isn't exclusive to Java; indeed any language which supports the notion of exceptions would certainly have a way to catch and deal with a thrown exception.

      Perhaps Delerium can elaborate on what he means by "self-healing".

      Java's stack traces for uncaught exceptions are handy though. I wish C++'s exception handling mechanism had something similiar built-in. I once read an article in Dr.Dobb's that showed you how to achieve the same thing in C++. Unfortunately it involved the use of ugly macros and required the programmer to remember to call these macros whenever you entered and left a function.

      However, I bet you can write a C++ debugger that'll show you the exact location of where an uncaught exception was thrown thus alleviating the need for a stack trace. Anybody know of such a debugger?

    19. Re:Exceptions by dark404 · · Score: 1
      Just to clarify: There are two types of Exceptions in java. Handled and Unhandled (note, this has nothing to do with if you are handling or not handling the exceptions). Unhandled exceptions do not have to be declared as being thrown by the method nor do they have to be handled by something using the method. Handled exceptions MUST be decaled to be thrown, AND must be handled by what calls the method.

      So if you declare a method throws a specific type of exception, any class calling that method must handle the exception or also declare to throw it. In the end, SOMEONE has to handle it, or it will be caught at compile time as an error.

    20. Re:Exceptions by michael_cain · · Score: 3, Interesting
      Java stack traces tell you the exact line number something went wrong, and the path taken to get there.

      Just as a historical note, the APL system that I used in 1975 provided this capability. When an exception occurred, the interpreter halted program execution, identified the problem and the source line, and provided access to the stack info on how (functions and line numbers) you had gotten there. You also had the ability to examine any variable that was currently in scope, and could change values and resume execution. Given the cryptic nature of the language, you needed all the debugging help you could get. Still, for certain types of numerical problems, you could get a lot of effective code written in a very short period of time.

    21. Re:Exceptions by pla · · Score: 1

      If you are into dynamic analysis and recovery of exceptions -- that is, self-healing software

      Stupid question time...

      Why not make it work correctly, rather than praying the language can make up for the programmer's ineptitude?

      I guess I show my age here (and I haven't even hit 30 yet)... Once upon a time, we just made the code work. We didn't need the compiler to read our minds to know our intent (and, in fact, most "real" programmers find it severely annoying when the compiler tries to second-guess us).


      If your code has a bug, FIX IT. Trusing that you have a serious enough bug to throw an exception, yet a mild enough bug to leave exception-throwing intact, just begs for trouble. But then, you also said:


      Java invented the dynamic analysis and handling of stack traces, not just exceptions.

      Which tells me that you either count as a troll, or completely clueless about the subject matter. Care to tell us which one?

    22. Re:Exceptions by TheSunborn · · Score: 1

      I would say c++ with a debugger such as gdb qualify. In fact I sometimes prefer to debug c++ code with a coredump insted of java becasue you also get the value of your variabels which is often usefull.

    23. Re:Exceptions by JohnFluxx · · Score: 2, Informative

      Say you have a button on a form that performs some function. you have something like:

      doSomeFunc()

      Now you know that doSomeFunc() should be correct, and shouldn't have any errors. But you might have missed something - perhaps a divide by zero, or something.
      So you do:

      try {
      doSomeFunc();
      } catch (Exception e) { //handle
      }

      where you try your best to handle the error gracefully (tell the user, disable the button, contact admin team, suggest a work around, etc)

    24. Re:Exceptions by JohnFluxx · · Score: 1

      Because in a complicated bit of code, it can be difficult to write bug free code.

      I work with lasers, and do complicate mathematics. So I have a function that does say:

      doMaths();
      assertMaths();

      where doMaths() does the calculation, then assertMaths() double checks the calculations (probably by doing the maths in reverse - often very quick) then if the assert fails, throw an exception.

      This is an example where it shouldn't fail, and might work 99.9% of the time, but if it does fail, I want to know and I want it to try to recover.

    25. Re:Exceptions by John+Courtland · · Score: 2, Informative
      What does threading have to do with exception handling? The two are almost completely unrelated, and the presence of one feature in a language in no way requires nor implies the presence of the other.
      I'd like to reinforce this statement. The only reason you would need multithreading is if you set up a watchdog timer to anticipate an infinite/semi-infinite loop state. Exceptions are almost exaclty like interrupt vectors. You set up a handler, it gets stored in a table, and if needed, it's called. In fact, some exceptions, like GPFs or invalid opcodes throw a hardware interrupt.

      Also, if you're smart, you can take the stack traces and find exactly what functions/datum those were. Had to do that a bunch on the IBM S/390. It's not hard, and with debugging code enabled, any exception generated will be able to produce line numbers and function traces.
      --
      Slashdot is proof that Sturgeon's Law applies to mankind.
    26. Re:Exceptions by Paul+Fernhout · · Score: 4, Informative

      Lisp and Smalltalk possibly in the 70s & certainly in the 80s (when I used ZetaLisp on a Symbolics and Smalltalk on various hardware -- Mac, TI, etc.).

      How much has been forgotten. Time and time again I hear people claiming Java invented something when it was just the place they first saw it compared to programming in C or TurboPascal or whatever. Java does have some ideas it popularized -- but they are things like interfaces. Much of its class design like for Swing was taken from ParcPlace Smatallk's VisualWorks. Hotspot profiling came from Smalltalk. MVC came from Smalltalk. etc. etc. Between Forth, Smalltalk, and Lisp (and a few other languages and libraries) most of the innovations people see now were invented a long time ago. VMs came from Smalltalk and IBM mainframes (first) and Pascal and Forth. Another example -- XML is a stupid version of Lisp s-expressions. And so it goes...

      --
      A 21st century issue: the irony of technologies of abundance in the hands of those still thinking in terms of scarcity.
    27. Re:Exceptions by rpresser · · Score: 1

      Clipper 5.x for DOS, circa 1989. Multithreading is a red herring; all you need is a stack trace, and that only requires a decent VM, which Clipper pretty much had.

    28. Re:Exceptions by Anonymous Coward · · Score: 0

      Err.. grauchk... NOOO!! My faith in Java has been shaken!

    29. Re:Exceptions by IWannaBeAnAC · · Score: 1
      Yeah right.

      And how often to programmers actually go to the effort of doing this?

    30. Re:Exceptions by Anonymous Coward · · Score: 0

      tcl has always had this, and predates java.

    31. Re:Exceptions by tonejava · · Score: 0

      You still cannot beat the JPDA. With hot-loading of classes during runtime it has made development and fixing bugs much easier. When you can reload classes in a web app remotely during debugging that is my idea of the perfrect debugging tool!

    32. Re:Exceptions by Anonymous Coward · · Score: 0

      That capability depends on the Java compiler used to compile the file where the exception occurred.
      Java class files contain metadata called 'Attributes', some are compulsory, i.e. the Code attribute, others such as the LineNumberTable (which provides this in-depth debugging facility) are not.
      They can be stripped from the compiled file if need be.

    33. Re:Exceptions by oops · · Score: 1

      Java stack traces tell you the exact line number something went wrong

      No. Java stack traces tell you where the exception was thrown.

      They don't tell you (for example) where you set a reference to NULL when you shouldn't have! (NullPtr pattern)

    34. Re:Exceptions by Dashing+Leech · · Score: 1
      Well, I'm not really a programmer, so someone can correct me if this doesn't qualify, but Matlab has been able to state which filename and line number a failure occured for as long as I can remember. As far as I know, this feature pre-dates Java.

      (Some may argue that Matlab is not a programming language, but that would just be semantics in this context.)

    35. Re:Exceptions by Anonymous Coward · · Score: 0

      Of course, with APL such a feature is completely useless unless it gives you the source character as well, no? ....

    36. Re:Exceptions by AKAImBatman · · Score: 1

      You're referring to syntax errors. That's similar to what a compiler does. Java Exceptions are more along the lines of runtime error handling. i.e. Methods for handling errors during execution. Things get a little blurred when we're talking about interpreted languages, but we can still separate syntax errors from runtime errors. (e.g. The former would be accidently typing a command like "prnt" instead of "print" while the later would be the variable "myvar" being used before it was given a value.)

    37. Re:Exceptions by AKAImBatman · · Score: 1

      I'm aware of that. But seeing a NullPointerException is often enough to infer where the Null came from. :-)

    38. Re:Exceptions by Mostly+a+lurker · · Score: 1
      Of course, with APL such a feature is completely useless unless it gives you the source character as well, no? ....

      LOL ... yes indeed. APL programs that I had problems with were often less than 10 lines of code, but each line of code could contain more functionality than an entire modern java procedure.

      In fact, though, the APL debugger did point at the actual APL function that generated the exception.

    39. Re:Exceptions by jovlinger · · Score: 1

      Hotspot profiling came from Smalltalk.

      I thought that was self.

    40. Re:Exceptions by Gilk180 · · Score: 1

      gdb.

      1. run program
      2. get uncaught exception
      3. ask for a backtrace

      The first few lines are library calls taken while deciding what to do with the exception. The rest are useable.

    41. Re:Exceptions by csirac · · Score: 1

      Perhaps he's talking about assert failures. Matlab's %assert even does a stack dump.

    42. Re:Exceptions by starbuck5250 · · Score: 1
      Java Exceptions *were* a revolution in debugging.

      IBM's System/38, AS/400 and iSeries computers use exception processing for all errors in all languages on the box. If you don't trap errors, the job will stop and force you to deal with them when they arise. 1978. The Free Dictionary

      --buck
    43. Re:Exceptions by jo42 · · Score: 1

      The Exception being when the JVM crashes... :]

    44. Re:Exceptions by Anonymous Coward · · Score: 0

      Java being neither a person nor a company, it cannot really have invented something.

      The only thing Sun may have invented with Java is marketing by obfuscated terms and hype. Try to define Java. Sun will insist it's more than a language, more than a technology, more than a platform, more than the universe. This has gotten to the point where young developers think that interprocess communication is some sort of magic possible only because of Java. (FYI, sockets have been around since, oh, the 60s?) And senior developers have a hard time finding out if a given feature is available "in Java". Do they need it in Java the language, a Java library, or just anywhere in the known universe?

      Of course, Microsoft or IBM may have beaten Sun to the invention of hype and obfuscated terms.

    45. Re:Exceptions by michael_cain · · Score: 1
      Of course, with APL such a feature is completely useless unless it gives you the source character as well, no? ....

      Absolutely correct. The debugger pointed to the exact point in the offending line where the exception occurred. Not that that was necessarily a lot of help when you were trying to figure out why a matrix that was supposed to have three dimensions now had four...

    46. Re:Exceptions by Dashing+Leech · · Score: 1
      Well, in a sense, yes, most Matlab errors would be syntax errors. But it does include errors such as references to cleared variables and such, which I believe would be equivalent to your "myvar" case. It also includes memory errors and numerical errors (e.g., near singular matrices). I think those would qualify as runtime, not syntax.

      And yes, it's hard to really compare interpreted vs compiled in this respect.

  2. What's New? by ipour · · Score: 1

    Seems like this form of debugging isn't too different from alpha testing. I don't see how this saves any work.

  3. Avoid debugging by heironymouscoward · · Score: 5, Insightful

    You get what's called 'glassnose syndrome' too easily.

    Instead concentrate on building software in many small incremental steps so that problems are caught quickly, and on separation of design so that dependencies are rare.

    If you can't find a problem, leave it and do something else.

    Otherwise, print statements, yes, that's about the right level to debug at.

    --
    Ceci n'est pas une signature
    1. Re:Avoid debugging by TrentL · · Score: 1

      My programs don't have a lot of bugs when they are finished. I think the reason is that I physically cannot code for more than 15 minutes without compiling and running. Obviously, my programs do have bugs that turn up when they're "done". But I catch a helluva lot before that time becuase I test each little bit of functionality as I build it.

    2. Re:Avoid debugging by mattgreen · · Score: 4, Insightful

      Ah, nothing like claiming that your way of approaching something is the only way. A debugger is just a tool. Like any other tool it can be bad if it is misused, and it isn't appropriate for every situation. I find a debugger invaluable for jumping into someone else's code and seeing exactly what is happening step-by-step. Debuggers can be great if you suspect buffer overflows and don't have access to more sophisticated tools that would detect it for you. Just yesterday I used a debugger to modify values in real-time to test code coverage.

      Inserting printf statements into the code is probably not logging - usually if you are debugging they are destined for removal anyway. I use a logging system that shows the asynchronous, high-level overview of events being dispatched and then can use the debugger to zero in on the problem very quickly without recompiliation. In addition if a test machine screws up I can remotely debug it.

      If you want to throw out debugging because Linus isn't a fan of it, be my guest. But I'm not a fan of wasting time, and injecting print statements into the code plus recompiling is a waste of time and ultimately accomplishes close to the same thing as debugging. Any decent IDE will let you slap a breakpoint down and execute to that point quickly. But I assume someone will come along and tell me that IDEs are for the weak as well.

    3. Re:Avoid debugging by jaoswald · · Score: 3, Insightful

      The main advantage of printfs over IDE/interactive debugging is that you can collect a lot of data in one burst, then look at the text output as a whole.

      The tricky part about IDE/interactive debugging is understanding the behavior of loops, for instance. Sure you can put a breakpoint in the loop, and check things everytime, but you quickly find out that the first 99 times are fine, and somewhere after 100 you get into trouble, but you don't quite know where, because after the loop, everything is total chaos. So you have to switch gears; put in some watch condition that still traps too often (because if you knew exactly what to watch for, you would know what the bug was, and would just fix it), and hope that things went wrong, but left enough evidence, when it traps.

      Whereas print statements let you combine the best of both worlds: expose the data you care about (what you would examine at breakpoints), but the ability to scan through the text result to find the particular conditions that cause the problem (what you could potentially get from watch conditions).

    4. Re:Avoid debugging by mattgreen · · Score: 1

      You've given me one case where print statements are better than a debugger. OK, that still doesn't prove that debuggers are worthless, as the original poster implied.

    5. Re:Avoid debugging by jaoswald · · Score: 3, Insightful

      Hey, I'm certainly not going to call debuggers useless; I use them, albeit usually in a crude way to do stepping where I need to check hardware state. But I must say that I have rarely felt comfortable using an IDE debugger to find a logic error; the old insert printfs and read, or interactive use of a Lisp REPL or test harness have always felt more comfortable.

      Another advantage of printfs or adding code to the app is that most languages are more powerful than the UIs of interactive debuggers; even the best inspectors make it hard to filter out large arrays to find the problem in element 1085. But I can add a little helper function to scan through the array in code and find exactly what I want. In Lisp, the full language is available in the debugger, so the debugging and coding are hard to distinguish.
      Sometimes the tools you write to make the code are the same tools that are useful for debugging, whether you plan it that way or not.

      Different strokes for different folks---we're all fighting the same enemy: the bugs.

      There is something weird about debugging, however, which I can't quite put my finger on. Powerful language features have a return on investment which has a longer time to compound. You can attack bigger problems by understanding the language better, so spending time to understand the language pays off.

      Powerful debugger features don't really have time to compound. Sure, they may save you 50% of your time tracking down a particular bug, but only if you recognize that the bug you have is solved with that tool.If you get a lot of practice using that tool, however, you'll tend to stop making the kind of specific mistake that makes the tool valuable.

      Before you know how to use a language feature, you can write toy examples until you can feel comfortable. It's hard to practice with a debugger; how do you make toy mistakes---make a mistake deliberately and forget what mistake you made?

    6. Re:Avoid debugging by thestarz · · Score: 2

      But I assume someone will come along and tell me that IDEs are for the weak as well.

      Beware the IDEs of March!

      --

      c++; /* this makes c bigger but returns the old value */
    7. Re:Avoid debugging by computational+super · · Score: 1

      "Glassnose Syndrome"? Is this your term, or is this something that's been published/studied/researched elsewhere?

      I've always had sort of an intuitive notion, partly based on experience and observation, that being too IDE-centric produces "bad code" - code that resists change, can't be reused outside the context in which it was written, relies on everything else being in a specific (undocumented) state at a specific time, etc... but this is hard to get across to other people - especially project managers (who can't understand why any programming takes longer than a couple of hours - "all you're doing is typing, after all! I thought we hired you because you knew this language.") or beginners (who already know everything, of course - "I used this IDE in college, and all of the 'Hello World' assignments I got from my professor worked great! You old-timers need to get with the 21st century.").

      Can you expand a bit more on "glassnose syndrome"? Where it gets its name, what the symptoms are, what the effects are, etc?

      --
      Proud neuron in the Slashdot hivemind since 2002.
    8. Re:Avoid debugging by geckofiend · · Score: 1

      Debugging is a skill just like development. Once you've learned a *good* interactive debugger you can find and fix bugs in much less time than you could with printfs.

    9. Re:Avoid debugging by Dixie_Flatline · · Score: 0

      That's the way I used to do most of my debugging. I'd fire up DDD only if I needed to see the state of a lot of data in a way that I needed a picture of. Conceptually, it's sometimes better to actually SEE what you're dealing with, rather than just having a bunch of printfs and a huge text log to search through.

      However, working on a deveopment team on a game for the XBox has really shown me that a debugger can be incredibly useful. I can't control how other people program, and while I try to code my systems in a modular, intelligent way, bugs are bound to slip in. It gets even worse when I'm told to start inserting features that weren't originally planned. I do my best to maintain orthogonal systems, but it's a hard battle that you can't always win when you're trying to be expedient.

      We use a great deal of logging in our game code, but there are things that don't lend themselves well to being dumped to text. We have events happening thirty times a second, and if you try logging that sort of thing, not only do you murder the framerate (making it slower to reproduce the bug that you're looking for) but you end up with an astounding amount of text. Looking for anomalous results in 10MB of text for a run of only a few minutes isn't my idea of a good time.

      Lastly, when you don't know the system that the problem is in and you've got over a hundred files to work with, checking out 30 of them so that you can put a printf in each one as you binary search through the code is significantly more time consuming than just putting a break point in where you think the problem may occur. Most of the time our problems that manifest themselves graphically aren't actually problems with the graphics engine; some game-side programmer is just doing something stupid. Break-pointing in a graphics method and climbing back up the stack isolates the problem in significantly less time.

      All that said, if you can make print debugging work for you, that's great. If you can back up your claim that you write largely bug-free code, and make errors that are of the small, easy to find sort, even better. You'll have a job forever. However, most people don't program like that. It's just the way it is. Of COURSE the best way to debug code is to not write code with bugs in it, but that's just not a reasonable assumption or demand.

    10. Re:Avoid debugging by ForteTuba · · Score: 1

      An interesting way to practice with a debugger would be to create a set of "known bad" programs with hints and solutions available. This'd be a nice little open source resource to develop that, say, teachers could use to help students figure out how to debug and do maintenance type programming.

    11. Re:Avoid debugging by ron_lima · · Score: 1

      I think that printfs in development environment are not a good idea. It helps when you have an environment where there is no debugger at all.

      For example, your program has a bug that you cannot reproduce in your test environment but the user has a test environment where the bug can be reproduced. Using it in the development environment sometimes can give you more headaches than if you use the debugger itself. For example, if you have a problem in the code and need to add an extra variable to build some data using a sprintf function and then the printf. You have added data to the stack of the local scope and probably have masked some memory invasion, since you have changed the stack. Also, printf may not be fast enough: it writes data into the buffered output. So, if your program dies for some reason, all the pending data in the buffers will be lost. Another problem is when you forget to delete the printfs from your code: you may annoy your users by putting messages on their consoles with some strange stuff like "PASSED HERE 1", "PASSED HERE 2" and so on. There is another stuff that is interesting: printfs can coredump! For example:

      printf ("Something: %s");

      Try it! It coredumps nicely! Debugging codes is always a pain. A good idea is to automate the debugging session. I've been using the .dbxinit files for unix debugging with great results, since I never lost what I'm doing, since all the breakpoints and print data is in a script that is stored in the disk. Automating the debugging sessions make it easy to analyze the most inconvenient loops inside your code. Also, it is good to share to other developers your script file since it may help them to see what you have looked into the code to solve some problems.

      --
      Ronaldo Faria Lima
      E-mail:ronaldo@ronaldolima.eti.br
      Home page: http://www.ronaldolima.eti.br
    12. Re:Avoid debugging by PurplePhase · · Score: 1

      I'm using Eclipse 2.1.3 for Java programming, and while I think all Eclipse/WSAD let you place a breakpoint on an exception type caught or uncaught - which are the obvious things shown in the logs (eg. a NullPointerException, ArrayIndexOutOfBoundsException, etc.), you also have the interpreter available from way back in VAJ so you can run an arbitrary expression to determine values in objects, arrays, etc. (add the Display View) And you need it for interpretting things like the blasted GregorianCalendar!

      8-PP

  4. Valgrind by brejc8 · · Score: 4, Interesting

    Oh I do love it. My boss had 100% faith in his code claiming that he tests it so much it cant have any bugs. Running it through valgrind showed pages worth of bugs which were only accidently non-fatal.

    1. Re:Valgrind by evvk · · Score: 1

      Yeah, Valgrind is a wonderfull aid.

    2. Re:Valgrind by Daniel · · Score: 3, Informative

      AOL.

      Valgrind is possibly the most useful debugging tool I've found lately. It's especially great for tracking down slippery memory bugs -- you know, the type that are virtually impossible to find using most debugging tools.

      For people who haven't used it, what it basically does is recompile your program to target a simulated x86 CPU. It can detect branches that depend on uninitialized values, writes through a freed pointer, and a whole slew of other nasties that are difficult or impossible to detect with other tools.

      Daniel

      --
      Hurry up and jump on the individualist bandwagon!
    3. Re:Valgrind by Soul-Burn666 · · Score: 4, Informative

      It wasn't infered from your post, but it is important to note that your do not need to recompile your code to get it to work. It wraps already compiled executables. Though it would be smart to compile with -g so that it tells your which lines the errors happend and such.

      --
      ^_^
    4. Re:Valgrind by Anonymous Coward · · Score: 0

      Hahaha! You guys had me going... I thought Valgrind was some kind of debugger from your posts, and since you were all careful not to put any links in, I fell for it and went googling. Heh... Val Grind... she is pretty hot, but I still would have appreciated a NSFW warning.

  5. More of the same by poptones · · Score: 4, Interesting
    How is this "revolutionary?" All you are doing is generating a bunch of test vectors and feeding them to a machine instead of comparing them yourself. You could let programs "create" the test vectors if, as it says, there is another program of similar function to generate the vectors, but what if there isn't one?

    All you are doing is replacing human eyes with a computer at the first "filter" process. Instead of having to compare a bunch of values and look for the errors, let the machine point them out to you - grep anyone?

    I see nothing reolutionary about this. You still have the DUT making "assertions" - duuuuh can you say "print?"

    1. Re:More of the same by Herschel+Cohen · · Score: 1

      Let's be fair, assertions are programming logic and if untrue you can exhibit quite a bit without stopping for another print.

      Nonetheless, assertion code is not new and I have encountered it in several languages and I know <b>very few</b>. What is more appropriate is what has been pointed out by other, earlier messages: a reference application may not exist.

    2. Re:More of the same by computational+super · · Score: 2, Insightful

      I have to agree... this sounds as revolutionary as "Junit". Yes, if you follow the paradigm correctly, you'll produce 100% bug-free code, but it would take so long to follow the paradigm correctly, you'd never get anything done. Not to say that it doesn't look like it might be useful, but I think they're being disingenuous about the amount of work that's going to go into using it.

      --
      Proud neuron in the Slashdot hivemind since 2002.
    3. Re:More of the same by MechaStreisand · · Score: 1

      I wouldn't say that it leads to 100% bug-free code: that's a pretty strong statement. It seems to me that that's not guaranteed unless all possible code paths are taken during development, which seems unlikely for code of any serious complexity. I think the only way to really be certain that there are no bugs at all is to do a correctness proof.

      Furthermore, how do you know there aren't any bugs in the reference code?

      That said, it does seem useful, and would probably lead to reasonably bug-free code, but only for a certain class of problems - those where you have existing, correct reference code that for some reason you don't want to use.

      --
      Disclaimer: IANAL. This post is, however, legal advice, and creates an attorney-client relationship.
    4. Re:More of the same by computational+super · · Score: 1

      not guaranteed unless all possible code paths are taken during development

      Exactly - as I said, if the paradigm is followed correctly (maybe "completely" would have been a better choice of word?), that would be the case. It's just that it's not not feasible to do so.

      --
      Proud neuron in the Slashdot hivemind since 2002.
    5. Re:More of the same by stoborrobots · · Score: 1

      I saw this before it was commercialized, (at a research organization's productline expo). The techique is designed to help you find "introduced" bugs.

      The process is to take a previously working copy of the program, as well as the current, buggy copy, and run them simultaneously, with the same inputs. Then you simply watch the internal state until it differs between the two copies.

      Wherever an alternative execution path is followed for a given set of inputs, that is the source of the problem.

      Note that it is of no help if you do not have a pre-existing, working copy of the program. (Or at least, it did not when I last saw it some years back... YMMV)

      Over-simplistic: probably.
      Limited usefulness: definitely.
      Value in the few cases where it works: priceless!

  6. Print statements work fine for me, too by YetAnotherName · · Score: 5, Interesting

    I haven't used a debugger in years; print statements are the only debugging tool I need.

    But bear in mind that almost all of my work these days are in environments where the bugs that traditional debuggers help you find are pretty much impossible to make in the first place (Python, Java, etc.). Instead of tracing data structures through bits of memory and navigating stack frames, you just focus on the application itself. It's kind of refreshing.

    1. Re:Print statements work fine for me, too by littlefoo · · Score: 0

      Using the stack/back-tracing abilities in eg. Python and Java, do avoid many of the times you'd have to fire up a debugger in say, C or C++ - in fact this works fine until the bug is actually in ummm Python for instance, where many of us have spent plenty of time.. Who debugs the debuggers ?

    2. Re:Print statements work fine for me, too by Gorobei · · Score: 5, Insightful

      Print statements are a great tool, especially on large pieces of software maintained/enhanced by many people. Once you've debugged your problem, you just #ifdef out the prints, and check the code back into version control.

      When the next poor programmer comes along, trying to fix/find a bug in that code, he a) can #ifdef the prints back on and quickly get debugging output about the important events taking place in his run, and b) read the code and see where the hairy bits are, because they tend to be the sections most heavily littered with debugging print calls.

      Fancy debugger IDEs just don't support this preservation of institutional knowledge.

    3. Re:Print statements work fine for me, too by Anonymous Coward · · Score: 2, Insightful

      Yeah, it's always tempting to leave your debug printfs in and ifdef them out but I find that has two problems:

      1. When reading the code for logic, the print statements can be distracting and take up valuable vertical screen realestate. An algorithm without printfs can usually fit on a single screen. With printfs it may spill over two pages. That can make debugging harder if you need to understand what you're looking at at a conceptual level.

      2. Almost invariably I find that a previous person's printfs are almost totally useless because that person was usually debugging a different problem. Thus, enabling old printfs will dump out a whole bunch of information I couldn't possibly care about.

      Thus, I make it a point to clear out any debug printfs I was using before I check in my code.

    4. Re:Print statements work fine for me, too by Anonymous Coward · · Score: 0
      1. When reading the code for logic, the print statements can be distracting and take up valuable vertical screen realestate. An algorithm without printfs can usually fit on a single screen.


      Use an editor with folding capability.

      With printfs it may spill over two pages. That can make debugging harder if you need to understand what you're looking at at a conceptual level.


      Redirect stdout/stderr to a file. Besides, this sounds like a straw man. There's nothing stopping you from having differently detailed level of debugging output.

      Thus, I make it a point to clear out any debug printfs I was using before I check in my code.


      Fine, but I hope you document how you tested/debugged the algorithm so another developer can recreate whatever it was that you did.
    5. Re:Print statements work fine for me, too by Anonymous Coward · · Score: 0

      Who debugs the debuggers ?

      Larry.

    6. Re:Print statements work fine for me, too by Charles+Dart · · Score: 2, Funny

      I use humorous print statements e.g. in a loop i will put in

      echo 'bork! ';

      ....ahh, good times.

    7. Re:Print statements work fine for me, too by hachete · · Score: 2, Informative

      I agree with your comments 100% but try Log4j/Log4perl/Log4c. It allows you to turn debug info on/off through the config file. Saves you that extra claim

      h

      --
      Patriotism is a virtue of the vicious
    8. Re:Print statements work fine for me, too by Xyrus · · Score: 2, Insightful

      "I haven't used a debugger in years; print statements are the only debugging tool I need."

      You shouldn't limit your options. For instance, I can guarantee that I can find a fix a bug with a debugger faster than using printline's when dealing with cross-language projects. Like using Java's JNI to talk with native dll's, for example. The error could be somewhere on the java side or the C++ side. It could be the object on the C++ side, the converter to a Java object, the way the object is being used on the java side, etc. etc.. When you need to see a bunch of data simultaneously, a debugger is the way to go.

      Need I mention assembler? Much easier to look at the registers and stack in a debugger. :)

      I'm not saying that printlines are bad, because I use them frequently for quick to moderate debugging. But when I need to examine large objects, functions, etc. I bring out the debugger.

      ~X~

      --
      ~X~
    9. Re:Print statements work fine for me, too by Monkelectric · · Score: 1
      I haven't used a debugger in years; print statements are the only debugging tool I need.

      I'm afraid to say if printf is the only tool you need, you're either an insanely great programmer, or barely a progammer at all ... The printf debugging paradigm breaks down quickly when writing all but the most simple multi-threaded programs. If you don't know how to write multi-threaded code, then you aren't yet a programmer.

      --

      Religion is a gateway psychosis. -- Dave Foley

    10. Re:Print statements work fine for me, too by Dave419 · · Score: 0

      At my last job, we used exclusively log files for debugging since it was embedded development with a miniglx frontend. Thats the best method available until someone gets around to writing a custom debugger to use the serial port. It was a big pain in the ass since you needed to reboot from isolinux to read the logs. If this program could provide real time debugging on an embedded target, maybe using a PC simulation for comparison, it would be extremely valuable. It may not be applicable in that case, since it probably requires some sort of daemon running on each machine. If there was cross-platform and processor support it would be ideal for many situations. And for the record, _ASSERT( , ) == #ifdef DEBUG if( ) fprintf( , ); #endif since asserts are only compiled in for debug builds anyway.

      --
      ~ there are 10 types of people in this world, those that can read binary and those that can't
    11. Re:Print statements work fine for me, too by E_elven · · Score: 1

      Personally, in C++, I use a self-brewed logging facility that doesn't rely on #ifdefs but rather the compiler's optimizations.

      I'm sure many have similar versions, but in case someone's interested, the idea is simple -the Log object, when called, actually returns another object depending on the priority level of the string to be logged. If this priority level is lower (e.g. Priority::DEBUG) than the priority level that's set at compile-time for that particular Log object, it will return a functor that simply ignores any arguments given to it. This, on the few compilers I've tested it on, will result in those calls being optimized out entirely.

      --
      Marxist evolution is just N generations away!
    12. Re:Print statements work fine for me, too by phurley · · Score: 1

      Well I cannot comment for the grandparent post; however, I do a lot of multi-thread and multi-process programming and I have found that in these cases a nice tracing/logging system to be invaluable (as compared to debuggers, which outside of core dump type errors are almost worthless to find thread type error).

      Yes your trace code has to be thread safe and will effect the timing (sometimes hiding the bug you were search for, other times causing a bug that would not have otherwise occur -- but is still a bug none the less), but I do not know of a better way to understand the "flow" of threaded applications.

      --
      Home Automation & Linux -- now I know I'm a geek
    13. Re:Print statements work fine for me, too by Glug · · Score: 1

      The converse of your point is that print statements are also restricted to certain environments. When the code you're debugging is something like a high volume interrupt handler, print statements may perturb the system more drastically than the bug you're trying to find does.

      I use print statements a lot too, but sometimes print statements simply will not work and I need to use Winice, Periscope, tcpdump, an HP 1600A logic analyzer, or sometimes even some TTL chips and a few LEDs instead. Saying print statements are all you ever need to debug is like saying you can build a house using only a hammer. Sure, you *can* mix concrete, cut rebar, and dig drainage ditches using a hammer, but you look a bit silly to the rest of the crew.

    14. Re:Print statements work fine for me, too by martinflack · · Score: 1

      I code in Perl like a lot of web developers.

      #ifdef's are not really used in the Perl world (I suppose technically you *could* use a preprocessor), so I would like some form of 'print' command that is optimized away in the absence of a debug variable. I don't mean the print is not evaluated - I mean the arguments and the whole command is ignored, like a comment, when compiling to bytecode.

      So instead of this:

      print join(', ', map("\"$_\", @array)) if $DEBUG;

      have this:

      debug(join(', ', map("\"$_\", @array)));

      Having an official command:
      - allows much better optimization ($DEBUG can be set as a constant at compile-time)
      - allows editors to syntax-highlight the command in a special color
      - could let you override the debugging behavior (do something other than print it out)
      - allows the debugger, when you use it, to detect your debug commands and do something special (e.g. "please break on all my debug commands after printing the value")

      Anyone know of anything like this for Perl?
      If not I think it would make a great Perl 6 feature.

    15. Re:Print statements work fine for me, too by gurustu · · Score: 2, Interesting
      If you're working in Java, you should add assertions to your toolkit. You don't just preserve the institutional knowledge about where the code gets hairy, but you preserve institutional knowledge about what the internal state of the application is supposed to be.

      What's especially potent is that you don't actually need to comment the assertions out : leave them in your code, so that downstream users can activate them and confirm that there's nothing broken in your code. There's no performance hit when they don't ask for them, and if you're writing code for others to incorporate into their apps, you've just given them a powerful support tool.

      This is why configuration driven logging (like log4j) is such a leap over commented in/out println() statements : you can use them outside of your own development environment. Your customers, be they other developers or end users, can get an insight into how things are failing, either to diagnose problems for themselves, or to generate a report for you, so that you can find out what's going wrong for them.

    16. Re:Print statements work fine for me, too by bluGill · · Score: 1

      When the only tool you have is a hammer though...

      I was a carpender for a while. Once in a while I needed to dig a hole, and the only tool that would work was a hammer, so I dug a hole with a hammer. Of course if my job was digging holes I would get a real shovel, but the job rarely involved holes, so I made do.

      Printf works great on Unix, so that is often what we use. (often in the form of debug_print so we can turn parts off and on depending on which bug is suspected) Sometimes a debugger would be better, but so long as the pain of learning to use a debugger is greater than the gain we use printf. Eventually we will learn to use a debugger for problems that it is better for. We might or might not make greater use of the debugger after it.

      You use the tools you have. You should be aware of other tools, but often the pain of getting a different tool exceeds the gain of the tool. Doesn't matter if it is a carpender digging a hole, or a programmer debugging a program.

    17. Re:Print statements work fine for me, too by Zooks! · · Score: 2, Insightful

      > Use an editor with folding capability.

      For one thing my editor doesn't support this, and not all editors do. For another thing it depends on the folding implementation in the editor as to how distracting this is.

      > Redirect stdout/stderr to a file. Besides, this sounds like a straw man. There's nothing stopping you from having differently detailed level of debugging output.

      So now you want me to sit down and create sed/awk/grep/perl scripts to filter out stuff I don't want. No thanks. I'd rather just put in the print statements I actually need rather than waste time filtering out useless printfs I didn't want in the first place.

      Again, I've found most printfs to be useless except to the person debugging the particular problem. A reusable debug printf is a RARE thing. Why bother preserving them?

      > Fine, but I hope you document how you tested/debugged the algorithm so another developer can recreate whatever it was that you did.

      All I can say is: DUH. First off, I never said to delete comments, and as far as detailing how the file/problem was debugged, that's what the checkin log is for..

      --

      --

      "I'm too old to use Emacs." -- Rod MacDonald

    18. Re:Print statements work fine for me, too by WillWare · · Score: 1
      Log4j is cool, but one of the unfortunate things with Java is that the absence of a preprocessor means you can't get a truly zero-overhead logging statement in the production code. Depending what you're doing this may be important. One approach is to use a final static boolean to conditionalize your logging statements, then they'll really be optimized out of the compiled code, just like #ifdef with C.

      The other thing to be careful about (and I don't recall if log4j does anything for this) is that when the logging statement is switched off, you shouldn't construct the arguments for it, since that will at least change performance, and at worst have side effects in program behavior. The final static boolean can take care of this also.

      --
      WWJD for a Klondike Bar?
    19. Re:Print statements work fine for me, too by torpor · · Score: 1

      The parent is an elitist prick.

      "if you dont know multi-threaded, you're not a programmer", indeed ... how about "threads are for people who don't know how to write a state machine" ... thats another 'good' sagely programmer maxim.

      me personally, i've been programming professionally since 1978, and i still think that debuggers are a fad used by non-programmers to try and 'feel' like they're actually doing work ...

      --
      ; -- the corruption of government starts with its secrets. a truly free people keep no secrets. --
    20. Re:Print statements work fine for me, too by hachete · · Score: 1

      Sure, and I agree with all you say. I was wondering if log4c was any different? http://log4c.sourceforge.net/

      For the applications that I build - build & distribution software - logs are very important and maybe considered as being part of the application, so the Java quirk doesn't matter to me in this respect.

      h

      --
      Patriotism is a virtue of the vicious
    21. Re:Print statements work fine for me, too by Anonymous Coward · · Score: 0

      One of the problems with print statements is that they change timing. Say you have a multi-threaded or multi-process application with multiple units of execution contending for a single resource. Adding print statements changes the timing often resulting in a more synchronized flow of execution. As a result, your race condition or deadlock disappears rendering your debugging method useless.

      I find stack traces and reading/understanding code to be the most useful tools for debugging these kinds of problems. Based on what I've seen lately, reading/understanding code is pretty revolutionary.

    22. Re:Print statements work fine for me, too by Monkelectric · · Score: 1
      threads are for people who don't know how to write a state machine"

      Ah the cry of the C programmer. The thing about that statement is it completely ignores reality. CPU's are designed to run multiple threads, the multiple thread paradigm allows you to seperate concerns actually making your program simpler, and answer me this question -- How do you write a state machine for a 500 cpu distributed database?

      Can't be done. For any project that needs to run on more then once CPU the state machine bullcrap breaks down.

      --

      Religion is a gateway psychosis. -- Dave Foley

    23. Re:Print statements work fine for me, too by Anonymous Coward · · Score: 0

      "For one thing my editor doesn't support this,"

      I guessed that, that's why I suggested that you do if screen real estate bothers you so much.

      "and not all editors do. For another thing it depends on the folding implementation in the editor as to how distracting this is."

      I'll agree with that.

      "So now you want me to sit down and create sed/awk/grep/perl scripts to filter out stuff I don't want."

      Where the FUCK did I mention grep etc.? Ever heard of conditional compilation. This is programming 101 for goodness sake.

      "All I can say is: DUH. First off, I never said to delete comments,"

      And I never said that you should. Do you have problems reading son?

      In case you missed it dicklick, good debugging output statements both comment the code AND allow other people to recreate precisely the debugging output produced by yourself.

      Are you really this dumb or do you just play one on /.?

  7. Nothing I've done needs relative debugging by DeadSea · · Score: 4, Interesting
    To use relative debugging, you need a reference implementation that is correct. The only time I have that is when I'm extending an existing implementation with new functionality. In that case I use unit tests with assertions that compare the new and the old implementations.

    I suppose this would be useful if you were writing something in a new programming language. You could port your code and run the relative debugger to make sure that both implementations acted the same. In such a situation, that would be great, but such a situation isn't the common case for me.

    1. Re:Nothing I've done needs relative debugging by Bozdune · · Score: 1

      Actually, what you need more than a reference implementation is a set of assertions to test against, i.e. "state" -- the value of various items or datastructures at a given point in time. The problem, of course, is exactly what DeadSea is complaining about. Where's the reference data going to come from? We should all be so lucky to have such data.

      I actually think that the problem goes beyond data.

      I proposed a thesis at MIT that leveraged a parser generator to build a state machine representing the proper paths of program execution. Basic idea is that each key section of your program emits a token, the tokens are parsed according to a pre-defined grammar, and the parser generator's built-in syntax checking finds at execution time any paths that weren't anticipated.

      In other words, if you can write a grammar that describes all execution paths your program ought to take, then a parse error during testing becomes something that's really quite interesting to drill down on. The token stack tells you what happened, the parser knows what state you're in, what production it's reducing, and so forth, so it's easy to track down not only the call stack, which typically has limited context to tell you what's REALLY going on, but also the overall context of where you are and what the hell you're doing.

      Since LR parsers are really, really fast, the state tables they generate are small and tight, and tokens are generated at a relatively low frequency, the whole scheme imposes essentially zero overhead on program execution.

      Although the faculty member to whom I proposed this was wholly uninterested (Barbara Liskov: "The problem is not control, it is data" -- thanks for the deep insight, Barb), some guy in Canada got his PhD a couple years later with a similar idea. Don't know whether the concept ever found its way into a commercial product, but I would have killed for it a couple of different times in my career, especially for things like driver-level interrupt routines.

    2. Re:Nothing I've done needs relative debugging by slickwillie · · Score: 1

      I didn't get much past the first paragraph. It seems that their premise is faulty. If you have a working program (and how do you know it is 100% correct anyway?) why not just go with that one?

    3. Re:Nothing I've done needs relative debugging by Anonymous Coward · · Score: 0

      I suspect the idea is that if you understand what the fuck you want the program to, you may understand what it shouldn't do. Then you can add a number of checkpoints to see the program isn't grossly misbehaving... ah, fuck it.

    4. Re:Nothing I've done needs relative debugging by tepples · · Score: 1

      If you have a working program (and how do you know it is 100% correct anyway?) why not just go with that one?

      What if the working program is non-free or otherwise legally unacceptable? Using the existing non-free program as a test case helps in developing free replacements one by one.

  8. Good idea.. by sw155kn1f3 · · Score: 2, Insightful

    Good idea, but isn't unit testing + standard assertions do the same thing but in more automatic way ?

    You feed some data to functions, you expect some sane pre-calculated output from them. Simple yet powerful.

    And more important it's automatic. So you can integrate it into build process.

    --
    - Arwen, I'm your father, Agent Smith.
    - Well, you're just Smith, but my father is Aerosmith!
    1. Re:Good idea.. by Anonymous Coward · · Score: 1, Interesting

      And more important it's automatic. So you can integrate it into build process.

      Part of me thinks that the appeal of debuggers versus unit testing is that a debugger is something mysterious to use and therefore feeds the ego, versus unit tests which are simple to write.

      Course the end goal for a programmer is to deliver a workable system, and I think unit tests are the way to get there.

  9. AppSight Debugger by dominick · · Score: 2, Informative

    I am attending a college pursuing my Software Engineering degree and a company called Mutek showed us via weblink a new problem to track software issues. They called it AppSight. It could tell you exactly at which point your program failed. It even showed all the .DLLs your program called, COM objects that were created and even system calls made by the App. Mutek was bought out I believe and is now called Identify Software. You can see more about their technology at: http://www.identify.com/ - Dominick

    1. Re:AppSight Debugger by sjwt · · Score: 1

      But did it popup a nice freindly pink window
      with a title of "Dont panic" and all that info
      in it as well??

      As an actual question though,
      how customsable is it??

      --
      You have 5 Moderator Points!
      Which Helpless Linux zealot/MS basher do you want to mod down today?
  10. Another cool technique by Halo1 · · Score: 5, Informative

    Debugging backwards in time. See the Omniscient Debugger for an implementation in Java. Instead of re-executing the program a thousand times, each time setting breakpoints and watchpoints in different places to get nearer to the root cause of the problem, this debugger completely records all key events and lets you view the complete program state at any point in time.

    --
    Donate free food here
    1. Re:Another cool technique by Soul-Burn666 · · Score: 1

      DDD also allows "undo"ing steps you've made and also shows the data structures in nice structures, with arrows to successors and such...

      It's a very nice tool to use when you are trying to debug your AVL tree for a homework assignment for a Data Structures course ;)

      --
      ^_^
    2. Re:Another cool technique by jgrahn · · Score: 1
      The Omniscient Debugger seems similar to what Trace32 does, only in hardware and for embedded systems. Collect all memory accesses and CPU register changes in a huge circular buffer, and when you hit a breakpoint, you can move back and forth in time at will.

      This makes for some very interesting debugging techniques.

  11. Hey, nice ad! by EnglishTim · · Score: 4, Insightful

    I can't escape the suspicion that the anonymous poster is actually in some way connected to Guardsoft, but let's leave that for now...

    I think it's a good idea, but I do wonder how many situations you'll be in where you already have an exisiting program that does everything you want to test against.

    Having said, that, I can see how this would help with regression testing - making sure that you've not introduced any new bugs when fixing old ones. But I wonder how much it gives you above a general testing framework anyway...

    1. Re:Hey, nice ad! by fishdan · · Score: 5, Insightful
      I agree with you. I would have rather seen it posted without a reference to guardsoft and have someone mention it. I'm all for advertising on /. -- just not in the form of news.

      The fundamental issue here is that people are ALWAYS looking for a way to avoid having to write unit tests. I'm happy with a combination of Intellij and print statements. So far I've never had a situation where I though "the debugger isn't giving me enough information."

      I think that one of the reasons I'm happy with the debugging options available to me, is that I write my code so that it can be easily followed in the debugger. That means splitting my declarations and assignments, and other such things that make my code a bit more verbose, but eminently more readable. Lord knows as a child, I loved those complicated boolean switches, and cramming as much line into one line of code as possible. Now that my code is maintained by more people than me, I'm tired of people having ot ask me "what does this do." I used to get angry at them, but now I get angry at myself when that happens. We don't just write code for the users, we write it for our peers. Write code that your sibling developers will be able to follow in a debugger. I know some code is hard to follow, even with a debugger, so I write all my conditions as clearly as possible, name my methods and variables as clearly as I can and refactor reusable code into well named "submethods", so that we can solve "modules".

      This is because I want my code to last beyond my employment. Therefore it has to be maintainable by someone other than me. The real test of your code is: can someone ELSE debug it, using whatever the heck tools they want. A fancy debugger is a fine thing, but someday someone is going to have to debug your code with inadequate tools. My rule of them is "Code as if your life depended on someone else being able to fix it"

      --
      Nothing great was ever achieved without enthusiasm
    2. Re:Hey, nice ad! by humblecoder · · Score: 1


      I think it's a good idea, but I do wonder how many situations you'll be in where you already have an exisiting program that does everything you want to test against.


      Guardsoft probably also sells an add-on tool to verify that your reference implemenation is correct, and to debug it if it isn't correct.

      While I am always open to new ideas, based upon that single web page, it doesn't look like this product is going to revolutionize debugging. I can see it being useful in a small problem space where you are developing a program that has a small range of outputs where you can specify them explicitly. For the more typical, complex system, this system doesn't really help much.

      It reminds me of the academics who say the can use advanced math and logic to "prove" the correctness of a program. However, for a program of any complexity, the time it takes to prove the correctness of the program is astronomical: possible in theory but difficult in practice.

    3. Re:Hey, nice ad! by moexu · · Score: 5, Funny

      "Always code as if the person who ends up maintaining your code will be a violent psychopath who knows where you live." -- Martin Golding

      --
      "Seek first to understand." - Socrates
    4. Re:Hey, nice ad! by jay2003 · · Score: 1
      The real test of your code is: can someone ELSE debug it, using whatever the heck tools they want.

      I like the sentiment but the best test of any code is whether the next person would rather maintain it than write a new version him/herself. Software engineers have a bias towards rewriting stuff. If they decide it's easier to maintain the code you wrote, then you know you did a damn fine job.

    5. Re:Hey, nice ad! by swdunlop · · Score: 1
      I think it's a good idea, but I do wonder how many situations you'll be in where you already have an exisiting program that does everything you want to test against.
      Let's say you've written a quick and dirty implementation -- no optimizations, it expresses your data model, but rather inefficiently. Lots of linear and exponential time consumption. Certain programming practices recommend using the simplest, easiest implementation first, and optimizing the slower portions of the code until performance is acceptable. This tool becomes a lot more useful; the slower yet clearer implementation becomes your reference for writing the optimized version.
  12. Aspect-Oriented Programming can help by cpu_fusion · · Score: 5, Informative
    I've found that aspect-oriented programming using tools like AspectJ (for Java) can be a big help. There are aspect-oriented programming tools for many other languages.

    Basically, you can define an aspect to capture points in your program that are of particular note, and then do debug handling at those points. Aspect oriented programming allows you to break out that debug-handling logic into seperate modules, keeping your main sourcecode nice and clean.

    Aspect-oriented programming (AOP) has a lot of other uses too. I think in 5 years or so talking about AOP will be as commonplace as talking about OOP. They are orthogonal concepts.

    Cheers, Me

    1. Re:Aspect-Oriented Programming can help by wayne606 · · Score: 1

      I like Gerund-Oriented Programming. It's only well supported by Intercal, though

    2. Re:Aspect-Oriented Programming can help by javajedi · · Score: 3, Interesting

      One of the more interesting uses of AOP I've heard of was to intercept an Exception, and generate a JUnit test case that recreates the point in the code and the user input that generated the exception.

    3. Re:Aspect-Oriented Programming can help by Anonymous Coward · · Score: 0

      Dude! Post that code, or a link to it.

  13. Relative debugging, an idea whose time has come by Red+Warrior · · Score: 1, Funny

    I have some relatives who demonstrate numerous error conditions.

    --
    "If, therefore, any be unhappy, let him remember that he is unhappy by reason of himself alone."
    ~Epictetus
    1. Re:Relative debugging, an idea whose time has come by Patrik_AKA_RedX · · Score: 1, Offtopic

      Reboot them. Solves quite a lot of the problems. Male relatives can be rebooted with a well aimed kick in the nuts. (source: BOFH)
      I'm not sure if there is a way to reboot female relatives. Except perhaps pulling the plug and doing a cold reboot, but I'm not sure if that's legal.

  14. Right... by Anonymous Coward · · Score: 1, Funny

    So you already have to have a program that does what your program does in order to check it.

    Ever think of deploying that one?

  15. Revolutionary? NO. by News+for+nerds · · Score: 3, Interesting

    It looks no more than a fancy variation of good old 'assert' macro, or an antecedent of unit testing. Why did this anonymous submitter find it 'revolutionary'? What does it have over current debuggers which can be attached to working process or can analyze post-mortem dump?

  16. Old methods best. by hegemon17 · · Score: 4, Insightful

    "Relative debugging" seems to be what people have always been doing. Dump some state and comapre it to an expected state. Most frameworks for regression tests do something like that.

    The best debugging method is to have a fast build environment so that you can add one printf, rebuild, reproduce the bug, move the printf to an even better place, rebuild and reproduce, etc. The more you rely on your tools to do the work for you, the less you understand the code and the less you understand the code, the more bugs you will make in the future.

    There are no shortcuts to good code.

  17. The use of formal methods? by rahard · · Score: 1
    Would the use of formal methods eliminate(or perhaps lessen) the use of debugging? Is there anybody doing real development with formal methods?

    See Formal Methods Virtual Library for more info on Formal Methods.

    My guess, "real" programmers still use print statements.

    ... now, i'm trying to printf my Gmail account with mails! ...
    -- br

    1. Re:The use of formal methods? by Detritus · · Score: 1

      If you assume that the requirements are correct and that there are no bugs in the compiler, libraries and hardware.

      --
      Mea navis aericumbens anguillis abundat
    2. Re:The use of formal methods? by mattgreen · · Score: 1

      What tripe.

      Ah yes, those damn errors in hardware are surely remedied by printf! Plus, there's tons of buggy hardware floating around that invalidates formal methods! And whose blasted compiler writers sure aren't very good, we might as well write our own compiler! Who needs mathematical proofs of correctness when we can have printf's strewn everywhere? And I'm sure its completely impossible to use BOTH formal methods and printf's!

  18. Re: Old news by David+Byers · · Score: 4, Interesting

    Back in 1987 the FORTRAN compiler i used generated code that prited the source-code location of all failures, and that feature was old news even then.

    Besides, nontrivial bugs don't result in stack traces or crashes. They result in infrequent, hard-to-spot, anomoalies in the output. No amount of Java stack traces will help you find them.

  19. Relative debugger checks user-supplied assertions by Anonymous Coward · · Score: 0

    This sounds like a combination of debugging and test plans. More of a evolution and not much of that.

  20. Revolutionary way of debugging what? by Rosco+P.+Coltrane · · Score: 4, Interesting

    do you know any new debugger that has a revolutionary way to help us inspect the data?

    I'm noy sure what the question is here. Any debugger will allow you to watch data. If your program is special enough that you can't use a standard debugger, you probably need to write a test suite to go with it (and well, for any reasonably sized project, you should anyway).

    That's to help you find "surface" bug, i.e. to catch things like misaligned words, wrong data types, buffer overflows ..etc...

    For deep structural problems, like when you try to code something and you have no clue how to go about it, and the end result is just not good and never going to be, the cure is usually a total rewrite, so debuggers won't help you there. That's a problem due to bad architecture of the code.

    So, I'm not sure anything else is required. FYI, when I code, I believe I have enough experience to architecture and code something relatively clean the first time, then because I've done it for many years, I sort of "instinctively" expect to find a certain amount of this or that types bugs. And usually, I can fix them without debugging because they jump at me. When they dont (and I can do it), I pull out the old "print to stdout" debugging (or LED wiggling, sound generating ... on headless embedded boards), and that's usually enough to catch a 99% of whatever bugs remained. Normal debugging techniques using debuggers, or the test suite I made for that particular piece of code, takes care of the rest. My guess is, if you need anymore than that, it's probably that you lack experience.

    --
    "A door is what a dog is perpetually on the wrong side of" - Ogden Nash
  21. living under a rock? by hak1du · · Score: 2, Informative

    Java Exceptions *were* a revolution in debugging.

    Only if you have been living under a rock. Most languages and compilers other than C and C++ have been doing that forever. Even C and C++ allowed you to get a complete backtrace and inspect the complete program state from a core file (software bloat has made more and more people turn off that feature, however).

  22. Re:.NET by Anonymous Coward · · Score: 0

    .NET has kickass debugging capabilities.

    You're kind of right, I've never seen any .NET project with serious bugs. Then again, I've never seen any serious .NET project...

  23. old technique... by hak1du · · Score: 3, Insightful

    Comparing the "state" of multiple implementations or versions of code is an old technique. You don't need a special debugger for it--you can use a regular debugger and a tiny bit of glue code. Alternatively, you can insert the debugging code using aspects (aspectj.org).

    However, like many programming techniques, most real world programmers won't know about them unless they can shell out $1000 for a tool; reading a paper or book just would be too much intellectual challenge, right?

    This news item seems to be a thinly veiled attempt to drum up business for that company.

  24. Visual software testing by Novus · · Score: 4, Informative

    On the subject of software debugging techniques, I'd like to point out visual testing, which (basically) allows you to try out method calls and fiddle with variables and examine the results (including execution history) graphically. MVT is a prototype visual testing tool for Java.

  25. Does anyone know of a good debugger debugger… by Anonymous Coward · · Score: 0

    ...to debug the user-defined assertions that I have to feed into the relative debugger.

  26. Re:.NET by gatkinso · · Score: 1

    I have. Visual Studio for one.

    --
    I am very small, utmostly microscopic.
  27. nothing new by hak1du · · Score: 4, Informative

    There has been almost nothing new in programming environments or debuggers over the last 10-20 years.

    Almost those features you see in Visual C++, Visual Studio.NET, Eclipse, NetBeans, etc. have been around in IDEs since the 1980's. Debuggers have allowed you to step forwards and backwards, see the source code, examine data structures graphically, and modify the running source code for about as long.

    If anything, current commercial IDEs and debuggers still haven't caught up to the state of the art.

    1. Re:nothing new by brondsem · · Score: 1
      If anything, current commercial IDEs and debuggers still haven't caught up to the state of the art.
      Then where is the state of the art, if not in commercial apps (or commercially-backed ones like Eclipse)?
      --
      "a quote" -me
    2. Re:nothing new by hak1du · · Score: 2, Interesting

      Then where is the state of the art, if not in commercial apps (or commercially-backed ones like Eclipse)?

      Sorry, you're right, taken literally, what I said doesn't make much sense.

      What I meant was that the currently big and commercial platforms (Windows, Macintosh, Java) are still behind what was already available commercially 10-20 years ago, although it wasn't very successful back then.

      The reason why it's successful now and wasn't back then is because programmers in industry didn't understand they needed it back then. Programmers in industry have slowly been learning: object-oriented programming, garbage collection, dynamic loading, reflection, etc. The development of popular platforms simply reflects the state of education and understanding of the great mass of programmers. But the state of the art represents what is actually available if you only know that you need it.

    3. Re:nothing new by Spy+Hunter · · Score: 1

      What debugger allows you to step backwards? Point me to it! I can't count the number of times I've wished I could step backwards a few loop iterations instead of running the whole program through again.

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
  28. cool, but not useful by hak1du · · Score: 3, Insightful

    That sounds cool, but it isn't all that useful in practice. Debuggers that support stepping backwards usually end up keeping a lot of state around, which limits them to fairly small, well-defined problems or modules. But the problems where an experienced programmers need a debugger are just the opposite: they involve lots of code and large amounts of data.

    Usually, it's best to avoid going back and forth through the code altogether; insert assertions and see which ones fail.

    1. Re:cool, but not useful by Halo1 · · Score: 5, Interesting
      Well, he has used the Omniscient Debugger to debug itself. In a paper published about it at the AADEBUG03 conference, the author writes
      In actual experience with the ODB, neither CPU overhead nor memory requirements have proven to be a major stumbling block. Debugging the debugger with itself is not a problem on a 110 MHz SS4 with 128 MB. On a 700 MHz iBook it's a pleasure. All bugs encountered while developing the ODB fit easily into the 500k event limit of the small machine.
      I also disagree with your assertion that all situations where experienced programmers need a debugger involve lots of code and large amounts of data. The former is most of the time true, but latter isn't necessarily.
      --
      Donate free food here
    2. Re:cool, but not useful by hak1du · · Score: 1

      I think the fact that the best test case the ODB writer could come up with was running it on itself suggests that he actually hasn't tested it on a lot of real-world software.

      I also disagree with your assertion that all situations where experienced programmers need a debugger involve lots of code and large amounts of data. The former is most of the time true, but latter isn't necessarily.

      I didn't exactly say "all situations". But tools that only work occasionally are also just not worth bothering with: it's more work to learn the tool and keep it working than just to solve the problem the old-fashioned way.

      My point is simply the following: don't expect too much from this. I have used systems with this capability for many years, and I have never found it to be more than a curiosity.

  29. Which is nice... by Kjella · · Score: 4, Interesting

    ...unless you happen to have two pieces of software, that each function excellently alone, yet dies a horrible death together, for reasons unknown.

    I've got this thing with OpenSSL, Qt and my code right now. On a one-time run, it works fine. When I put it into a program and try to loop it, it crashes on some mysterious and horrible error, sometimes on 2nd pass, sometimes 3rd, 4th pass or more.

    All I'm getting from traceback logs are some wierd memory allocation errors in different places, e.g. in Qt code that *never* crashes if I replace the OpenSSL code with dummy code, but has nothing to do with each other. Or in OpenSSL itself, which I hardly think is their fault, if it was that buggy noone would use it. And only if this is put together and looped. Each taken apart, they work perfectly.

    Kjella

    --
    Live today, because you never know what tomorrow brings
    1. Re:Which is nice... by Anonymous Coward · · Score: 0

      The reason this is happening is there is something wrong.
      You have to find out what's wrong and fix it.

    2. Re:Which is nice... by Anonymous Coward · · Score: 0

      Ok, I'm just an AC (no one you should trust), but to me it sounds like some of your variables and structs are not properly cleared before they are used.

    3. Re:Which is nice... by Meijer · · Score: 1

      In addition to the other posters' advice:

      Check whether you have any slot that has a return type different to "void". I don't know for the current version of Qt, but in older version this was not checked and could cause awful corruption of the stack frame.

    4. Re:Which is nice... by iabervon · · Score: 2, Interesting

      Try running it through valgrind. This has the advantage that you'll get errors on many kinds of bad accesses when they occur, rather than just when the program relies on something that got messed up. Note, however, that OpenSSL as distributed xors uninitialized memory into the random pool, which means that valgrind (not knowing that the outcome is intended to be unpredictable) complains about every use of a random number. You can stop this by defining "PURIFY" when you build OpenSSL, or removing the line that's under this define.

    5. Re:Which is nice... by Klowner · · Score: 1

      Speaking of OpenSSL, I swear that thing is haunted.. I tried doing some work with it, and had a similar problem, like it'd work until I ran a function a couple times involving RSA key encryption.. Something to do with RSA_Free something-or-other claimed to 'free' the memory associated with a key pointer, but I somehow determined it really _wasnt_ doing that...

      In other words, I don't think you're crazy ;)

    6. Re:Which is nice... by pchan- · · Score: 1

      Or in OpenSSL itself, which I hardly think is their fault, if it was that buggy noone would use it.

      you're new to openssl, right? if you know of another library that replaces it, i would love to switch to it. the reason everyone uses it is because there is no substitute.

    7. Re:Which is nice... by Pathwalker · · Score: 1

      There's always nettle.

      It's not quite as full featured as OpenSSL, but if all you need are basic crypto functions, it's small, non-buggy, and fast...

    8. Re:Which is nice... by Anonymous Coward · · Score: 0

      Why not try gnutls instead? I'm not saying it's perfect but at least it's LGPL -- a better fit with the GPL of Qt.

  30. Re:.NET by gatkinso · · Score: 2, Informative

    1) you are correct, VISUAL STUDIO has a great debugger for its products - but that isn't .NET per se. The VC++ debugger is hands down the best in the industry but...

    2) gdb will do everthing VCDB does, just not as easily (ok not even remotely as easily)

    3) there are guys/gals at my work who write very tight code under gcc - they rarely need a debugger anyway. Their debugging is almost all done at design time

    Posts like that are just going to rile up their audiance and deserve their low score. Grow up.

    Some flamebait of my own: I will try to not look down my nose at you for being a VB "programmer."

    --
    I am very small, utmostly microscopic.
  31. Polyheaded Debugger by N8F8 · · Score: 4, Funny

    The technique I've found most effective is to run many simultaneous debugging sessions in parallel. My debugger of preference is a semi-autonomous intelligent agent that seeks out defects in a random fashion. I call this type of agent a "user".

    --
    "God fights on the side with the best artillery." - Napoleon, Marshal of France - speaking truth to power
    1. Re:Polyheaded Debugger by Anonymous Coward · · Score: 1, Funny

      "My debugger of preference is a semi-autonomous intelligent agent .... a 'user'"

      You have intelligent users?

    2. Re:Polyheaded Debugger by Anonymous Coward · · Score: 0

      oh, so close to being +6 funny! You just needed a good acronym . Example: ... I call this type of agent a Universal Simulation Execution Robot - a U.S.E.R.

      You do get bonus points for your subject line, though!

  32. Less Debugging Technique, More QA Tool by yebb · · Score: 1

    It sounds like this could be used rather effectively as a QA tool. Machine 1 running version 1.23 of the software, Machine 2 running 1.24 running on the same data and should produce the same results.

    Automated regression testing etc.

  33. Blinking Lights by Detritus · · Score: 1

    For systems that don't have a console, and even for those that do, a parallel port connected to a set of LEDs can be very useful. you can run the system at full speed and monitor important events on the LEDs.

    --
    Mea navis aericumbens anguillis abundat
  34. Hummm yeah by Anonymous Coward · · Score: 0

    The problem with relative debugging is that it assumes that you have a "reference" implementation. What if you're making the reference implementation?

    I think that the people making the tool have missed the point.

  35. A better solution by Morgahastu · · Score: 2, Informative

    A better solution is to make your program generate a log of everything that happens, when an object is created, when an database connection is made etc.

    And when you launch the program in debug mode everything is printed to a log file and when it crashes or a bug occurs you can just halt everything (if it hasn't crashed) and look at the log to see what it was doing.

    Different levels of logging could be used. Say level 1 with the most basic logging (database connections, disk access, network access, etc), level 2 includes all level 1 plus network traffic, level 3 has all object creations, etc.

    ex: logEvent(3,"DBO_Connection create");

  36. Some ideas by AeiwiMaster · · Score: 5, Informative

    They might not be revolutionary, but the is a few ideas
    which can be just to reduce the number of bugs in a program.

    1) 100% unit test coverage of your programs.
    2) Statistical Debugging

    3) Valgrind

    4) The D programing Language
    with build in support for unit testing, contracts and class Invariants.

  37. YHBT YHL HAND. by Anonymous Coward · · Score: 0

    n/t

    1. Re:YHBT YHL HAND. by gatkinso · · Score: 1

      Christ you are even more idiotic than the original poster.

      HAND... bitch.

      --
      I am very small, utmostly microscopic.
    2. Re:YHBT YHL HAND. by Anonymous Coward · · Score: 0

      Yeah, you're right.

      That guy probably actually IS a VB scripting guru, there's NO possible way he's a troll, and you didn't just feed him.

      Never mind that he was exposed as a comment stealer who couldn't even create his OWN trolls, like two days ago.

      You probably ruined his day by insinuating that there is something wrong with VB.

      fool.

  38. Just another tool by kabdib · · Score: 1

    Things I have used in debugging: A debugger, when available. No debugger, when the available debuggers have been worse than the disease (MPW, augh). The venerable printf, or its equivalent. Logs of all kinds. Whole machine state that you get from a machine through a serial port (tap foot for several hours). Nano logs written to memory (to catch race conditions). Flashing LEDs. Speaker beeps. Floppy disk track seeks. An AM radio held next to the machine. A photocopy machine (to get a permanent record of a register dump from the face of a hand-held machine). Cans of coolant spray. Heat guns. Logic analyzers (yay!).

    This is just another tool, and it looks like it doesn't even work that well on the really hard problems, or even moderately complex multithreaded apps. It's more like an assert tool. Reminds me a lot of the stuff that Tandem was doing to scale availability (read Gray's Transaction Processing for a good description).

    --
    Any sufficiently advanced technology is insufficiently documented.
  39. Data logging by mrm677 · · Score: 3, Informative

    Don't trivialize the data logging approach to debugging.

    In complex, multi-threaded systems where you are debugging timing events more often than programmer logic, data logging (aka print statements) is probably the only technique that works.

    In fact, one of the first things we implement in embedded systems is a data logger that can spit out your print statements over RS232. Yes, we can single-step through code using in-circuit emulators and JTAG interfaces, however I found this rarely useful.

    1. Re:Data logging by Tim+Browse · · Score: 4, Insightful

      Of course, as many people who debug multi-threaded programs have found, using print routines to output logs can make the bug 'go away', because quite often CRT functions like printf() etc are mutex'd, which serialises code execution, and thus alters the timing, and voila, race condition begone!

      I know it's happened to me :-S

    2. Re:Data logging by mrm677 · · Score: 4, Informative

      Of course, as many people who debug multi-threaded programs have found, using print routines to output logs can make the bug 'go away', because quite often CRT functions like printf() etc are mutex'd, which serialises code execution, and thus alters the timing, and voila, race condition begone!

      Of course. A good data-logger design does not call expensive output routines in the timing sensitive threads. The routines should be low-cost and append information to some kind of shared memory block such that low-priority threads occasionally format and spit them out to your output device.

    3. Re:Data logging by Anonymous Coward · · Score: 0

      But then, you have buffering problems, as your high-priority time sensitive threads generate log information faster than your low-priority task can spit it out the serial port, and you drop log messages. Also, the output is no longer synchronous with what is happening in the rest of the system, which can be misleading.

      There are problems where an ICE is invaluable; they're non-intrusive, real-time, and can monitor low-level aspects of code (like bad pointers overwriting a known memory area) that printf() simply doesn't do.

      There's no one-size-fits-all solution to the problem. Use any of the tools at your disposal when it suits, rather than getting hung up on an ideological preference for the One True Technique of Debugging.

    4. Re:Data logging by Jeremi · · Score: 1
      using print routines to output logs can [...] alter the timing, and voila, race condition begone!


      Now that's what I call a debugging technique! Just be sure to include a comment next to the printf() statement explaining that the printf() call is necessary for correct behaviour of the program, and should not be removed.... :^)

      --


      I don't care if it's 90,000 hectares. That lake was not my doing.
    5. Re:Data logging by pclminion · · Score: 1
      [...] append information to some kind of shared memory block [...]

      Which also requires serialization and does not solve the problem whatsoever. It does, however, cause your locking to become more fine-grained leading to a smaller probability of serialization induced Heisenbug-ism.

      Do you really want to debug using a technique that only usually works, and the rest of the time simply masks the problems?

      My rule of thumb is, if you produce more than 1 synchronization bug per ten thousand lines of code, you don't understand multithreaded programming correctly, and somebody should take the samurai sword away. You'll hurt someone with that.

    6. Re:Data logging by Tim+Browse · · Score: 1

      Hey, never thought of that! :-)

      Sadly, this was on a PS2, and printf() is slooooowww on a PS2, so I couldn't really keep that in the shipping code. Oh well. In the end, I had to actually fix the bug. Bloody deferred rendering, grrr, etc.

  40. Debugging is much, much nicer... by Anonymovs+Coward · · Score: 4, Informative

    in a lot of higher-level languages, eg functional languages like lisp, haskell and ocaml. But not only debugging: in these languages you tend to write code that doesn't have bugs in the first place. No need for mallocs, no buffer overflows, no memory leaks. And if you're careful to write in a functional style, no "side-effect" bugs (variables that change value when you weren't expecting them to). For a language that started out in the 1950s, it's amazing how far ahead it was and still is as a development environment. This paper is a fascinating read, especially the section on Worse is better that describes why Unix/C won. And there are other languages like the ML family and Haskell. OCaml (Objective Caml, a descendant of ML) is as concise and elegant as python, but produces native-code binaries quite competitive in speed with C, and occasionally faster. I'm wondering why anyone uses C-like languages anymore.

    1. Re:Debugging is much, much nicer... by Anonymous Coward · · Score: 1, Insightful

      I'm guessing it's because writing a device driver in LISP is not anybody's idea of a good time?

      Seriously though, not all bugs in a program have to do with allocation or buffer overflows. Besides, there are tools to help people with these problems. Most interesting bugs are beyond these types of distractions and can happen regardless of the language, or are you asserting that functional language programs always work perfectly the first time you run them?

    2. Re:Debugging is much, much nicer... by mattgreen · · Score: 1

      There goes your karma forever for implying that C is unnecessarily low-level. That is, saying nothing of implying that Unix isn't a perfect OS.

    3. Re:Debugging is much, much nicer... by jaoswald · · Score: 1

      The reason people use C-like languages is still because of "Worse is Better."

      Kernighan mentions that in the interview as well: people who can think in the very abstract way that is the true power of Lisp and functional languages are usually smart enough to be able to sweep all sorts of practical issues away very easily.

      Most people, even software people, however, can't or won't think abstractly. They need something concrete, and C is nothing if not concrete. Whatever you want to do, you can bang the C rocks together until it happens mostly the way you want, and move on. I've seen people code in C by adding and subtracting & and * operators until their code works. Yes, it makes me want to puke, but you could never explain to people like this how to code in ML, or how ML would be better.

    4. Re:Debugging is much, much nicer... by Anonymovs+Coward · · Score: 2, Informative
      are you asserting that functional language programs always work perfectly the first time you run them?

      Most of the time, yes. The reasons are, first, the strict checks it does before even agreeing to run your program, which eliminates a huge class of errors (usually emanating from typos that C will ignore), and the generally clean structure of the language that makes it easier to code what you have in mind. Consequently any errors you see when running the program are likely to be bugs in your algorithm itself, not in the implementation.

    5. Re:Debugging is much, much nicer... by tialaramex · · Score: 2, Insightful

      We use C-like languages to make things go very, very fast, immediately. Sometimes a high level language _could_ deliver this if we were willing to wait for the hardware architecture to be re-designed in its favour (which we're not), and sometimes it's just not possible because the C-like language lets you do things which cannot be proven by the machine to be safe, yet nevertheless are correct. Even scary old gets() can be quite harmless, under certain carefully controlled circumstances.

      Now, some people use C (or even more stupidly, C++) to make petty database GUIs, or configure their font preferences, and here I agree that it's worthless, and a modern high-level language would be more appropriate. But note that even when Red Hat use Python throughout their management applets, they still crash, just with a run-time error (a list is too short, or a string is found when a number was expected) instead of SIGSEGV. Some of those mistakes might even have security implications... Programmers make mistakes in any and every language.

    6. Re:Debugging is much, much nicer... by N1KO · · Score: 1

      The languages the OP was referring to (except for Lisp) are statically typed. They will find a lot of errors that can make a Python program crash. Of course, you still need error detection for things like bad input or insufficient memory... but there isn't much the compiler can do about someone entering their phone number in the file selection dialogue.

    7. Re:Debugging is much, much nicer... by N1KO · · Score: 1

      I think the problem is using too much C for software that could be written in a higher level language. Since C can bind easily with other languages it can be used in cases where speed is a big concern or someone needs to write a device driver while using a higher level language for everything else.

    8. Re:Debugging is much, much nicer... by jaoswald · · Score: 1

      I'm sorry, but writing device drivers in Lisp (non-functionally) would be a freaking dream come true. Serious Lisp environments have an assembler layer with Lispy syntax available, for starters.

      The main win is macros; you can create all sorts of syntactic and semantic sugar to abstract this Lispy assembler syntax into something that makes sense. Synchronization primitives, etc., can be abstracted into intelligent macros which can be context-aware. Plus, Lisp is there at every stage of the process, including before compilation/assembly. Need to precompute a lookup table? Write Lisp code to generate it at compile time.

  41. RetroVue by Stu+Charlton · · Score: 3, Interesting

    This is going to sound like a plug, but I have nothing to do with this company or product - I just thought it was really cool.

    When I was wandering through JavaOne last year, I ran across this booth by VisiComp, Inc. who sells this debugger called RetroVue. I think it's an interesting attempt at bridging the gap between live-breakpoint debugging and logging.

    The main issue with debugging vs. logging is that logging provides you with a history of operations that allows you to determine the execution order and state of variables at various times of the execution, something that debuggers don't actually help you with.

    RetroVue seems to instrument your Java bytecode to generate a journal file. This journal file is quite similar to a core file extended over time, by recording all operations that occurred in the program over time: every method call, every variable assignment, exception thrown, and context switch. RetroVue then allows you to play back the execution of the application.

    It includes a timeline view to jump around the various execution points of the program, as well as an ongoing call-list to show the call sequence that has occurred. It also notes every context switch that the VM makes, and detects deadlocks, thus making it a great tool for multi-threaded application debugging. You can adjust the speed of the playback if you would like to watch things unfold in front of you, or you can pause it at any time and step through the various operations. Want to find out when that variable was last assigned to? Just click a button. Want to find out when that method is called? Same.

    It's not free/cheap, but it seems quite useful.

    --
    -Stu
  42. Unit testing by Tomah4wk · · Score: 2, Insightful

    It seems to me that a lot more effort is being put into creating good unit tests to identify and prevent bugs, rather than debugging running applications. With an automated testing framework you can seriously reduce the amount of time spent on manual debugging and fixing as the bugs get identified as early as compile time, rather than run time.

    1. Re:Unit testing by llopis · · Score: 1

      Agreed, the emphasis today should be on avoiding bugs, not on fancy debuggers. I really think that using a traditional debugger should be something fairly rare nowadays. With the common usage of unit tests (especially when doing test-driven development), and type-safe languages, if you find yourself debugging a lot, it's a sign there's something really wrong in your code. I used to rely on the debugger all the time years ago, but ever since I started doing TDD and making heavy use of refactoring, I've only had a couple of serious debugging sessions in the last few years.

    2. Re:Unit testing by Anonymous Coward · · Score: 1, Interesting

      Amen brother.

      Since I've gotten into test-driven development, my bug rate has dropped nearly to zero. Let me be more specific: the code that I write test-first does not fail unpredictably on its own. Sure there are bugs in the GUI, in integration of modules, in understanding specifications... but those bugs were already there before, TDD basically eliminates one class of bugs.

      And when I get a bug report related to one of the above, I figure out how to write a test for it (GUI's are the toughest, but I've got WWW::Mechanize and HttpUnit for web GUIs).

      I haven't used a debugger OR a debugging printf statement in the last couple of years.

      If you haven't tried test-driven development, DO IT NOW! Your code becomes MUCH simpler and well-factored, and you get nearly 100% test coverage, and nearly 0% buggy code. Of course you have to be a decent programmer, and you have to know when to test edge cases and so forth, but it helps me tremendously.

  43. Print statements good, debuggers good by crmartin · · Score: 3, Interesting

    thinking is better.

    1. Re:Print statements good, debuggers good by oogoody · · Score: 1

      To think about something you need data.
      If a failure happens after 2 months running
      at a client site, without data there's nothing
      much to think about. Especially since they
      will have rebooted (or whatever) and are back
      to running their system.

    2. Re:Print statements good, debuggers good by crmartin · · Score: 1

      Fine. Just don't think either print statements or debuggers replace thinking. I've seen way to many programmers debug for hours to find a bug that could be found in a few minutes actual thought.

  44. debugging what? by moviepig.com · · Score: 1
    ...variables are compared...with variables in another reference program that is known to be correct.

    So, this isn't for developing or implementing a new algorithm.

    However, it might be a step closer to fully automating the re-implementation of existing ones ...which is inherently a rote task to begin with.

    --
    Seeing bad movies only encourages them. Watch responsibly
  45. The best debugging by Decaff · · Score: 2, Informative

    The best debugging system I have ever used is in Smalltalk. Its possible to stop code at any time, and then data can be inspected and altered, new classes coded and methods re-compiled without interrupting execution. When changes have been made code can be re-started or resumed.

    Features like exception handling with full stack trace in Java are great, but nothing beats the Smalltalk system of suspending execution and keeping the application 'alive', so it can be modified, inspected and resumed, when an error occurs.

    1. Re:The best debugging by noda132 · · Score: 1

      Features like exception handling with full stack trace in Java are great, but nothing beats the Smalltalk system of suspending execution and keeping the application 'alive', so it can be modified, inspected and resumed, when an error occurs.

      GDB does this. gdb --pid=[running process].

    2. Re:The best debugging by koali · · Score: 1

      Eclipse (and I guess other IDEs do as well) supports hot-code swap with JDK1.4. Never used it much myself, though...

    3. Re:The best debugging by tommck · · Score: 1

      So, you mean the same functionality that exists in Visual Studio 6 & VS.NET ??

      --
      ---- It puts the lotion on its skin or else it gets the hose again. It does this whenever it's told.
    4. Re:The best debugging by scode · · Score: 1

      I would be willing to bet a considerable amount of money that you have never used Smalltalk - based on the above statement.

      Smalltalk is lightyears ahead of "gdb --pid=[running process]". With Smalltalk you can develop and bugfix your application *while it is running* and experience the results immediately.

      For example, I did considerable work on an IRC bot developed in VisualWorks, while the bot was connected to the IRC server. There was almost never any need to restart anything. Changes I made were immediately available. The only reason to re-connect was if something was changed that affected the connetion/login procedure - for obvious reasons.

      In a real crunch you can debug and alter a production system with zero downtime and no restarts. There is no stop/edit/compile/run cycle. If I recall correctly someone posted on comp.lang.smalltalk a while back describing such a situation...

      --
      / Peter Schuller
      --
      peter.schuller@infidyne.com
      http://www.scode.org
    5. Re:The best debugging by Earlybird · · Score: 1
      The best live modification system I have seen was Supercede -- from Paul Allen's company Asymetrix -- later acquired by Instantiations and then going the way of the dodo. (Instantiations is now an Eclipse follower, having retired their JOVE product.)

      Microsoft Visual Studio's C++ debugger supports a limited form of live modification. In practice, it falls down pretty quickly; many kinds of changes require a full build and restart. It is so awkwardly implemented that it is, in my experience, rarely worth the effort to use it.

      As of 1.4.2, Java supports live modification, or "HotSwap" as I believe they call it, as a generic JVM feature. Eclipse's interactive debugger supports this feature, as does other IDEs.

      While Java's support seems much more lenient towards code changes than MSVC++, Java can only hot-swap code at the method/class level; if you modify something inside a loop while the loop is running, when you tell your debugger to continue execution, the JVM will replace the entire method and then run it from the beginning.

  46. Valgrind, the ultimate debugging tool by bluefoxlucid · · Score: 2, Informative

    Memory leaks and such are easily tracked with valgrind, although for basic logic errors you want to use the printf() and gdb methods.

    Valgrind is http://valgrind.kde.org and requires that you turn off all pax protections for the binary you wish to debug.

  47. the problem with print statements... by Anonymous Coward · · Score: 2, Insightful

    ...is that they don't help in time-dependent situations.
    For example, a program in C that uses lots of signals and semaphores could perform differently when print statements are added. This is because print statements take a (relatively) long time to execute. Print statements can affect the bug their supposed to be monitoring.
    I had a situation very much like this. One process would fork and exec another, and they would send signals to each other to communicate. But there were a few small bugs that caused one of the processes to occationally miss a signal. When I added the print statements, it slowed the process down enough that it caught the signal. The only way i was able to successfully debug it was with a line-by-line trace with pencil and paper. I don't know if ddd would have helped (but I didn't know about it at the time).

    1. Re:the problem with print statements... by slickwillie · · Score: 2, Informative

      Same problem for real-time embedded software. Print statements take a relative eternity, assuming you even have someplace to print to. "Printing" to a memory buffer can help if you bypass the formatting.

  48. How about single step *backwards* by Beatlebum · · Score: 1

    This would be pretty difficult to implement efficiently since a single instruction has the potential to make massive state changes, however, even a limited implementation would be extremely useful and would provide an alternative to restarting the application.

  49. Rewind by jarran · · Score: 3, Interesting

    O'Caml has a replay debugger. You can run your program in the debugger until it crashes, then step backwards through the code to see what was happening before it crashed.

    Very handy, IMHO, although the O'Caml debugger sucks in other ways. (E.g. no watch conditions.)

  50. Inspector and Valgrind by Bluelive · · Score: 1

    I wrote a little jar that spings up an awt window filled with all the information about fileds and values about an java object, allows to browse to the fields and such, really handy when you need to debug something related to a datastructure. That combined with exceptions and println, i never use a debugger in java. For C, valgrind has revolutionied debugging.

  51. Better emphasis by Futurepower(R) · · Score: 2, Insightful

    Often something goes wrong with no runtime error. Those bugs are often really, really difficult to find.

    1. Re:Better emphasis by aled · · Score: 1

      Sometimes something goes wrong at random times in conditions that we are unable to reproduce, without any kind of runtime error nor message, and without remote access to the machine. Oh and the user is so fuzzy that is no help of course. Those are the truly hard to find bugs.

      --

      "I think this line is mostly filler"
    2. Re:Better emphasis by zuzulo · · Score: 3, Interesting

      Ah, you refer to the notorious heisenbug.

      This class of bugs is significantly less painful than the little known 'shrodinbug' which is reported by testers and/or users, and cannot be reproduced in the prescence of a qualified observer or logged in any usable way.

      The question is whether there is a 'planck constant' associated with debugging any sufficiently complex algorithmic function that constrains the ability of the coder to localize the bug while specifing its effects.

      A question for the theorists among us, no doubt.

      Interestingly, several theoretical frameworks do exist to describe the heisenbug and shrodinbug but unfortunately none have yet been verified through experiment, and it is not clear that the tools currently exist to allow us to do so.

      --
      "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety."
    3. Re:Better emphasis by aled · · Score: 1

      Interesting. Can you share a definition of both cases? I meant to include the symptons of 'shrodinbug' but my wording wasn't good.
      Anyway these bugs are surely caused by the little dwarfs inside the CPU that are inconstant in their job.

      --

      "I think this line is mostly filler"
  52. I'm surprised. by /dev/trash · · Score: 1

    21 comments, and no one has mentioned that using eXtreme Programming, there would be no need for a debugger.

    1. Re:I'm surprised. by oogoody · · Score: 1

      Because nobody would be stupid enough
      to say there are no bugs in a system.

  53. *Bzzzt* by bmac · · Score: 3, Insightful

    Nope, looks like marketroid hype to me. Answer me this: what is the point of comparing two separate identical runs of a computer, except in the case of testing platform equivalence, in which case the output of a test set can simply be diff'd.

    The key to their idea is that The user first formulates a set of assertions about key data structures, which equals traditional techniques. The reason such traditional techniques have failed and continue to fail is that those assertions are always an order of magnitude simpler than the code itself. These people forget that a program *is* a set of assumptions. Dumbing it down to "x must be > y" doesn't help with the complex flow of information.

    Peace & Blessings,
    bmac

  54. It's all relative by Anonymous Coward · · Score: 0

    And here I thought relative bebugging was something you did before you went out on a date in West Virginia

  55. Automated Debugging by Anonymous Coward · · Score: 0

    Also worth a look is AskIgor at http://www.askigor.org/

    More about Delta Debugging at http://www.st.cs.uni-sb.de/dd/

  56. don't debug by mkcmkc · · Score: 5, Insightful
    • The best programmer I've met once told me that once you've dropped into the debugger, you've lost, which over time I've found to be quite true. The best debugging practice is to learn how not to use a debugger. (e.g., Are you using threads when they're not absolutely required? Say hello to debugging hell...)
    • When you must debug, print statements cover 97% of the cases perfectly. They allow you to formulate a hypothesis and test it experimentally as efficiently as possible.
    • Differential debugging is a nifty idea, but most of the time it'd be better to just use it with your print statements as above (e.g., print to logs and then diff them). For the one time per year (or five or ten years?) that having a true differential debugger might pay off, it's probably a loss anyway because of the cost and learning curve of the tool. (I thought about adding this to SUBTERFUGUE, but realized that no one would likely ever productively use this feature.)
    • If you need another reason to avoid this tool in particular, these guys have a (software) patent on it. Blech!
    --Mike
    --
    "Not an actor, but he plays one on TV."
    1. Re:don't debug by S3D · · Score: 2, Informative

      It's not always possible not to debug. Ever tryied programming multiagents systems ? The behavior of the system unpredictable (heh emergence), and it's quite often just plain impossible to tell why the system behave this or that way without debugger. Which rule or combination of rules exactly causing that specific situation...Print not help much if you have 1000 agents, and each have a lot of data. Only good old breakpoints help :)

    2. Re:don't debug by Anonymous Coward · · Score: 0

      im surprised by the number of people on /. who express this opinion. printf'ing is a poor substitute for real logging mechanisms, but i use both, _and_ i use a debugger.
      why throw away useful tools?
      before i ever publish code to other users i always step through my code using a debugger -- not to track down bugs -- but to verify the code works the way i thought it did.
      maybe no substitute for unit tests but its a grand way to check your assumptions about your code.

    3. Re:don't debug by William+Tanksley · · Score: 1

      I agree with all your points, but I'd like to add that automatically running test drivers are better than print statements in a few ways:

      1. They provide regression testing for free -- no need to ask a later programmer to figure out what your print statements mean.
      2. They document the interfaces of your program.
      3. They encourage loose coupling between modules.
      4. They can't possibly affect the execution of your production code (since they're not executed in the normal line of operation).

      I'm not saying that they're always better than print statements or a debugger, but I do find the advantages compelling over print statements in all recent cases, and over debuggers when the problem doesn't involve legacy code. Debuggers still make a great learning tool, but once I understand the problem I try to reproduce it in a test.

      -Billy

    4. Re:don't debug by iabervon · · Score: 1

      I think debuggers work very well as a hint mechanism. If you have a large program, and it sometimes suddenly breaks, it's useful to know exactly where it's breaking, and give you the stack trace. Sure, that's probably not where the bug is (although it might be, if you've got a typo involving negation), but it gives you a lot more information about the nature of the issue than "It doesn't work."

      Debuggers like valgrind can also be valuable for situations where something always works on your system, but may not work elsewhere, or may not work in situations you haven't tried. For example, if you're writing a library and testing it, chances are that some functions will be run only when the stack have never been deeper than it is when the function is run, which means that uninitialized variables will all be 0. If your code depends on this, you won't know until you start getting frustrated email from users.

    5. Re:don't debug by mkcmkc · · Score: 1

      I agree--regression tests are a great method to help avoid debugging. Not so useful once you have a bug report, but very useful to avoid getting them in the first place.
      Mike

      --
      "Not an actor, but he plays one on TV."
    6. Re:don't debug by mkcmkc · · Score: 1

      If you just want a stack trace, there's a nifty utility catchsegv that probably already exists on your system. (I only recently discovered it.)

      Mike

      --
      "Not an actor, but he plays one on TV."
    7. Re:don't debug by SpinyNorman · · Score: 1

      ># The best programmer I've met once told me that once you've dropped into the debugger, you've lost, which over time I've found to be quite true. The best debugging practice is to learn how not to use a debugger. (e.g., Are you using threads when they're not absolutely required? Say hello to debugging hell...)

      Ain't that the truth!

      As a 20+ year veteran programmer (soldered together my own 1Mz Z-80 - NASCOM-1 - when it bacame available - -in 1978, beginning of personal computer ownership possibility UK - ow gawm am I drunk - tha t I camn agfree!!!

      I *now* submit horribly arrogant patches to source conteol (mutli thread, sdynamis datsa struct, sync primatives - mutexes etc, and I *KNOW& that shit is gonna work ! :-), the young graduate fiucks willl take *weeks* to get the samem shitb as took m e 4hrs to submit (untested) that works.

      Yes, I'm drunk. amd I'mm worths 100x those newbe cosksukierss.

      hahhahhah

    8. Re:don't debug by William+Tanksley · · Score: 1

      Regression tests are also useful _with_ a bug report -- they're a formal reproduction of the reported bug, and once you narrow down the cause they're also a proof of the accuracy of your judgement.

      Actually, though, I use them mainly as what I call progression tests. Whenever I think of a feature or design point, I try to express it as a simple test. Then I add to my software code to pass that test. Tests don't hinder my work anymore; they help it along. Rather than the phycological disappointment of doing _additional_ work writing tests only to have my already-written software proven incomplete, I get the psychological reward of having my already written tests tell me when my work is done.

      My point: regression tests help on many parts of the software life-cycle, if you use 'em.

      -Billy

  57. Relative debugging? by some+guy+I+know · · Score: 2, Funny
    To use relative debugging ...
    I don't see how relative debugging can work at all.
    I mean, most of my relatives don't know anything about computers, much less debugging.
    --
    Those who sacrifice security to condemn liberty deserve to repeat history or something. - Benjamin Santayana
    1. Re:Relative debugging? by E_elven · · Score: 1

      I believe you severely misunderstood the term 'relative debugging'.

      In actuality, its purpose is to find out why your relatives know nothing of computers and correct the problem so THEY DON'T ALWAYS CALL YOU AT GODDAMN SIX-O'CLOCK SUNDAY MORNING TO 'TURN OFF THIS VIRUS ON HERE THAT I DON'T KNOW HOW IT COULD HAVE BEEN IN THAT EMAIL FROM FRANK THAT SAID 'YOU WANT TO SEE THIS!1!!11!''

      ---
      Sometimes moral relativism is a nice concept. Shame it doesn't really translate from other cultures.

      --
      Marxist evolution is just N generations away!
  58. Umm... huh? by tommck · · Score: 1


    What?

    --
    ---- It puts the lotion on its skin or else it gets the hose again. It does this whenever it's told.
    1. Re:Umm... huh? by /dev/trash · · Score: 1

      Isn't the whole cliam to fame from the XP crowd is that it's so awesome that it eliminates bugs?

  59. With hardware you have no choice by Alan+Cox · · Score: 5, Informative

    Its all very well talking about elegance and planning in advance until you try and deal with hardware. No amount of zen contemplation of your code is going to tell you what a debugger does about how the hardware and its documentation relate.

    The neatest debugging tricks I've seen so far are those logging all inputs and returns from the OS level. Since you can replay them you can rerun the app to an earlier point and investigate - in effect you can run it backwards from a bug to see how it got there.

    1. Re:With hardware you have no choice by brejc8 · · Score: 1

      Ofcause if you have the whole system simulated but still interacting with the hardware you can do much more fine grain tricks. Because we use an ARM simulator running on an ARM when I use I run it till it crashes and look at the instruction count. Then rerun to any point just before the crash.
      This has become a little tedious and with weird interrupt based hardware it becomes difficult to recreate exactly the same error. It would be nice to record the last x (10k?) states so you can rewind to any point before the error.

    2. Re:With hardware you have no choice by Xoro · · Score: 1

      I had this problem writing an emulator -- code worked, unit tests passed, programs crashed. The problem was that the specs were not bug-compatible with the emulated hardware.

      The solution was zen-like contemplation of assembly language logs. Grim, but my time with +Fravia paid off!

      --
      Kill, Tux, kill!
  60. How about.. by Koguma · · Score: 1

    #IFDEF DEBUG putc.. :-)

  61. MOD PARENT UP by tommck · · Score: 1

    Very insightful (hint!)...

    Totally true... I do a lot of Unit testing...
    With .Net code, I use NUnit and LOVE it.

    In C++, I always have a static method on each object I write that is called UnitTest(); This function calls the UnitTest on all objects on which it depends.

    It throws if it fails...

    That way, you just call ApplicationObject.UnitTest() and it tests the whole system. (there is an issue with some repeated tests, but who cares?)

    T

    --
    ---- It puts the lotion on its skin or else it gets the hose again. It does this whenever it's told.
    1. Re:MOD PARENT UP by Gilk180 · · Score: 1

      There is at least a small band of new monks part of that monestary.

      Last fall the final project for my compilers class was to write a pascal to p-code compiler (for a small subset of pascal, of course).

  62. Firmware! by jlseagull · · Score: 2, Interesting

    I didn't see much that addressed this, so I'm going to bring it up... firmware debugging! I always design in a serial port I can use for printf(), but when the system doesn't have much overhead and using printf() delays execution of a critical loop or changes a value in memory, the whole thing can crash.

    I ran into this when putting together a system with two micros, each of which had a 16MHz processor and 32K of onboard memory. I couldn't afford their damn emulator, so I had to think of other good ways to debug. They had to communicate regularly, and using printf() caused the program to delay at critical points, causing it to hang even though nothing else was done to the code. Even putting in a trap-check was still too big of a delay. I started using bitwise operators on 4 bits of memory. Each time I executed a bit of code that I thought would give problems, I inserted an assembly command into the C code that shifted in 4 bits with a code that corresponded to the location, and set the read line high. Then I put those 4 lines to a logic analyzer and triggered on the read line, reading the bits as the program ran. If (when) it hung, then I would know where. This had the advantage of being much faster to execute than a printf(), so I could put it in anywhere, even in the middle of getting a packet.

    Debugging firmware is a whole new bag, to be sure.

    --
    'Be always mindful, even when ditch-digging.' --D. T. Suzuki
    1. Re:Firmware! by jImbEam · · Score: 1

      I write firmware myself and I believe you should use the correct debugging method for the problem at hand. I use an IDE/Debugger most of the time, but I also use a logic analyzer and sometimes create log files and send them out over a port.

      I don't understand how people can say one method is best for every job.

      jImbEam

  63. Unit testing by Anonymous Coward · · Score: 0

    To my experience, 99% of bugs can be located quickly via a combination of tracing and unit testing. Although on rare occasions it helps to be able to hop into the debugger (.NET shop using VS .NET 2k3, btw), overusing it produces bad code.

    I've noticed that most developers use the debugger in the initial implementation phase to track down all of the possible issues in their code. This results in them writing very limitted unit tests, which is fine until a year from now when someone goes back to modify that routine. Yes, debugging is faster than unit testing, but unit testing is ultimately more beneficial to the longterm health of the product, so in my shop at least, we focus on the unit testing.

    Where I'll admit the debugger is very useful is placing conditional watches during the testing phase AFTER initial implementation. Trace logs say this reference is being set to null in very rare and somewhat arbitrary circumstances - we simply attach the debugger to the app and wait for it to notice the change in value. Even in this case, we don't insert a breakpoint into code and step line by line through when the circumstance occurs - in VS.NET at least, you can tell the debugger to simple append the stack trace, and basic information about other threads to the log when the condition occurs, so really, we're just using the debugger as a very complicated expansion to our own tracing code.

    -Steve

  64. Have a look at how debugging Works... by dirt_puppy · · Score: 1
    I think the most important features for debugging are interactivity (sure, any program is in some way, but there's a difference whether you have to do a 30 second build and rerun or if you can just interact where the error happened at any time - scripting languages can do this sometimes) and clear implementation (read: referential transparency)

    By far the neatest debugging possibilities I've seen is part of the Oz development suite... It can do things like: Lazy Display (your debugger won't get stuck long times on long lists, but you can unfold the whole list if you want), Thread Display, handling values still to be calculated, it even displays the evolution of any statement... Its a really powerful toy.

    And, no, Java did not invent stack Traces (or Exceptions). Really.

  65. Fix & Continue - Apple's ProjectBuilder by Jakob+Eriksson · · Score: 2, Interesting

    I'm surprised to see no-one has mentioned the Fix & Continue in Apple's ProjectBuilder IDE. I use it all the time, and it's saving me weeks of debugging. You really have to try it to understand how convenient it is, but here's an attempt to describe it.

    You run your program in the debugger. Let's say you try to click some button, and it doesn't do what you expected it to do. With the program still running, you change the handler code, click Fix in the debugger, and try your button again. Voila, problem solved! No need to recompile and then try to get back to the state you were in when stuff didn't work.

    Those of you who haven't used languages like LISP or Smalltalk (or Forth?) wouldn't believe how convenient it is to be able to change code run-time! I often add statements like

    if(this) printf(that);

    on the fly. Conditional breakpoints almost lose their relevancy when you can just add whatever conditional you like in the code, and put a breakpoint there. =)

    Works with many changes to the code, as long as the program counter isn't in the code block you're editing (in which case you get a warning and can retry later). Works with C/C++ and Objective-C just the same. Some things, like adding member fields to classes are not accepted, or changing the number of local variables for functions that are on the stack.

  66. Re: Old news by mindriot · · Score: 2, Interesting
    Besides, nontrivial bugs don't result in stack traces or crashes. They result in infrequent, hard-to-spot, anomoalies in the output. No amount of Java stack traces will help you find them.

    I second that. I currently have a piece of software that runs as a daemon. It silently crashes about once a week. Tell me a way of debugging it that doesn't take months, and I'll be happy. But until then, I'll have to add debugging statements and triple-check each line of code, run it again and wait another week or so. Right now I can only very vaguely tell where the crash occurs - but not what causes it. Not fun.

  67. Old method! by www.sorehands.com · · Score: 1
    This is a technique that has been used for quite a while, or at least I have, to an extent. When trying to track a bug, don't you compare the output or data at points between the broken and not broken version? When tracking a new bug, don't you try to isolate what is the same, what has changed -- and I don't mean just source code?

    This is interesting, where this automates the process, similar to when Frank and Jim introduced Bounds Checker to check for corruption of the memory chain instead of checking the memory chain multiple times.

  68. Debuggers are for pussies by javajedi · · Score: 1

    Log4j is all you need.

  69. This is an old idea... by gweihir · · Score: 1

    For example there is Design by Contract where you specify everything twice, once in code and once in conditions. These are then compared at runtime.

    There is prototyping with, e.g. a scripting lanuage, and then re-implementation in something else with offline comparison of the results. I do this all the time.

    In electronics the idea is decades old: Compare the signals in a working device with those in a non-working one. Although here the devices have to be identical. That is also the main problem I see with this relative debugging: The person doing the debugging has to know where the two instances are similar in their inner workings and where not. Without support for this from the language or programming method (e.g. Design by Contract) this is extrememly hard. With such support, there is no need for separate applications.

    My bottom line: Old ideas in new guise. And possibly worse in practice than many other methods.

    --
    Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
  70. For debugging my embedded board, nothing beats... by ivec · · Score: 1

    the status codes I display using the single led output it has.

    The think is pretty much I/O bound with several external components, so no chip simulator does the job.

    Consider yourself lucky ;)

  71. Re: Old news by AKAImBatman · · Score: 1

    I believe that the old Symbolics LISP machines also dumped a stack on error. However, they also allowed you to correct the problem and keep running the program from where it left off. But that isn't the point. The point is that when Java was introduced, most of the world was running on C/C++, which are very difficult to debug. Java popularized runtime stack traces and started a revolution in the way we debug programs. So what if it's old stuff? There hasn't been anything truly "new" in CompSci since the 1960's!

  72. So I need two running programs to debug relatively by Ricdude · · Score: 4, Insightful
    If I had a working program in the first place (to compare my buggy program with), I wouldn't need the debugger.

    Seriously, though. I've worked as a programmer for the last 15 years. Mostly, I've been fixing other people's bugs. Here's what I like to see in code that I need to fix (and generally don't see):

    1) Consistency in formatting, style, variable names, design - I don't care what style you use as long as it's consistent. I prefer my own form of Hungarian Notation, where a variable's prefix indicates its scope (global, static, etc), as well as the type. If any of that information changes, I should darn well follow through to make sure I've fixed everything that depends on them. Bring on strong type checking!

    2) No spaghetti code. Give me this:

    if ( something_bad ) {
    return failure;
    }
    good_stuff();
    return good;
    instead of this:
    if ( ! something_bad ) {
    good_stuff();
    return good;
    }
    return failure;
    It doesn't look like it matters much yet, but try adding eight more error checks to both, and see which you can track better. The "early bailout on error" model clearly surpasses the "endless nesting" model.

    3) Use of descriptive variable and procedure names. Source code is not meant to be understood by the computer. This is why we have compilers, and interpreters. Source code is meant to be understood by humans. Write your code for humans, and you'll be surprised at how much faster you can grind through code. You'll only write the code once, but when you have to debug it, you'll spend eternity sifting through line after line, wondering what the hell you meant by that overused "temp" variable (temporary value? temperature? celsius? kelvin?). If you had only taken the time to spell out, "surface_temperature_C", you'd know for sure. Vowels are good for you.

    4) Comment! Not every line. Not an impossible to maintain function header comment with dates and initials of everyone who's edited it. Don't fall for nor rely on that "self-documenting" code nonsense. Just one comment line every three to ten code lines. That's all. Give me an overview of what's supposed to happen in each logical block of code. Tell me what if conditions are checking for. A good rule of thumb is to sketch out your functions in comments first, then fill in the blanks.

    That's all I can come up with off the top of my head, but there are certainly more...

    NOTE: for the pedants who think they noticed an apparent conflict between my hungarian notation style and the "surface_temperature_C" variable: since there is no scope or type prefix on the variable, it's a local variable, and I can change it at will, knowing that it will not affect any code outside the function at hand. If it had been "m_fSurfaceTemperature_C", then I'd know it could have repercussions affecting the state of the current object. If it were "g_fSurfaceTemperature_F", then I'd know I could hose my whole program with an invalid value. And should have converted from Celsius to Fahrenheit before doing so...

    --
    How's my programming? Call 1-800-DEV-NULL
  73. Best debug technique ever by Kiryat+Malachi · · Score: 2, Interesting

    Embedded board doing solenoid control. Too lazy to read through the RS-232 output, so I programmed the controller to change the solenoid PWM to a frequency/drive that made them vibrate at the resonant frequency of the structure they were mounted to when a certain issue was encountered.

    I could be all the way across the room, and suddenly there would be this nice clear tone, as my solenoids 'sang' to alert me of trouble.

    --

    ---
    Mod me down, you fucking twits. Go ahead. I dare you.
    (I read with sigs off.)
  74. Relative debugging has been done before by Animats · · Score: 1
    I've seen this before, but don't have a reference. There's a system that uses this approach to verify ports of number-crunching code. The code is run on two machines simultaneously, with the numeric results compared at key points. When they differ, you have a porting problem.

    This is valuable for finding compiler and machine problems which affect the results of important numerical packages, like NASTRAN.

  75. Printfs, Blinkenlights! by Anonymous Coward · · Score: 0

    That is, print statements and their equivalent when
    you have no console or other device to print to.

    Assuming that the software was well designed,
    narrowing a bug by checking the values in critical
    variables is the right thing to do. Printfs do it
    just nicely.
    Your worst enemy, whatever the method used, will
    be the bugs that show themselves once in 100 runs
    of the software, not the easily reproducible ones.

  76. #include by carnivore302 · · Score: 1

    Great. Someone has reinvented assertions.

    How come this is even mentioned as slashdot?

    --
    Please login to access my lawn
  77. Re:Fix & Continue - VB6! by MrIrwin · · Score: 1
    I hate to have to mention it, but VB6 is very good at fix and and continue.....and at going back a few lines and retrying!


    This is the only reason I ever use VB6, in some types of project it is a godsend!


    Funny thing is that VB.NET does not have this level of debugging. (Yeah...I do know why before you all reply).


    Python is a language that could, and should, support such high level fix and retry debug.

    --

    And if you thought that was boring you obviously havn't read my Journal ;-)

  78. Tester vs. testee by Impy+the+Impiuos+Imp · · Score: 1

    For a long time, I've been building algorithms and testing them against a completely different algorithm to accomplish the same task. More often than not, the tester algorithm finds errors in the testee than the other way around. That's usually because the tester is a more brute force, simple implementation (that's not necessarily efficient.)

    --
    (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
  79. Re: Old news by Anonymous Coward · · Score: 0
    Besides, nontrivial bugs don't result in stack traces or crashes. They result in infrequent, hard-to-spot, anomoalies in the output.

    Ah, I see you are a C++ coder.

  80. Simplicity is more important by CondeZer0 · · Score: 3, Informative
    25 years later I still agree with Kernighan:

    The most effective debugging tool is still careful thought, coupled with
    judiciously placed print statements.

    -- Brian W. Kernighan, in the paper Unix for Beginners (1979)

    But I think the key to debugging is not the technique used for debugging, but how one wrote the code in the first place, here again God Kernighan hits the nail in the head:

    Debugging is twice as hard as writing the code in the first place. Therefore,
    if you write the code as cleverly as possible, you are, by definition, not
    smart enough to debug it.

    -- Brian W. Kernighan

    Once again, at the time of debugging, simplicity shows it's superiority to the complexity that seems to be so much in fashion this days. That is why I still prefer C to C++; rc to bash; AWK/sed to Perl; Plan 9 to Linux; Limbo to Java; 9p to NFS,...

    This is the forgotten key to software design: ...there are two ways of constructing a software design: One way is to make it
    so simple that there are obviously no deficiencies and the other way is to make
    it so complicated that there are no obvious deficiencies.

    -- C.A.R. Hoare, The 1980 ACM Turing Award Lecture

    Or put in another way:

    The cheapest, fastest, and most reliable components are those that aren't there.

    -- Gordon Bell

    Back in the topic of debugging, aside from the sacred printf, the Plan 9 debugger acid is often helpful, and now you can even use it on Linux/BSD!

    Plan 9 on Unix

    Also the chapter on debugging in The Practice of Programming by Brian W. Kernighan and Rob Pike is very good.

    Always remember:
    • Simplicity
    • Clarity
    • Generality
    --
    "When in doubt, use brute force." Ken Thompson
    1. Re:Simplicity is more important by mrchaotica · · Score: 1
      rather than:
      • Simplicity
      • Clarity
      • Generality

      It should be:
      1. Simplicity
      2. Clarity
      3. Generality

      This is because generality is good, but not at the expense of simplicity and clarity. (In other words, Simplicity and clarity are more important than generality)
      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

    2. Re:Simplicity is more important by DrSkwid · · Score: 1

      conde never did get the hang of HTML

      --
      There are places where the networks are not touching,and there are places where they are-Boeing's Lori Gunter
  81. If you have a correct reference implementation... by Slinky+Saves+the+Wor · · Score: 1

    ...why not just use that? Or use the computer to modify that to any programming language you want?

    How do you prove the correctness of the reference implementation?

    Why not just write all software with the reference implementation, and let the computer fill in the dots. Think paint by numbers brought to coding. You draw the picture, jot some of the numbers, the computer infers the rest.

    --
    I do not moderate.
  82. Contract by jefu · · Score: 1
    The best debugging technique I've ever used was based on the "Contract" notion.

    I used it in Sather and Eiffel, but the D language recently reported here has it as well.

    In Sather, every class could have class invariants which were checked every time a public method was called or returned (private methods often muck about in the innards of an object so the object may be temporarily inconsistent). Every method (function) could have pre and post conditions defined (and these had nice syntax) and these where checked on calling and returning from the methods.

    These checks could be turned on and off at compile time for every class.

    Debugging time was often cut by an order or magnitude or more just by finding the right preconditions, postconditions and class invariants.

    This did have a downside. I discovered quickly that I had to spend much more time thinking carefully about things like class invariants and pre/post conditions - but spending that time in the design phase usually paid off very well indeed.

    If Java had this kind of support it would be ever so much more useful. (And the rather archaic "assert" facility just ain't the same.) I'm not a big fan of microsoft, but if they'd added this to C# I'd probably be an enthusiastic supporter now. That they didn't (and that Sun did not build this in to Java early on) leaves me wondering if either company does in fact care much about software quality.

  83. Duel debugging language by sdxxx · · Score: 1

    The best system I've ever used for inspecting data in debugged programs is duel. Duel is a language specifically designed for inspecting data structures, and was implemented as a patch to gdb.

    I used to use and love duel--debugging with duel made so many complex things trivial to do at the command line. (Sort of the way programming with regular expressions allows you to do in a single line what otherwise would be incredibly complicated.)

    Unfortunately, the main author of Duel was an outspoken critic of the GPL and FSF. Even though duel itself was in the public domain, I think the author's animosity towards the FSF was probably largely reponsible for the fact that it never got integrated with gdb.

    For those curious, here is a paper describing duel. You can probably still find the source code somewhere on the net.

    http://research.microsoft.com/~drh/pubs/duel.pdf

  84. I actually don't mind the sales pitch... by Teppy · · Score: 1

    Assuming there's something newsworthy about it. And in this case it does look like an interesting product. However, what I *dispise* is not being told how much a product costs, and having a website plastered with "free 30 days evaluation, download now!!!"

    Do they honestly expect me to invest hours of my time learning their product, only to find out that it's $5000 a seat? (And I'm making this number up, because I can't for the life of me find it on their website, or Programmer's Paradise, or on Usenet, or anywhere else.)

  85. TestNG, Next Generation Testing by JSR+$FDED · · Score: 1

    Another innovative testing framework that was released recently is TestNG, http://beust.com/testng

    It uses Java Metadata to specify test runtime and deployment information.

  86. Message Object by yintercept · · Score: 1

    Rather than using print statements, I stuff error messages in an object. The object has option of writing the errors to a database (or flat file), emailing them to a sysadmin, calling a web resource, paging people, or printing the errors to the screen. Having a tidy error handling system attached to a program can increase customer loyality and the price you charge for the product. The database itself creates a nice little auditable history of program.

    When you give each error a unique id, then you can develop automated help systems with up to date info on common bugs. You can also create a system to escalate problems to the correct people.

    My main fears are about errors occurring in production, well beyond the debugging stage of development.

    Print statements alone depend on the end user being able to decipher what the programmer was thinking when they wrote the print statement.

  87. assert() by Poor+College+Student · · Score: 1

    I like to use assertions to debug code. Why? Under Unix, you get a nice core dump to feed back into your debugger, that shows the state of your program when it died. If you use MSVC++'s ide to run your program in debug mode, it will also stop at the assertion.

    Of course, some creative tinkering with a debugger might lead to the same result too, but I find assert() more convenient. Also, common sense tells us that a multifaceted approach to debugging code is best anyway (reading it, creating test scaffolds, asserts and/or exceptions, running it through a debugger, etc.)

  88. Reinventing the wheel for each language by Tablizer · · Score: 1

    The internal structure of a running program is more or less a RAM database. If it is going to be a database, then why not a relational database? If so, then one could use more-or-less off-the-shelf database querying and viewing tools to inspect and compare stuff as needed for debugging. At least the learning curve will be lower if they follow typical database conventions.

    It seems every language invents its own proprietary little (non-relational) database so that only that vendor can sell you tools to traverse the structures and debug them. Thus, we end up reinventing the wheel for each language. GUI systems are the same way: you need a custom browser to inspect them.

    The closest thing right now is probably MS's Common Runtime Language, which uses the same structure for multiple languages. However, CRL is not relational. Also, the "schemas" are not allowed to vary per language, as far as I know. I am not proposing sharing the same schema, only the same database interface and abilities. For each language may need a different schema.

    Opponents usually have 2 main complaints about such:

    1. Relational databases are (allegedly) too slow.

    2. They don't like relational databases, for whatever reason.

    The second one is a personal preference that nobody can do much about. Can't please everybody. As far as the first, I don't know that they have to be slow in such an environment. The current crop of Oracle Clones perhaps it not suited for the suggested niche, but there are other ways to implement them. Maybe standardization results in some speed loss initially, until economies-of-scale economics finds ways to tune them, the same way that companies are coming out with Java bytecode optimizers to make Java competative with C, speedwise.

    I have never seen theory that says relational MUST be slower than non-relational structures. Just because existing products are not tuned for a given use does not mean it is not possible.

  89. Similar to ye olde assert macro? by mike_diack · · Score: 1

    Having read the article, this "revolution" seems little different from using masses of assert macros in your code (a practice I strongly endorse).
    This seems far from being a revolutionary idea
    and makes me think....
    Errr....
    If you've got one machine working correctly which you are checking against.... then errr...
    why bother writing a second instance of the program....?
    Or have I missed the point!

    --
    Linux fan and Win32 developer
  90. Just assert; printf is not always enough. by BrittPark · · Score: 1

    I agree that this is just a fancy assert mechanism. But a lot of people are claiming that printf is the best debugger. Sometimes it't the best one can do. Other times a real debugger is the only efficient way. Many programmers that I respect, and I also, use the debugger as a sanity checker. Whenever I code up a new module and it has passed basic functionality tests I fire up my code in a debugger and do a thorough walk through. I find a good many subtle flaws this way, saving a great deal of time in the intensive testing and later QA cycles. I recommend this as a best practice to any programmer.

  91. Classical case of memory overwriting by eztarget · · Score: 1

    When your program tend to crash on random lines most of the times its because you overwrite your own memory (variables) without knowing it.

    Check:
    -strncpy not putting a ending '\0'.
    -writing more than buffer length.
    -if you pass a pointer to a fonction it must have been allocated (most of the time).
    -That all your new/malloc return good values.

  92. I rather enjoy Codeguide's..... by Dj · · Score: 1

    I rathe enjoy Codeguide's back in time debugger, because it lets you step backwards, through the statements (not the call stack).... then hot fix code and then you let it rip again. And you are always running the debugger. Lovely stuff.

    --
    "You know you want me baby!" - Crow T Robot
  93. novel debugging was implemented in Plan9...in 1994 by Anonymous Coward · · Score: 0
  94. They've got it wrong... by c0d3h4x0r · · Score: 1

    In their diagram explaining relative debugging, the "reference application" PC is the one with the blue screen!

    --
    Moderator hint: a comment is neither "Flamebait" nor "Troll" if it is true.
  95. The best debugging-Gecko. by Anonymous Coward · · Score: 0

    I agree. So when will someone port Gecko to Smalltalk? I bet that things like SVG, and other such would already be there if they had been written in Smalltalk. Throw in an Objective-C/ Smalltalk bridge and now we're talking.

  96. Microsoft Excel used this technique by elan · · Score: 3, Informative

    The code that calculated all the spreadsheet dependencies and what cells needed to be recomputed, was pretty complicated, as you might imagine.

    So they had the super-optimized version running in parallel with the dumb, calulate-every-cell-every-time engine, and then they'd compare the results.

    In certain cases, like this one, the technique is useful, but it's neither revolutionary nor new.

    -elan

  97. UPS is worth a look by jcupitt65 · · Score: 3, Interesting

    No one has mentioned UPS yet. I'm not sure you could really call it revolutionary, but it does have a few interesting features:

    • Not based on gdb, amazingly. Does C/C++/FORTRAN on linux, freebsd and solaris.
    • As your program runs you see an animated view of the machine at roughly source-code level (ie. text style, not ddd-like graphical).
    • It includes a C interpreter ... you can write scraps of C and attach them to parts of your program as it runs. You can use the C interpreter to write watches and conditional breakpoints etc.
    • It's based on the Athena widget set so it now looks incredibly ugly. OTOH, it also makes it very quick.

    Like other people here I debug mostly with printfs() logged to a file for easy searching, supplemented with valgrind, memprof and occasionally UPS. They are all tools and you need to try to pick the right one for the sort of bug you think you're facing.

  98. Ask Igor by r.jimenezz · · Score: 1

    I found Ask Igor on Slashdot some time ago and I think that is a revolutionary debugging technique (I was going to say "as well" but after reading the advert from GuardSoft, err, the article, and some posts I am not so sure that is correct ;))

    --
    The revolution will not be televised.
  99. Revolutionary? Certainly not! by Anonymous Coward · · Score: 1, Interesting
    Chip designers (and I suspect others) have been doing this sort of thing for decades.

    Often, chip architects create reference models in a high level language, typically C/C++, while the logic designers create an implementation of the same functionality using a Hardware Description Language (HDL), typically Verilog or VHDL.

    Chip verification engineers then run simulations in which data is fed into both models, and data values (internal values and/or output values) are compared at key points in the two models as the simulation progresses. The simulation is usually set up to automatically complain (WARNING/ERROR) when the two models disagree, and may or may not halt, based on the severity of the discrepancy.

    It is also typical to have the HDL model dump value change events into a file whose contents can be viewed graphically in a GUI which shows the value changes with respect to time (similar to what one might see using a digital logic analyzer on real hardware).

    Also, if I recall correctly, the Space Shuttles use triple redundancy with "voting", so that as long as at least two CPUs agree on output results, they are viewed as correct, and the odd man out is ignored.

  100. Mild self promotion by Timbo · · Score: 1

    For my final year dissertation I wrote an interactive profiler named rtprof. The idea is you have a remote machine calculating the profile of a process running on another machine in real time, all of which is visualised in three dimensions.

  101. java and jython by lexluther · · Score: 1

    While albeit not that radical, and definitely not applicable to all environments. One of the most effective methods I have used for debugging java code is by using jython I find using jython about an order of magnitude faster for writing test cases, and debugging code than Java. Furthermore, having the ability to pop open an interpreter and try methods out whilst you program is invaluable. Eclipse added a feature (jpages I think it is called) which you can write code in, but the value of python lies in the dynamic data structures, and no compile time type checking (no class casting which is what you spend a good bit of your time doing when writing java test code)

  102. Assertions == by snookerdoodle · · Score: 1

    Assertions == printf on steroids.

    Or was that crack?

    G, D, & R...

    Mark

  103. Re:So I need two running programs to debug relativ by blueAcid · · Score: 1

    On the subject of descriptive variable names, I've found that having a decent method of identifier completion has helped my programming immensely. Sometimes I start to get lazy and begin to use acronyms that will undoubtibly make no sense in a few days. But if I can just type somthing like _te to get _temperature and so on, its much easier. ctrl-n is for vim, I would imagine there are similar methods in most editors.
    -blue

  104. MOD PARENT UP by doktor-hladnjak · · Score: 1

    I thought of this too. Automated debugging really is a new technique. Of course, it's still experimental and what not, but it is different.

  105. Don't be silly. by Anonymous Coward · · Score: 0

    don't debug

    How about always debug.

    I've been writing commercial C++ code for 7 years. I pride myself on the quality and consistency of my code. The single biggest factor that's helped me to achieve this is that the very first time I run a piece of code, I'll always step through it in the debugger (the MSVC IDE) to make sure that it's doing exactly what I *intended* it to do. You get instant feedback on how well your layout worked, if you've covered all the problem areas. It also encourages you to write code that's easily debugged.

    If a function has easy to replicate data, I might even write a temporary block of code at the front of my program to pass it several different types of inputs and make sure the result is what I'm expecting. Yes, self-inflicted quality assurance.

    Even if you only find a minor mistake 25% of the time, that's still a significant improvement in reliability of your code for very little effort. When you're working on a software team (~8 programmers), it pays to fix mistakes as early as possible, before you check code in and infect the codebase with what should have been easily avoided problems.

    1. Re:Don't be silly. by elmartinos · · Score: 1

      The idea behind "don't debug' is that you try to write such a simple code, that it is possible to understand everything to its fullest with one glance. If this is possible, no debugging is necessary. Unfortunately most common programming languages (C++, Java, C#) have such a complicated syntax that this is really difficult. With scripting languages like Ruby this works really cool.

      Writing a temporary block of code in front of a program is a bad idea, because this code will be removed later on. A much better idea is to write a Unit Test, this prevents regression.

  106. Jbuilder Eclipse and co... by oliverthered · · Score: 3, Informative

    Jbuilder tells me in real time every sytax error in my code, I guess that's debugging.

    It also has good refactoring support, so no need to debug my poor hand refactoring. I guess that's kinda debugging.

    And it's very good at displaying my code in a way that allows me to find any bugs before running it, getters, setters, things I may have wanted to overload, UML diagrams etc... So I guess that's debugging.

    Debugging without even having to run the application, and wizards to perform all the monkey work so you don't gte bugs in the first place and intergrated junit testing.

    I think Eclipse has simila support.

    I'm not a very experianced java programmer, but my productivity is more than 4 times that of a friend whos been programming in java for more than 6 years. I do very little runtime debugging because my code is by and large bug free thanks to the design time and code time debugging in the IDE.

    Go download jbuilder trial or Eclipse with some sister project plugins (eclipse is a bit of a pain to use because it's still quite a recient product)

    --
    thank God the internet isn't a human right.
  107. I have found... by dutky · · Score: 3, Informative
    it is easiest if you just leave the bugs out in the first place.

    Failing that, as most of us do, the next best practice is to program defensively: anticipate where problems might occur in your code and include assertion checking and logging (yes, print statements) to illuminate those problem spots. Generally, I include debugging flags on the command line that allow me to control the level of assertion checking and logging (0=no logging, except for errors (the default), 1=log all branches, 2=log branches and variable values, 4=log everything).

    This defensive debugging strategy works quite well. First, it forces the programmer to think harder about both the algorithms they are using, and their implementation. I catch about a quarter of my programming errors just in the process of adding assertions. Second, the program will tend to abort as soon as a problem is detected, rather than running on for a couple billion instructions, dumping crap into the output file or database and then either aborting mysteriously on some marginally related condition, or, worse, completing without any reported errors! Finally, when errors are detected, the debugging can usually be done simply by inspecting the soure and following actual execution from the log file.

    All debugging comes down to one, fairly simple, idea: show me the program status at crucial points in the flow of control (generally at every branch and return). A few other tools are of some use under special circumstances: Purify, Electric Fence or Valgrind for detecting problems with dynamically allocated memory, or something like ddd for examining linked structures (though I prefer to just write a validation function for my data structures, see my AVL-tree code for an example). Defensive programming works because it answers the important question that usually forces you into using the debugger: what the hell just happened?!? Defensive programming gives you a way to examine program states without invoking an outside tool.

    The only class of bugs that doesn't succumb well to this approach is race conditions. Unfortunately, anything that changes the timing of the program (such as stepping instruction-by-instruction in a debugger, or writting log messages out to a disk file) will change the behavior of the race condition. I'd be really interested in tools or techniques that could address this class of bugs.

  108. My technique is truly revolutionary by aled · · Score: 1

    I use printf() instead of print statements.

    --

    "I think this line is mostly filler"
  109. Tarantula -- Visual bug localizing by doja · · Score: 2, Interesting
    My research at school is looking at a new method for debugging, or more specifically fault localization (finding the bugs). The method assumes the presence of a test suite where each test case can be classified as passed or failed.

    Tarantula Web Site

    The intuition of the approach is simple (this is our hypothesis): statements that are executed primarily by failed test cases are more suspicious of being faulty than those that are primarily executed by passed test cases.

    So, we take the statements executed by each test case and its pass/fail status and the source code for the progam under test as input. Statements that are executed primarily by passed test cases are colored green to denote safety; statements that are executed primarily by failed test cases are colored red to denote danger; and statements that are executed by both passed and failed are colored in a yellowish hue to denote caution.

    Example screenshot

    We use a visualization for the code called SeeSoft that represents each line of code by a line of pixels, where the length of the line of pixels is proportionate to the length of the source code. This gives a miniature view of the code -- much like if you were to print out all of the code and post it on a wall and walk away from it. This allows the developer to see the colors of many lines of code simultaneously.

    We have since extended the visualization to include an even higher-level abstraction than the SeeSoft view. This view uses TreeMaps and allows the simultaneous display of the colors of about 2 million lines of code.

    Another example screenshot with the TreeMap visualization

    So far, our experiments show that for programs with a single bug showing up in the test suite, this method successfully illuminates the fault about 90% of the time.

    Here's some papers about this work.
    Paper 1
    Paper 2

  110. In Cicuit Emulators by NortWind · · Score: 1

    Real In Circuit Emulators (ICS) were great. You could load up the symbol tables from your code, and all the code fetches (as well as all data accesses) would be stored in a hardware queue for automatic di-assembly and de-compilation. Tags from the original source were used where they matched. The great part was being able to trigger on a memory location (variable) being written, and even qualify the value written. You could say things like "run until myvar has bit 15 set" and then go backward in the execution stream to see who did it and why.
    Now with on-chip memory caches and virtual memory mapping, as well as super-fast clock speeds, it would be a lot trickier to build such things today. I don't even know if anybody is doing it commercially in the PC/Windows environment, but it still is popular for embedded projects.

  111. my two cents by ajs318 · · Score: 1

    I still use traditional debugging methods, but I'm just a lightweight programmer. I write mainly PHP, Perl and JavaScript ..... for web applications, and our own in-house stuff. I start by writing a mock-up of the most important inner bits, maybe starting with fixed parameters, and build it up from there. My code is full of commented out echo, print and alert() statements respectively. I have also been known to use things like print $foo if $diag; {and then just changing my $diag = 1; to 0; it's quicker than finding all the extraneous print statements to comment out} and even the odd warn statement in a CGI script, using tail -f on the web server's error log.

    Maybe if I was doing heavier-weight work, though, especially in compiled languages, I might need more sophisticated tools.

    --
    Je fume. Tu fumes. Nous fûmes!
  112. MOD PARENT UP by CptNerd · · Score: 1


    Every time I hear about how "unique" the Java VM is, I can't help but think about the old ucsd Pascal and it's "p-code" interpreter.

    It almost feels like being one of the old monks in the dark ages, keeping alive the memory of how things used to be...

    --
    By the taping of my glasses, something geeky this way passes
  113. Glowing Natural Keyboard by demmegod · · Score: 1

    One of these would be kinda cool, but I only use ergonomic keyboards. Has any one ever seen a glowing ergonimic keyboard?

    1. Re:Glowing Natural Keyboard by demmegod · · Score: 1

      Oops.. wrong window. Sorry.

  114. Omniscient debugging for Linux programs by mec · · Score: 1

    I wrote an omniscient debugger for Linux programs in 1995 (I wish I had thought of a cool name like 'omniscient', though).

    The debugger works by capturing all the system calls in the inferior program. When you think about it, most of the instructions in the inferior program are deterministic -- given the same machine state on input, they produce the same machine state on output. These instructions can be replayed with no overhead.

    The major interesting instructions are system calls. A system call will produce different changes in inferior state each time it is run. (Think of the results of gettimeofday(), or read()). So I wrote something like strace that hooked all the system calls and recorded all of their memory effects and return values.

    So with a copy of the original program and a copy of the log file, one could replay the execution of the inferior program, on the same machine or on a *different* machine. Trace on the end-user's machine; mail the files to the developer; replay on the developer's machine!

    The next step is to connect a debugger to the replay'ing program. I did this by running a debugger (gdb) in another sandbox where I filtered all of its system calls. When gdb calls ptrace(), I feed it appropriate values from the replay-inferior process. So gdb (or any other debugger) thinks it is interacting with the replay'ing process, without any changes needed to gdb.
    Things I never implemented: ELF shared libraries; signals; shared memory; non-deterministic instructions such as the cpu-id instruction and hardware random number generator.

    At this point the project is pretty defunct, but I may retun to it someday. It might have some value as 'prior art' in case anyone tries to patent this technique. The code is available at mec-0.3.tar.gz.

  115. Welcome to the 70s! by voodoo1man · · Score: 2, Informative
    Lisp and Smalltalk certainly had these capabilities in the 70s. Some of the Smalltalk stuff is described in a book I highly recommend, G. Kranser's (ed.) Smalltalk-80: Bits of History, Words of Advice. Interlisp had advanced stack-handling facilities for it's spaghetti-stack VM, and hooks into all the error handling facilities, dating back to the late 60s, when it was known as BBN-Lisp. Of course, development was also entirely structure-oriented, so instead of line numbers with your stack trace, you'd get the source code, right then and there (Smalltalk is the same way, but you get the text - in Interlisp, all the code was actual data structures).

    One thing that shouldn't be missed is that object-oriented exception handling, as popularized by Java, was invented in MIT Lisp Machine Lisp. This simplified and regularized error handling tremendously, to the point where today hooks into the deepest aspects of a typical implementation of Common Lisps' debugger are reduced to about a page's worth of code to deal with stack handling. I did a little work on the CLISP backend for SLIME, and this really surprised me.

    --

    In the great CONS chain of life, you can either be the CAR or be in the CDR.

  116. Debugging by Alex+Belits · · Score: 1

    Debuggers should be used for three purposes:

    1. Reverse engineering.

    2. Crash analysis.

    3. Teaching aid.

    If a programmer needs a debugger (as opposed to debugging output) to find his own mistakes while he is writing the code, he practices an unsafe programming technique. Debugger can only show a huge amount of information about what happened in a particular test scenario, so there is no hope that it will cover even a noticeably large percentage of problems, leave alone make sure that program is working as intended, or is robust. Also each and every timing-dependent problem and race condition will be missed or distorted, and the programmer will never be able to see it. Security bugs (that usually depend on the input that can not be thought of by a developer for the test cases) will be all missed. too.

    Debugging output allows a programmer to see the program's work dynsmically, cover a huge amount of cases, and allows semi-automated analysis (even if it's just regexp search in vi/emacs), profilers may help with efficiency issues (though not all of them because, again, they rely on a small amount of test cases), however jumping between little boxes with values, or endlessly stepping through the lines and functions at most can produce a program coerced into giving the right answer by applying a completely wrong (and usually dangerous) algorithm.

    --
    Contrary to the popular belief, there indeed is no God.
  117. Re:So I need two running programs to debug relativ by Janek+Kozicki · · Score: 1

    could you elaborate a little on meaning of "m_f" and "g_f" and for what those are acronyms? I bet that "g" stands for global, but I have no idea what "m" or "f" should mean... What other variable types (apart from m_f and g_f) do you have?

    honestly I just want to learn from you how should I distiguish my own variables (local/global .. what more?)

    --
    #
    #\ @ ? Colonize Mars
    #
  118. Re:Print statements work fine for IBM by swordfishBob · · Score: 1

    Print statements allow something that many other debugging tools don't - they can be run by a client on their own systems. The larger a system, the more potential for problems to hide for years until the right data/request exposes it.

    The prints don't even have to be "all on" or "all off". You should see the amount of information coming out of some IBM software when you set the highest possible trace levels though - it's often enough that the vendor can determine the cause of an obscure problem without having the entire customer data set.

    Not saying they don't use other tools, and I don't work for IBM.

    --
    -- All your bass are below two Hz
  119. My fancy printf debugging library by danielwebb · · Score: 1

    I have written a flexible printf debugging package, it can be found here. It is fully documented, but I have only used it myself. I figured I might as well release it since it is on-topic for this Slashdot post. Consider it an alpha release, because the API may change and I haven't done any testing outside my own systems.

  120. Job Security! by Anonymous Coward · · Score: 0

    if someone else can fix it, you are expendable. obfuscated code means you keep your job so nobody else is debugging your code, taking your money. this "maintainable code" movement is an evil idea by managers to make it possible to hire good programmers for a little while then replace them with low paid code-monkeys once the hard work is done. way to screw yourself

    1. Re:Job Security! by Anonymous Coward · · Score: 0
      Ah, the 8th Century Glass Maker's Guild argument. I haven't heard that since...well...the 8th Century.

      Actually, that's not true. Check out Chris Rock's diatribe on doctor's. The jist of it is, doctor's are not financially incented to cure their patients. Instead they'd rather have them on some medicine where they have to keep paying the doctor for the rest of their lives.

      Call me an idealist, I don't believe this is true, and I believe that Doctors hold themselves to a higher standard that that. As should we.

  121. Re:So I need two running programs to debug relativ by johannesg · · Score: 1
    m = member, i.e. it is declared in a class definition. f = float, i.e. it is something of type float. I have never met the poster but I'm sure I could read his code ;-)

    As for the original poster, I can only say this: "amen, brother".

  122. Time for Valgrind! by Anonymous Coward · · Score: 0

    Run your code under valgrind (http://valgrind.kde.org/) and watch for memory errors. If it reports an error, go fix it! If it doesn't then you can be reasonably sure memory errors are not your problem.

  123. Self Certifying Code by Anonymous Coward · · Score: 1, Informative

    as described at http://www-2.cs.cmu.edu/~necula/papers.html holds a lot of promise, especially if the proof annotations were saved in the executable along with symbol table information.

  124. Re:So I need two running programs to debug relativ by Ricdude · · Score: 1

    excellent guesses. exactly right.

    Executive Summary of my personal hungarian style:

    Variables are (scope)(type)(name)(units)
    scope is: g_ for globals, s_ for file statics (affects entire file, but only the current file), s_ for class statics (affects more than current class object), m_ for class members. Local variables have no scope prefix.

    Types: b for boolean, c for character, d for double, e for enumerations, f for float, i for int, l for long, n for unsigned, o for misc object, p for pointer, r for reference, s for string, t for time, v for vectors/arrays/iterable sequences. Local variables have no type prefix. Scroll back to review the type if you need.

    Names: all_lower_case_underscore_separators for local (unimportant) variables. UseInitialCapsForEverythingElse. Acronyms are treated as a word for the purposes of capitalization and separation, e.g. IrsForm1040A.

    Units: If it is expressing a dimensioned quantity (length, volume, time, mass, etc., or combinations thereof), add units, e.g. rpm_Hz, UplinkFreq_MHz, etc. You'll never wonder whether or not that timespan measurement was in seconds or milliseconds ever again. Not for long anyway.

    That's the simple version. Try a few, and see what sticks with you. Your brain might not be wired the same way as mine. This is geared towards enforcing consistency in scope and type, which are the places where assumptions tend to be broken. e.g. m_iNumerator / m_iDenominator will truncate, m_dNumerator / m_dDenominator will not (at least in C/C++, where it's useful to know the difference).

    Enjoy.

    --
    How's my programming? Call 1-800-DEV-NULL
  125. Writing good code by gidds · · Score: 1
    If only I worked with people like you...

    Consistency is so important to find your way around code. I've spent so long being confused by different names that eventually turn out to be referring to the same thing, and one name used to refer to several different things... Yes, this matters in comments as well as identifiers.

    OTOH, I've tried a couple of standard prefixes, and come to hate them. Scope prefixes can be slightly useful; they tell you where to go to find out anything else. (Depends on the language/system.) But IME type prefixes are awkward, long-winded, and give no benefit. If you can see the variable name anywhere, then you've usually got about as much information as you need to use it. And of course encoding the type precludes you from changing it -- it only takes one or two variables which have been retyped but not renamed to put you off! But I know people feel differently about this, and I don't want to start a Holy War on what's really a minor point compared to the vast amount of really bad code being written...

    Your point 2) is I think an application of a more general principle: concentrate on success. Of course, failures must be spotted and dealt with, but the main flow of the code should always be with the successful case(s). Not only does it make cases like you describe easier to handle, it also helps you to think about what the code is really doing.

    I'd like to qualify 3) a little: the lengths of identifiers should generally be directly proportional to their scope. Globals (which are of course EVIL anyway) are doubly bad when you can't tell what they mean. But I've also seen code which is made completely unreadable by having short-term index variable with 10 or 20 characters. I'd be perfectly happy with a variable called 'i' if it was only used for a few lines, and the context made its value perfectly clear; though maybe 'cell' or 'line' or something might be even better. The knack with naming is to find the shortest name that's meaningful in the circumstances.

    And comments are similar. For goodness' sake, DON'T put comments in to explain stuff that's obvious from the code. (This very day I've been working on code with lines like:

    indent = *(bufStart + i * 8 + 4) // Set indent
    ...!) And DON'T use comments to explain bad code when you could write better code which didn't need the comments.

    Instead, write comments to explain the big picture. I'm not stupid; I can usually work out what the code is doing at a low level. What I have more trouble seeing is why it's doing that, and how it fits in with the rest of the system. And explain functions/methods/procedures from the caller's point of view. If I want to see how it works, I can; but if I'm going to be calling it, I need to know what assumptions to make, and what it can do for me.

    --

    Ceterum censeo subscriptionem esse delendam.

  126. Crazed method by Anonymous Coward · · Score: 0

    I knew a guy with Perfect pitch, who would access the PC speaker at different frequencies in different parts of his code, and then by listening to the screeching and warlbing could find bottlenecks and such.

    "Hey, there's too much B flat. My damn animation library is slowing things down again".

    Scary bastard.

  127. Fear of the debugger is caused by... by alispguru · · Score: 1

    Debuggers that suck

    Languages whose features make debuggers suck

    Most languages are designed primarily to run programs fast. Features that make debuggers useful (symbols, data structure descriptions) are not available by default, and have to be grafted on afterwards with special compiler options that can sometimes change program behavior (remember when -g in gcc would turn -O off?).

    Most Lisp implementations grew up in AI environments - there was a lot of experimental programming done on problems where it wasn't clear the task could be done at all. Also, machines were a lotslower back then - you might land in the debugger after a run of hours or days, and you really didn't want to start over from scratch if you could possibly avoid it.

    So, Lisp implementations were (and still are) designed to "get it right, then make it fast". If you land in the debugger, you can almost always examine the whole stack, modify pretty much anything, change code and data structures, and continue the program, backing up a few stack frames if necessary.

    And so, Common Lisp exceptions can be handled two different ways - handlers can run in the context where they are established (like Java and C++) or they can run in the context where the exception is created (and where a debugger/handler has the best chance of fixing things transparently). Stroustrup considered allowing this second type of error handling in C++, and rejected it because it could allow bad, non-modular coding styles, without considering the effect not having it would have on C++ debugging.

    In most other languages, debugging is evil, intrusive, and slows your code down. In Lisp, the debugger is good, always there, and an extension of your basic interaction tools.

    --

    To a Lisp hacker, XML is S-expressions in drag.
    1. Re:Fear of the debugger is caused by... by mkcmkc · · Score: 1
      I agree that debugging with a good debugger in a language like Lisp or Prolog is a lot easier than with a language like C or C++, but my thinking is mostly orthogonal to that question. I've done a fair amount of Lisp programming in the past and I mostly use Python (which you might call "Lisp in drag") these days. I find, though, that even though Python has a nice debugger, I hardly ever need to use it. For the few errors I encounter, a handful of print statements does the job just fine.

      Probably the place where debuggers are most useful to me lately is when I have to track down bug in a huge blob of poorly written, undocumented code. This is really a reverse-engineering task, and for sufficiently inscrutable code, a debugger can be a (relatively) efficient way to go.

      Mike

      --
      "Not an actor, but he plays one on TV."
    2. Re:Fear of the debugger is caused by... by alispguru · · Score: 1

      Probably the place where debuggers are most useful to me lately is when I have to track down bug in a huge blob of poorly written, undocumented code.

      Sounds like a description of the typical AI project (possibly leaving out the "poorly written" aspect). I was going to put something in my original post about ill-specified problems being common back then, too.

      This is really a reverse-engineering task, and for sufficiently inscrutable code, a debugger can be a (relatively) efficient way to go.

      Yep. Another way to say it is that the program itself is the most accurate specification of its own behavior. A good debugger lets you see what's happening, while it's happening, and change it in mid-flight if necessary.

      I've been doing CGI programming in both Lisp and Perl (spit) lately, and the different styles I've used are related to debugger value.

      The Perl was standard Apache receive-and-dispatch stuff. Debug printing was the only way to go. Yech.

      The Lisp stuff was based on portable AllegroServe - the web server and the logic code live together in an image that persists between web transactions, and each incoming form spins a new Lisp thread. If something goes wrong during a transaction, the thread can land in the Lisp debugger, and you can examine the entrails and fix it right there. The only odd thing you have to do is configure your testing web browser to wait a long time before timing out, so it won't close the connection and jerk the rug out from under you while you're looking around...
      --

      To a Lisp hacker, XML is S-expressions in drag.
  128. Simple! by frank_adrian314159 · · Score: 1
    Just don't write code that has bugs!

    And, if you can't do that, use your psychic powers or cast the yarrow stalks.

    And, if that doesn't work, well, there's always print statements...

    --
    That is all.
  129. Delta Debugging by Anonymous Coward · · Score: 1, Informative

    Delta Debugging (http://www.st.cs.uni-sb.de/dd/) - has been featured on Slashdot before.

    Basic idea: Run a program with input data until it crashes. Debugger will find the diff in the input data that triggered the crash and the location in the source code where the crash originated. Also works for same input and different program versions.

    It's free and they have an online demo where you can upload your program with test cases and they will show you where the bug lies. (http://www.st.cs.uni-sb.de/askigor/)

    Also works in Eclipse with automated testing using JUNIT.

  130. Exceptions-Trickle-down ideas. by Anonymous Coward · · Score: 0

    "How much has been forgotten. "

    More like, How much did most even know?

    Anyway what your describing is basically the same thing that happens with hardware. Trickle-down of technology. How much of what's in our present-day hardware was originally in mainframes, and workstations? Well now we're seeing the same with software, and like the above it has to be simplified. Remember SGML? Remember the Lisp machines were dedicated in order to get usable performance out of the language, at that time. Moore's law now makes the past possible.

  131. A better idea by Doug+Neal · · Score: 1

    Something I'd quite like to see is an expansion of the varible watch feature of debuggers. What would be really useful is a set of widgets that you could quickly drag and drop to form a custom "view" of the internals of your program whatever way you liked. Of course it would have to be slightly intelligent and look at how you organised your data structures etc.

    Another useful thing would be, a debugger which steps through your program and memorises its state at every point, and lets you backtrack to see where it was a few lines ago. The two of these combined would be the most powerful debugger ever, I think.

  132. Re:So I need two running programs to debug relativ by Jeremi · · Score: 1
    The "early bailout on error" model clearly surpasses the "endless nesting" model.


    I disagree. Early bailouts make it too easy to accidentally skip necessary cleanup/rollback steps, and end up with leaked memory / file descriptors / etc. (Yes, smart pointers, I know... but not all APIs support them) "Single entry point / Single exit point" is a standard principle of structured design, and not without reason.

    --


    I don't care if it's 90,000 hectares. That lake was not my doing.
  133. I prefer a debug print func by Hecatonchires · · Score: 2, Interesting

    debug_print(int debug_level, str debug_msg)

    Somewhere, you have a list of what the various debug levels are. It's useful to do something like
    0 = off
    1 = entering major functions
    2 = less major functions
    3 = specific breakpoints
    4 = loop variables

    The debug print checks a constant global variable, or if more work is required, gets set by a command line. Means you dont need to remove the statements for the final compile.

    --

    Yay me!

  134. Options other than valgrind by Anonymous Coward · · Score: 0
    Purify: Works great, get the trial and see what it's worth. It will probably find a lot more bugs than you thought you had.... IIRC it's about $1500 or a bit less per seat, but that's cheap when you use it to empirically find a memory problem that would otherwise have haunted your program for months. How many times have you spent days looking for bugs that turned out to be memory-related? Those hours probably cost your employer at least $100 each when all the overhead for you is considered: salary, taxes, hardware for you to work on, support for the hardware you work on, software for you to use on the hardware you work on, power for the hardware you work on, lights, heat and air-conditioning for the air you breathe, indoor plumbing...

    On Solaris, if you're using Sun's compiler/debugger, load up your program in dbx and before you enter the 'check -all' command, then run your program just like before.

    Also on Solaris, you can use the "watchmalloc" library: set the LD_PRELOAD (or LD_PRELOAD_32/LD_PRELOAD_64) envval to "libwatchmalloc.so" and see what happens (see the man page for watchmalloc for details.

  135. String 8 simple tasks linearly by Anonymous Coward · · Score: 0
    Write some code that strings 8 really simple tasks together linearly. But they could all fail - file not there, disk full, CD not in drive, etc. Write it once using early-bail and once using 8 levels of nesting.

    Then go back and try changing the error conditions and their handling for tasks 3 and 6 in both versions of your code.

    Which one's much easier? And therefor more maintainable and much less error-prone for the life of the code?

    While you might disagree with me, if you worked for me your code would fail in a code review if you used the single-entry/single-return for such code. (Of course, if you worked for me you wouldn't be able to go 8 nesting levels deep because I hold to code standards the limit line length to 72 chars for a lot of reasons - but the real reason is to prevent anyone from being able to go too deep in nesting code. It's really hard to write readable code that nests 11 levels deep when you have to use 4-space indentation and are limited to 72 characters per line. And if it ain't readable, it fails review....)

    1. Re:String 8 simple tasks linearly by mrchaotica · · Score: 1

      There's a problem with your "72 characters per line" idea, in that it encourages short variable names - perhaps you should say instead say "72 characters per line, but identifiers count for n characters each"

      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

    2. Re:String 8 simple tasks linearly by Anonymous Coward · · Score: 0
      There's a problem with your "72 characters per line" idea, in that it encourages short variable names - perhaps you should say instead say "72 characters per line, but identifiers count for n characters each"

      I've thought about that. When I get a reason to redo the standards I'll probably up the line limit - all the way to 80... (which is actually a pretty hard limit because someone might have to edit the file in vi on a console for some reason... )

    3. Re:String 8 simple tasks linearly by Jeremi · · Score: 1

      vi handles arbitarily long line lengths without any trouble.

      --


      I don't care if it's 90,000 hectares. That lake was not my doing.
    4. Re:String 8 simple tasks linearly by dododge · · Score: 1

      I think the point is that the console is likely to be 80 columns or less. And code that wraps off the end of the line is a pain to edit.

      Note also that some versions of vi (actual vi, not the lookalikes on steroids that Linux usually ships with) can't handle really wide terminals.

      bash-2.05$ vi
      Terminal too wide
      :q
      bash-2.05$ stty -a | grep col
      rows = 24; columns = 168; ypixels = 244; xpixels = 1027;
      bash-2.05$ uname -sr
      SunOS 5.9
  136. Distributed, multi-threaded, timing-related by Tomster · · Score: 3, Informative

    Those of you who have written distributed applications/code know what a bitch it can be to debug something when multiple processes are involved.

    Those of you who have written multi-threaded applications know what a bitch it can be to debug something when multiple threads are involved.

    Those of you who have written timing-sensitive code know what a bitch it can be to debug something that is timing-related.

    Now, put all three of those into a pot and stir it around. That's what I and a co-worker have been working on the past four days.

    We sent four or five debug versions of the code to the customer for them to run in their production test environment over the past several days with various information printed to the console. With the dials turned way up, the problem usually manifested after a few hours (as opposed to a day or more, when operating under normal conditions). Each time, we'd get back a multi-megabyte log file which we would pore over to see if we had found the root cause of the problem. (Yes, grep was our dear, dear companion -- we're taking it out for drinks as soon as we've verified the problem has been fixed.)

    The problem was caused by a specific set of conditions -- the right things happening at the right time, in the right sequence, with a particular timing. To "trap" those conditions would require running both the client and server under a tracing debugger that recorded the time and "event" (e.g. method call, assignment, exception) of everything the system did and then allowed complex queries on the data produced. E.g. "How times per minute was update() called prior to isDead() returning true, on this instance?"

    The data could perhaps be recorded using AOP. Next time we run into a scenario like this, it might be worthwhile to break out AspectJ or AspectWorkz. But analysing it will be tricky.

  137. how do I debug the reference application? by Anonymous Coward · · Score: 0

    Recursive algorithms are always confuseing.

  138. The only way to debug.. by thing2b · · Score: 1

    try {
    int linux += microsoft;
    } catch (Exception error) {
    System.out.print("Looks like I am not going home tonight");
    }

    --
    Webmaster of Infoweb
  139. Code cleanups by r6144 · · Score: 1
    When writing experimental programs during research (that is, the actual algorithm is not planned beforehand, but adjusted in a trial-and-error way), I often need to clean up the code after a lot of algorithmic changes, such as some code and data structures that I suspect should not have any effect anymore. I want to make sure that the results are exactly the same after the change, so I log the execution path in detail (needed for ordinary debugging anyway --- there is too much data for an interactive debugger), and compare the 10+MB log file before and after the change using "cmp", or eye-browsing if there are floating-point issues.

    I think this can be seen as a kind of relative debugging. It can be used during algorithmic optimization as well. Of course, a version-control program such as Subversion is important when using such techniques.

  140. What about watchpoints? by r6144 · · Score: 1

    I do not know about the best commercial tools in the 1980's. However, I didn't see many debuggers supporting watchpoints (stop when some data gets changed) before late 90s, and you didn't mention it explicitly, so I hope someone would tell me when did watchpoints become commercially available.

    1. Re:What about watchpoints? by Anonymous Coward · · Score: 0

      turbo pascal, 80s

    2. Re:What about watchpoints? by hak1du · · Score: 1

      I'm pretty sure all of the major UNIX source level C debuggers (sdb, dbx, gdb) have supported watchpoints since early on. UPS (also from the 1980's) had a complete C interpreter in it, which you could not only use for watch points, but to insert arbitrary C code. Purify let you set data breakpoints using memory management hardware since early on. The feature is somewhat hard to support in C/C++ because it is either slow or requires hardware support.

      But C is really so far behind technologically that it took it a long time to catch up. Systems like Smalltalk-80, CommonLisp, and Prolog, all commercially available in the early 1980's, not only let you set arbitrary data-dependent breakpoints, they let you change your source code while debugging and have your changes reflected in the running program. With the rise of C/C++, all that was forgotten, and people like you now think that it was all invented yesterday.

  141. Clarification by Anonymous Coward · · Score: 0

    Clarification: BWK does not use debuggers.

    OK, he has used them, and will on very rare occasions use them, but that's a far cry from the understated mentality expressed here.

    Programmers who know their code do not need debuggers. They know where the errors are because they know their code.

    Read BWK again and read him more carefully this time. And spend more time writing your own fricking code so you don't become another video arcade loser. The only programmers who finish assignments are the ones who don't need and don't use debuggers. As for anyone else - look at the deplorable state of affairs today.

    People like you are wasting our time: wasting it with shitty products, puerile attitudes, suckee lack of talent, and just generally being the worst possible definition of a visitor to Slashdot.

    Eat shit and die, but leave your office computer password on a post-it on the screen to minimise the clean-up after they tow your carcas out the door.

  142. You still need self-discipline... by r6144 · · Score: 2, Insightful
    C (and especially C++) are sufficiently good languages in the hands of those who know how to program cleanly (for example, they know why returning a pointer to a automatic variable is bad in C, and why you need to define copy constructors, or make the destructor virtual, for certain classes in C++) --- just look at the many well-written projects in C, you rarely hear the core developers screaming that the language is painful to use. A good compiler helps for giving warnings about certain constructs, but some of the more subtle types are very hard to detect by a compiler.

    In high-level languages, you usually don't have memory-allocation or buffer-overflow problems, but quite often there are other traps. In Perl, numerous gotchas are mentioned in the manual. In Python, unexperienced developers often make shallow copies of lists when deep copies are needed. In Lisp, beginners often accidentally modify quoted lists in program sources, and they may write macros that captures variables. In Haskell, hastily-written programs may leak memory because of incorrect handling of laziness. I can't quickly think of an OCaml example, but at least it is easy to get hard-to-find typing errors during compile time if you are not careful... As for Java, I bet lots of beginners write applets that locks up randomly because they are not well aware of AWT/Swing threading issues.

    All these, like memory problems in C/C++, are avoidable if the gotchas of the language is well taught and learnt --- and indeed they are mentioned on most books about the language. However if people happen to forget one of these, they will all lead to very hard-to-find bugs. So in this respect, you need self-discipline when programming with present-day languages, even high-level ones.

    A problem with functional languages is that they are quite hard to learn (which also makes them interesting if you like computer science). One have to read quite a number of CS papers if he wants to use Haskell well (otherwise he will see cryptic type errors if he tries to do anything advanced, or if he did anything wrong). C is much easier in this respect, and even C++/Perl aren't that hard --- they are just complex.

  143. Ida Pro 4.6, SoftICE, gdb and more... by acz · · Score: 2, Informative
    IDA Pro, the Interactive disassembler from datarescue is not only
    the best disassembler but also a great debugger, it can
    graph function flows, display pentium microcode, supports
    nearly every processors on the market (including your car's
    CPU.) Works nice with linux ELF binaries, etc... It is used by most antivirus researchers, crackers (who remove software protections), reverse engineers, hackers (who write exploits), etc. It runs perfect under wine without tweaking. Grab the
    demo and give it a go.


    Also under windows, SoftICE, is also an excellent debugger which lets you assemble in place and do many other neat things.

    Under linux, people have been trying to make SoftICE look-a-like debugger, such as LinICE, etc. and gdb is quite a powerful tool and is scriptable.

  144. Is that really as good as #ifdefs? by mrchaotica · · Score: 1

    If your debugging statement #ifdef'd in, it is completely removed during compile. Is your debug_print() completely optimized out?

    --

    "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

  145. Re: Old news by wannasleep · · Score: 1

    run the same daemon in 20 machines, so it will crash 3 times a day, or run 20 instances on the same machine if you can

  146. .NET by undef24 · · Score: 1

    .NET users should check out the Trace and Debug classes. They are extremely useful as trace logging can be configured via an App.Config file to log to a sql database, file, etc. ASP.NET users should also check out http://yoursite/Trace.axd to get a full stacktrace or program execution of the last few visits to your site. You will never need to reproduce a bug yourself again they the full exception is already logged.

  147. Urgh by KlausBreuer · · Score: 1

    While this seems like an interesting way to debug code you have ported between systems, I have this tendency to expand existing software. Or write new software.
    Where this is not terribly useful.

    Besides.. have you looked at the background graphics on the left. I hardly dare to admit that I know this, but it *is* VB code. Great advert. Urgh.

    --
    Free PC version of ChipWits at http://www.breueronline.de/klaus/chipwits/
  148. Assertions work great by nimblebrain · · Score: 1

    If you're working in Java, you should add assertions to your toolkit.

    Amen to that; that goes for any number of development environments that have assertions or pre/postconditions as an available construct.

    I use assertions anywhere that a violation of the condition would be a programming error, instead of a configuration or input error. Pass in null into the constructor? No! Pass in a negative number for the distance? No! Use this resource object after return_to_pool() has been called on it? Nuh uh!

    Just having assertions be a gatekeeper for "impossible" circumstances catches a lot of those very selfsame "impossibilities".

    I do a lot of concurrent programming these days, so the rules count triple. It's almost always something stupid, too, like using the ID of a constant instead of the value of the constant (in COM programming, varNull instead of Null), or forgetting to declare support for an interface. Adding assertions to other peoples' code can really track down anomalies pretty fast - someone's red/black tree algorithm had some cases where the root object (which should have no parent) got assigned, causing all sorts of subtle mayhem.

    Along with this, I would highly recommend unit testing - highly. Based on the number of failed unit tests I've had over the past year, some twenty very subtle bugs would be haunting me still. Now, at least to a much higher degree than otherwise possible, I can "prove" that my objects and algorithms work, at least as advertised.

    Unit tests also really help out when swapping out algorithms. I swapped a list for a much faster red/black tree (was doing thousands of ID lookups). Two unit tests failed - and both had to do with what happens if your object ID matches a blank ID. Easy to fix, but I wouldn't have had a clue.

    Unit test also help out when porting. I have a fairly hefty framework in Delphi. Porting that to .NET took about a week to get working - a few days for the syntax changes, a couple extra to get green lights on the unit tests again.

    Unit tests are, unfortunately, one of those things that you can agree with in principle, but figuring out how to do useful ones that don't seem like makework takes a leap. A small leap in retrospect, but a leap that can be hard to find nonetheless. Techniques for cutting down repetition, emphasis on negative unit tests (i.e. equally important to explicitly state that you can't do X), creating mock objects that record actions to compare against expectations, all are techniques that are a little hard to extrapolate from simple examples.

    Assertions and unit testing might not be "debugging tools" in and of themselves, but they certainly help prevent bugs from slipping in unnoticed.

    --
    Binary geeks can count to 1,023 on their fingers :)
  149. gnutls ! by Anonymous Coward · · Score: 0

    GNUTLS (www.gnutls.org) is a LGPL'd library, originally done because the OpenSSL license is uncompatible with the four freedoms of GPL and they don't want to change that. However, it is great quality, and from the developers of GPG so they know their crypto very well! I would say it's better in every way, plus it has an alternative OpenSSL-compatible-API for the switchers.

  150. Missing the point by Decaff · · Score: 1

    The big deal with Smalltalk (and similar systems) is that if you have an error (even one you have not prepared for with an exception handler). The system will stop with a traceback and allow any operation to be executed, any code to be compiled. Visual Studio is typical Microsoft: You can do some things in a suspended application, but not others. You can't recompile the module where the error occurred and restart, for example. Java 1.4 is part of the way there, with hot-swappable code, but you still only discover errors because of a traceback after the process has terminated.

    Once someone have used a good Smalltalk-type environment in which everything is possible at any time, and with refactoring tools as standard, they usually come to realise that products such as Visual Studio are limiting and primitive.

  151. How to ask a question on Slashdot by Ed+Avis · · Score: 1
    Slashdot questions that aren't really questions?
    A Slashdot editor writes: "I am wondering the best way to write a headline for a reader's submission. I'm new to this and I always thought that a question has to have a verb and usually some kind of word like 'what' or 'how', but a lot of stories seem to manage by just sticking a question mark onto the end of some random words. What should I do?"
    --
    -- Ed Avis ed@membled.com
  152. Delta debugging by Ed+Avis · · Score: 1

    To hype anything as 'new' and 'revolutionary' is silly, since as we all know, nothing new has been invented since 1970. But there are certainly techniques which aren't as popular as they deserve to be. One is Delta Debugging as implemented by delta (a tool to automatically produce minimal test cases) and Ask Igor.

    --
    -- Ed Avis ed@membled.com
  153. Printing debug info in java by bertvv · · Score: 1
    Printing debug info while developing an application is neat, but when your code goes into production, it's a nuisance. Here's a trick to avoid this in Java. Define a public constant somewhere, e.g.
    public class Utils {
    public static final boolean DEBUG_OUTPUT = true;
    ...
    }
    when you want to print some debug info elsewhere, use:
    if (Utils.DEBUG_OUTPUT) {
    System.out.println(stuff);
    }
    When you're about to release the code, change the value of DEBUG_OUTPUT to false. The java compiler is smart enough to know that the if-blocks will never have to be executed and will not generate byte code for the print statements.
  154. Re:So I need two running programs to debug relativ by Janek+Kozicki · · Score: 1

    thank you very much for this information. I must standarize my notation somehow. Most problems I have are just because I'm not aware what types should I distinguish.

    I have more questions if you don't mind.

    what is your convention for giving class/struct/typedef names? (I tend to use prefix class_ struct_ type_ respectively - is that enough or something more sparks to your mind?)

    some hints about function names? (or just what do you prefer `foo_bar()` or `FooBar()` ? I just cannot make a legitimate decision on this topic)

    do you use c++ namespaces? (I almost always start my c++ program with 'using namespace std;') If yes, then what names do you give to them?

    --
    #
    #\ @ ? Colonize Mars
    #
  155. Who needs debugging? by n2rjt · · Score: 1

    Simply release the product, and let the support group start recording the issues. Keep paying a stable of programmers, and eventually, like monkeys on typewriters, they'll hammer out version 2.0. Rinse, Repeat.

  156. Bidirectional debugging by cau · · Score: 1

    Bidirectional debugging allows you to step forward and backward one line of code at a time.

    A paper published in PLDI 2000 describing this is available here. IIRC at some point they had an implementation of this built on top of gdb.

  157. Linux magazine by sad_ · · Score: 2, Interesting

    Linux Magazine issue of April 2004 covered a new debugging technique that has been used on the 2.6 kernel, called 'source code analysis'. the program used, called smatch, and all the documentation needed can be found on sourceforge here.
    its main focus is the kernel, but it should be easy enough to adapt to other programs. not a debugger in the true sense of the word but it will detect a lot of bugs for you which you might otherwise have to hunt down with a debugger.

    --
    On a long enough timeline, the survival rate for everyone drops to zero.
  158. Re: Old news by peter · · Score: 1

    run ulimit -c unlimited before running the daemon. gdb a.out core. If it doesn't crash in a way that dumps core, i.e. it just exits with an error code, you could run it under ltrace or strace. You'll have giant trace files if you do that, though. You could exclude some system calls from tracing, such as gettimeofday.

    --
    #define X(x,y) x##y
    Peter Cordes ; e-mail: X(peter@cordes , .ca)
  159. Re:So I need two running programs to debug relativ by johannesg · · Score: 1
    thank you very much for this information. I must standarize my notation somehow. Most problems I have are just because I'm not aware what types should I distinguish.

    Don't overdo it. The question you need to ask yourself is, "what information do I really need when _reading_ the code?" I find I am usually interested in scope, but not really in type (the question I want answered is "where the hell did they declare that?" rather than "hmm, I wonder if it is a bool or an int?"). In particular, if something has class-scope I want to know, so like the original poster I use a prefix for those. I do not use enough static or global variables for them to ever become an issue, so I do not prefix those.

    Of course when you are _reading_ code it is often other peoples' code, leaving you at their mercy, prefix-wise. Typically the nastiest code will also use misleading prefixes...

    what is your convention for giving class/struct/typedef names? (I tend to use prefix class_ struct_ type_ respectively - is that enough or something more sparks to your mind?)

    I would say it is too much already. The difference between a class and a struct is too insignificant to worry about. I consider typedefs just a clever-looking way to obfuscate code that is otherwise perfectly clear, so as a general rule I steer away from them (whatever is wrong with just using "int" when you want an integer? I understand things like "uint32", but making integers look like structures ("csw_status_t") is just plain annoying...)

    some hints about function names? (or just what do you prefer `foo_bar()` or `FooBar()` ? I just cannot make a legitimate decision on this topic)

    Whichever you can type the quickest ;-) I hate those underscores, it messes up my typing, so I use BiCaps. And try to use names that makes your program look like normal prose - when you see "cfg_hw" I have no clue what it does, while "ConfigureHardware" gives me a good idea. Same goes for variable- and other names of course.

    do you use c++ namespaces? (I almost always start my c++ program with 'using namespace std;') If yes, then what names do you give to them?

    I do not usually use them. Whether or not that is smart I haven't figured out yet, despite 6 years intensive C++ programming (and earning the title of "C++ guru" within my company).

  160. Different philosophy by Hecatonchires · · Score: 1

    If I typo with an ifdef, my compiler doesnt report what _really_ went wrong. I'm not developing for mobile platforms, so I don't need the absolute greatest efficiency - hell, thats why I'm not writing in assembler. And what about languages other than the c family, that dont support precompile directives? This is a more 'language agnostic' solution.

    Or, a little from column a, a little from column b
    ^_^

    --

    Yay me!