4 ms·
"When approaching debugging, I first find out where the problem is, i.e. the exact line of code or config file or whatever that is causing the problem. That sho
by jakevoytko 16y ago
"When approaching debugging, I first find out where the problem is, i.e. the exact line of code or config file or whatever that is causing the problem. That should not take long, and before you ask anyone else about it you should know exactly where the problem lies."
For crashes: Get backtraces! Knowing the line and the state of the callstack makes many common errors trivial to fix. Some languages (Java, Python) are helpful and generate them automatically. Others (C, C++) require a debugger. I've seen lots of programmers ignore gdb or Visual Studio and spend minutes with printf() looking for the exact line of a crash. Code crashes all the time. Dealing with it methodically and effectively will add minutes - or even hours - to your day.
- flatline 16y agoAlso, for Windows/.NET: mdbg.exe is a .NET command-line debugger that can be helpful when there is a crash on a test or client system as it is portable. Also learn how to take a memory dump and analyze it with Windbg, it has saved me hours particularly when analyzing problems with complex applications like webapps running under IIS. More in terms of tools: if you are tracking down a memory leak, get a memory profiler, don't guess blindly at what is leaking. What can be done in an hour of tracing rooted objects with windbg takes five minutes with a profiler. Likewise with performance profiling.
- bjg 16y agoWith some prior setup you can actually get automatic stack traces in C/C++ for some common crashes ( SIGSEGV, or any other signal for that matter ). http://www.tlug.org.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV http://www.tlug.org.za/wiki/index.php/Obtaining_a_stack_trac...
- ecaradec 16y agoUnder windows you can also get minidump which are a mini core dump with the current state of variables
- dgallagher 16y agoIn Objective-C/Cocoa, I'm a big fan of using the "assert" macro's to throw exceptions if something happened in programming land which is the fault of the programmer. If the assertion is not true, an exception is thrown, and the Class/Method/Line-Number is printed to the console with the exception details. This makes certain programmer errors extremely easy to track down. For example, say you have a method that prints a string, and you "require" that all callers of the method to actually provide a string, and that it's not 0 length: - (void)printAString:(NSString *)aString { NSParameterAssert(aString || [aString length]); NSLog(@"Printing a string: %@", aString); } If |aString| was passed as nil, or 0 length, an exception would have been thrown, showing up on the console. Class, method name, and line number, along with the exception are all printed. Super easy to find! Asserts are also great to affirm that a method returns only "kosher" results: - (NSData *)loadDataFromDatabase:(NSString *)databasePath { NSData *someData = [aDataBaseClassInstance loadData:databasePath]; NSAssert1(someData, @"The |databasePath| is invalid: %@", databasePath); return someData; } If |someData| came back from 'aDataBaseClassInstance' as nil, an exception is thrown; the programmer provided a bad |databasePath| to the database file. The caller of -loadDataFromDatabase: never has to worry about being returned a nil NSData either. You can crash the app, do @try/@catch/@finally, or whatever you choose. While you have to be careful where you use NSAssert()/NSParameterAssert() (Obj-C methods) and NSCAssert()/NSCParameterAssert() (C functions), it can make it easier to stay out of debugger land.
- scott_s 16y agoIndeed. There's also valgrind, which will let you know if you're stomping over memory you shouldn't: http://valgrind.org/ http://valgrind.org/ When students come to me with broken C code, I ask two questions: do you know which line it breaks on, and did you run it with valgrind?
- motters 16y agoDebugging is the lion's share of programming. Any tools which can make the process easier, like gdb or valgrind, will increase productivity. In the olden days I was that printf debugger, but things have improved quite a bit since.
- dasil003 16y agoThe article was decent, but the debugging section offers no insight at all. Shotgun debugging is a strawman, only the incompetent rely on that. Of course you should identify the exact line causing the problem, and of course it should be fast on average, but sometimes it is exceedingly difficult. Bugs come in three flavors: Trivial bugs where available evidence points directly to a cause. The scope of these increases with experience, but most bugs that come up in day to day coding are of this variety. Deep bugs are reproducible, but require bisecting the problem to figure out the cause. Performing optimal bisections requires skill, experience, and raw brain capacity. This is where a good, but let's say, not virtuoso developer can distinguish himself from his less-than-average colleagues in a major way. Heisenbugs are the most difficult because you can't reproduce them, either because it's a concurrency problem or some limitation of the environment the bug occurs in. To solve these bugs, a functional language and pure mathematics may be the best way to get reasonable assurances that a bug is gone, but also radical creativity in code instrumentation or expensive test scenarios with dedicated hardware may be necessary. So, yes, being a productive programmer requires a level of skill where most bugs are trivial. But nevertheless, the second two flavors exist no matter how smart you are, and being productive over the long term means being able to tackle those systematically, even if it takes days or weeks to solve, and if all else fails, figuring out a workaround.
- narrator 16y agoSometimes you can find concurrency bugs by reading logs during concurrent execution, along with a lot of sanity checks that throw exceptions when things go wrong. You can also just look really hard at the code and simulate in your head what might go wrong. IMHO, the hardest bugs are the ones where you have too much data and/or running through the test case takes a very long amount of time. Usually the best way to chip away at these is to try and speed up the test phase by mocking things or to just do a good old stare at the code until the bug shows up. It's a cut once, measure twice approach except with time. You can either run the test again, or you can stare at the code for twice as long and not have the run the test multiple times.
- VBprogrammer 16y ago