Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×
Programming

Eric S. Raymond Identifies A Common Programming Trap: 'Shtoopid' Problems (ibiblio.org) 189

"There is a kind of programming trap I occasionally fall into that is so damn irritating that it needs a name," writes Eric S. Raymond, in a new blog post: The task is easy to specify and apparently easy to write tests for. The code can be instrumented so that you can see exactly what is going on during every run. You think you have a complete grasp on the theory. It's the kind of thing you think you're normally good at, and ought to be able to polish off in 20 LOC and 45 minutes.

And yet, success eludes you for an insanely long time. Edge cases spring up out of nowhere to mug you. Every fix you try drags you further off into the weeds. You stare at dumps from the instrumentation until you're dizzy and numb, and no enlightenment occurs. Even as you are bashing your head against a wall of incomprehension, consciousness grows that when you find the solution, it will be damningly simple and you will feel utterly moronic, like you should have gotten there days ago.

Welcome to programmer hell. This is your shtoopid problem.... If you ever find yourself staring at your instrumentation results and thinking "It...can't...possibly...be...doing...that", welcome to shtoopidland. Here's your mallet, have fun pounding your own head. (Cue cartoon sound effects.)

Raymond's latest experience in shtoopidland came while working on a Python-translating tool, and left him analyzing why there's some programming conundrums that repel solutions. "You're not defeated by what you don't know so much as by what you think you do know," he concludes. So how do you escape?

"[I]nstrument everything. I mean EVERYTHING, especially the places where you think you are sure what is going on. Your assumptions are your enemy; printf-equivalents are your friend. If you track every state change in the your code down to a sufficient level of detail, you will eventually have that forehead-slapping moment of why didn't-I-see-this-sooner that is the terminal characteristic of a shtoopid problem."

Share your own stories in the comments. Are there any programmers on Slashdot who've experienced their own shtoopid problems?
This discussion has been archived. No new comments can be posted.

Eric S. Raymond Identifies A Common Programming Trap: 'Shtoopid' Problems

Comments Filter:
  • how on earth would you instrument *this*?? https://en.wikipedia.org/wiki/... [wikipedia.org]

  • Not always... (Score:5, Interesting)

    by rbeattie ( 43187 ) <russ@russellbeattie.com> on Sunday September 30, 2018 @05:49AM (#57398584) Homepage

    More times than not, the solution is actually really difficult - you just underestimated the problem. Then you go to github and find a library that shows you how it should be done, and you can't believe it takes so much code to do something that seemed so straightforward.

    • Re:Not always... (Score:5, Informative)

      by StormReaver ( 59959 ) on Sunday September 30, 2018 @06:03AM (#57398600)

      ... can't believe it takes so much code to do something that seemed so straightforward.

      While that happens too, it is on the other end of the spectrum of what Eric is describing.

      • Re:Not always... (Score:4, Interesting)

        by igny ( 716218 ) on Sunday September 30, 2018 @09:01AM (#57399018) Homepage Journal
        The shtoopidest problem I faced was in TransactSQL. Usually, the syntax there is case insensitive, but there is a difference between
        • where timeStamp >= format(watermark,'yyyy-MM-dd hh:mm:ss') --<-- incorrect
        • where timeStamp >= format(watermark,'yyyy-MM-dd HH:mm:ss') --<--correct

        This bug was extremely elusive for me because the code looks fine and watermark in our data is almost never between 00:00:00 and 01:00:00 and that was when the bug sometimes causes missing data in our target tables.

        • Re: Not always... (Score:4, Interesting)

          by UnknowingFool ( 672806 ) on Sunday September 30, 2018 @01:10PM (#57399698)

          Sometimes it's a very slight difference between environments that causes problems. We rolled out some code to production that had been fully tested in Dev and Test environments. Things started to break due to SQL errors. Ran the SQL directly on the production database server but it ran fine. Somehow the SQL was getting different results running through the production server than it was on the production database server directly.

          After some investigation the only difference between the production server and other environments was the server used a slightly older database driver. It was a minor version difference. How this caused errors was that in the older db driver all math operations had to be explicit data casts despite what documentation said but the newer driver followed the database documentation. So Integer A / Integer B should be implicitly cast as Integer according to the documentation. However the older driver would cast that as Float for some unknown reason and that would cause errors.

          But this would only happen using the db driver on Production. Testing the SQL directly on Production DB wouldn't have found it. Testing the code and SQL on Dev and Test servers wouldn't have found the bug. The patch notes for the db driver didn't mention the change.

        • Nice example of how to do something completely wrong.

      • Re:Not always... (Score:5, Insightful)

        by Rei ( 128717 ) on Sunday September 30, 2018 @10:10AM (#57399226) Homepage

        Agreed. But I don't really think Eric's "solution" is that helpful. Heres the last two "shtoopid" problems I had (in a CFD model evolution app):

        1) My program (which a piped child process, which in turn had its own children) was randomly locking up when one of the subprocess's children died. Now, normally that's an eminently solveable problem... except for the fact that it was locking up in a different place each time. I was stuck digging deeper and deeper into pipe magic with no luck. I even went to strace python, but that just added more confusion, as strace was dying at random times, and sometimes not even printing out full lines!

        The problem? The output of my program was running through "tee". I was only seeing the last section of the buffer to be printed out :P The real problem was that the subprocess had simply stopped printing data and so the pipe read was hanging; it was instantly obvious when "tee" wasn't used.

        2) My program would sometimes go into a "subprocess keeps dying" mode. This started out of the blue with no changes to my code. Again, I kept instrumenting more and more, with no luck.

        The problem? I had started, in another window, a shell script that ran on a loop to generate visualization data at regular intervals whenever the process was running. When the visualization data would appear in the middle of a run, it would sometimes interfere with the raw data, due to the way the data processing was set up. But since that visualization data wasn't present when the run started, it took time for the problem to show up, and then would just occur out of the blue.

        The short of this is... if you follow Eric's "instrument everything" solution to "shtoopid" problems, you'll sometimes just dig yourself further into a hole. The problem is that you have a base assumption that's wrong. IMHO, the best solution is to bring a third party in and explain everything about what you're doing and where it's going wrong. Not only can their different perspective add insight, but the very act of having to explain and reproduce everything from scratch (and answer their questions) can help you as well.

        • I go the exact opposite direction of him!

          Just stop looking at the instrumentation as if you're researching a problem or doing R&D. You're not doing R&D when you have a trivial mistake you can't find, you're just debugging.

          Stop looking at the tools. Look at the code. If you find yourself saying, "It...can't...possibly...be...doing...that" just whack yourself over the head with the cartoon hammer right there, because telling yourself that is why you're having trouble finding it. You have to instead be

    • by thsths ( 31372 )

      Yes, I agree that some problems are more complicated than they seem, especially if you need to synchronise with some other state, or a poorly documented piece of software.

      State is the key problem, the article is right about that. If I find these problems, I try to eliminate states as much as possible. Sometimes a different programming approach help. Reconstructing a value rather than saving it reduces complexity. But sometimes you need the state, and then you may want to look at state machine theory, which

  • Something visual, that needs no printfs.
    • by serviscope_minor ( 664417 ) on Sunday September 30, 2018 @06:41AM (#57398696) Journal

      Or with experience you realise that stepping debuggers are great for some problems and printfs are great for other problems.

    • by mikael ( 484 )

      One problem I encountered with an early C++ compiler was that a chain of function calls which had a function in the middle that had a return result of "int" would actually return the result of the last function call it itself had made,even if no return result was supplied. While this was the actual intention, it was spooky that no value was returned. Any attempts to add new code would just make this fail.

      • by djinn6 ( 1868030 )
        This would makes a lot more sense if you read the disassembled program. Per common C calling conventions, the return value is stored in the eax register before handing the control flow back to the caller. Suppose function A calls function B, which in turn calls function C. C would set the eax register to some int value that it wants to return, since B does nothing after calling C, eax would be unmodified. When A checks eax for the return value of B, it would get C's return value instead.
      • I knew people who relied on non-standard or indeterminate compiler behavior like that. Then they'd move to a new machine or upgrade the compiler and complain that it wasn't working right or that it was now giving warnings about code that they thought was perfectly fine.

  • Nothing said (Score:2, Insightful)

    by yanestra ( 526590 )
    No-one can doubt that Eric S. Raymond is a talker.
  • by Serif ( 87265 ) on Sunday September 30, 2018 @06:29AM (#57398652)

    Been there, got several wardrobes full of T shirts.

    If unit testing and staring at code for more than a few minutes doesn't solve this kind of problem, then the assertion hammer comes out. Assert everything, especially the things that are so obvious that they don't need an assertion. The bugs just have fewer and fewer places to hide and eventually surrender.

    • Re: (Score:2, Interesting)

      by justthinkit ( 954982 )

      These are always humorous comment threads.

      Everyone has some experience. Everyone has plenty of advice. Lots of absolutes (like the parent's) come out.

      Point number one, always, is to check our assumptions. We assume we know how to code. We assume others know how to code. We assume libraries work as documented. We assume compilers are logical. We assume we are.

      Men assume women are logical. Fun ensues.

      Kids assume parents are good examples. And waste decades of their lives.

      Physics drifts away from the

  • by jrbrtsn ( 103896 ) on Sunday September 30, 2018 @06:30AM (#57398656)

    Over my 30 year career, I cannot believe how many 'C' programmers I've come across who are unfamiliar with the assert() macro. This macro is essential for trapping all invalid assumptions! Usually it's as simple as:

    if ( ! functionWhichCanFail(a,b,c) ) assert(0);

    Run your program from the debugger, and it will stop when the assert(0) is encountered, giving you full and convenient access to everything needed to hunt down the issue.

    • by Anonymous Coward

      as a user, nobody wants the program to abruptly shut down when something goes wrong, often losing their work. this is why a lot of modern languages de-emphasize or completely lack things like assert and exceptions

    • by blackhedd ( 412389 ) on Sunday September 30, 2018 @12:47PM (#57399634)

      You got the right way to say it: "Assert all of your assumptions."

      Code rots when it gets modified in ways that don't respect the implicit assumptions made in the past. Have you ever said to yourself, "this function is only called from two places and I know those two places validate the parameters"? When you then write the function without checking parameters, you've made an implicit assumption that makes all the sense in the world at that moment. But someone else (or you in three months) will forget or won't know the assumption, and call that function from somewhere else, with unchecked parameters.

      Either document your implicit assumptions (making them explicit), or (better) assert them. The way to get good at asserting implicit assumptions is first to learn how to recognize when you're making an implicit assumption! That takes skill and practice, but if you don't do it, asserts don't help you.

      And I leave the asserts in the final builds, too. In decades of professional C programming, I've never had a case where the asserts imposed a measurable performance penalty.

      To the people who say "use NDEBUG to disable your asserts for production, because customers hate interruptions": no, don't do that. A violation of an implicit assumption is ALWAYS a bug, and it's always better for it to bite your behind sooner rather than later. The assert tells you exactly what you did wrong. I've had this conversation dozens of times:

      [Angry customer]: Your software crashed!
      [Me]: pop open the syslog and search for the word "assert."
      [Angry customer]: It says "line XXX in file YYY"!
      [Me]: you'll have the fix in two hours.

      Interestingly, there is a handful of classes of bugs that are impervious to asserting your assumptions. The worst of these, in my experience, is the accidentally shadowed variable. But using assert in a disciplined way is incredibly useful.

      • I have had to remove asserts where the code was too big to fit on the chip anymore. I found a few asserts, verified that they could not possibly happen, and removed them.

        For most stuff I've worked in in the last couple of decades, the assert causes a mysterious reboot and coredump.

        • One thing I've done a lot is to rewrite the assert macro so that it leaves a syslog trace. Another thing you can do (if you're lucky enough to get a coredump on failure) is to arrange for a distinctive signal (like SIGABRT) to hit your program. That stands out nicely in the coredump.

      • by dfsmith ( 960400 )

        [Angry customer]: The software I was using crashed with an assert code!
        [St. Peter]: Yes, we'll have to talk to the car manufacturer about that.

        Most of the software I work on can emit smoke, mangle parts, or lose data if it were to abort. There's a place for assert(), but it's not always an option.

    • They can sometimes be annoying. Ie, "assert(0)" for me often generates a code dump where I can't see the actual value of the original culprit variables anymore, since the compiler thinks the variables in don't need to be saved and the assert code itself scribbles all over the registers.

      Another problem with asserts is that they need to be about REAL errors. I've seen many cases where an assert has happened at a customer and when investigating you see that the assert itself is the error. Often the devs jus

      • As with every tool and technique, there are right ways and wrong ways to use it.

        To one of your points: sometimes it's not easy to figure out the best or most consistent way to handle a problem, when you expect it to happen never or almost never. A perfect example is when you can't create a realistic test case! In that case, I'd rather write an assert and get a deterministic and easily-fixable failure in the field, than write complicated error handling and recovery that I can't easily test.

        One time I nearly

  • by jrbrtsn ( 103896 ) on Sunday September 30, 2018 @06:34AM (#57398672)

    A few years ago I had an issue in a multi-threaded program where using printf()'s caused the problem to go away. In order to track the problem down, I ended up writing messages to a buffer in RAM, and dumping the buffer to stdout after the problem occurred.

    • Of course not. There is nothing special about printf: it is just an ordinary function that takes time (multiple cycles) to execute. During that time, multiple values to be printed can be changed by other threads so the printed results are inconsistent. In such cases, you need to use a mutex.
      • I would assume that printf is thread safe on at least some operating systems, printing the whole message and blocking other calls. That would force thread synchronization with the mutex present but hidden. Especially on Windows, where they do a lot to protect users against bad code, without much outside input in those decisions.

        • printf (and the stdio library in particular) may be thread-safe with respect to the FILE* objects but never with respect to the arguments you pass to printf for printing. In particular, something like:

          printf( "%d %d\n", i, j );

          guarantees nothing about when (or in what order) the values of i and j are read and copied into printf's stack frame (which happens before printf is even called just as every other functions' arguments).

    • by Wrath0fb0b ( 302444 ) on Sunday September 30, 2018 @09:03AM (#57399028)

      Fun story time related by a colleague. A pretty common piece of software (hint: there's probably one running within a few hundred yards of you) had an elusive bug. But as the parent noted, printf caused the problem to go away, and it was suspected because it caused synchronization on stdout. Unlike the parent, the developers didn't have time to actually implement a buffered-log solution to figure this out, so they the obviously-logical thing -- they replaced all the printf calls with barrier() [kernel.org] and shipped it. It's still running like this today.

      Another good one, I worked with someone who would log everything all the time by fprintfing to a high-numbered pipe. When I asked him, he gave a few advantages that still ring partially true (depends on context): first, he said, I can get the log from any running instance without even stopping by d-tracing the system call. But most critically, he said, all the formatting happens in userland and only after the syscall does the kernel actually realize that there's nothing on the other end of the pipe and drop the write. That means, he reasoned, that the release/debug versions would always have very close behavior and would avoid the class of 'bugs that don't reproduce in debug build'. As with the other story, to this day, there's a slew of machines out there, formatting and writing log messages to a pipe that's never open.

      • I like to think of those kinds of bugs as Weeping Angels. They only move when you're not looking at them.

        I have about a dozen years experience in MS Embedded CE. There is typically a Release build, and a Debug build. Release will macro out all the debug statements, which changes the execution timing. Enough so to where the bug that is biting you is often seen only in Release. Switch to Debug to chase it, and it goes away.

        I had a similar experience recently with a PIC32 project. The devboard they s

    • A few years ago I had an issue in a multi-threaded program where using printf()'s caused the problem to go away. In order to track the problem down, I ended up writing messages to a buffer in RAM, and dumping the buffer to stdout after the problem occurred.

      Similar story, except that the processor would reboot, clearing all the variables I stored leaving no opportunity to grab all the diagnostics.

      I examined the map, determined what the last address was, added an interrupt handler on the clock that logged the stack pointer ~250/sec (only needed to log the pointer if it was smaller than the existing one) to determine how much margin I had and used that little space between maximum stack and variables to write my diagnostics to.

      Once I had determined the smalles

    • by mikael ( 484 )

      printf makes calls to malloc/alloc and free to do allocation and deallocation for string construction. There were some libraries that provided the printf functionality using a static pool of memory and string concatenation.

  • by jtgd ( 807477 ) on Sunday September 30, 2018 @06:35AM (#57398678)
    Been there, done that many times. Nothing more frustrating to see something you know is absolutely impossible! But fairly satisfying when you ultimately find the bug.
    • "But fairly satisfying when you ultimately find the bug."

      It is not the kind of problem Raymond is talking about, then.

      He is talking about the kind of problem you *know* the solution should be obvious to you from second one and yet, it hides a whole lot of time in which you know, every single second, the problem is laughing at you. When, Bam! you finally find the answer, you know you were right all the time: the solution was obvious, it has been laughing at you at plain sight, and you only feel damn stupid.

      • by djinn6 ( 1868030 )
        Eric's problem is that he tried to write a shitty Python parser instead of doing it the proper way by using the built-in ast module. There would be no mucking about with white space if you start from the parsed ast.
  • by Anonymous Coward

    I learned long ago to recognize the feeling that comes when I know I'm missing something obvious. When I do that, I grab a coworker, and explain the issue to them. Just explaining it to someone is frequently enough, but sometimes they spot something glaringly obvious that I've missing.

    I spent an hour once trying to find an issue where the difference was between I5 and l5. Yeah, depending on your font and display that may be an easy problem, or a hard one. One of those is a capital i, the other a lowercase L

    • Yep. I think 90% of these problems are caused by

      1. Incorrect assumptions about how something that looks simple works. e.g. in Python using sort() (sorts and returns a success flag) instead of sorted (sorts and returns sorted object). I once spent several days tracking down what turned out to be an equation with an ambiguous denominator. The spec author intended (A+B)/(C+D).But elegantly typeset without the parentheses in the spec. The programmer read it as A+ B/C + D

      2. Missing punctuation

      3. Punctuat

    • I had one where I fatfingered O instead of 0. They are next to each other on the QWERTY keyboard, you know. Stared at that line of code for some 5 to 1O minutes, not seeing what the problem could possibly be. I did figure it out finally, but it was annoying to have lost that much time on a visual distinction problem. A better font would have helped.
    • Explaining definitely helps. I can't count the number of times I've spent hours trying to find a bug, finally broke down and posted a request for help, then solve the problem myself a minute or two later.
  • I know this type of thing, is my dayjob. Given, I'm currently doing total LAMP stack web development on setups degraded beyond imagination and a lot of my work involves coming up with crazy hacks and gluecode that gradually inches it's way towards a solution. In order to achieve I do exactly what he describes. It's basically what loosely typed web development is all about. But as far as I can tell, this type of problem is a regular thing in development and results in having to bend our abstraction of realit

    • Yes this is just programming. And Eric Raymond's attempt to sound relevant and profound by pontificating and giving names to things which don't really need naming.

  • by Proudrooster ( 580120 ) on Sunday September 30, 2018 @07:21AM (#57398774) Homepage

    I feel ya brother.. the off by one still gets me 30 years later.
    https://en.wikipedia.org/wiki/... [wikipedia.org]

    I wish we could have an agreement that lists, arrays, elements, and anything put into a list, table, query, associative array, start with an index value of either 0 or 1.

    I don't care just pick one, and don't use two different standards in the same environment.

    • Don't forget the old Fortran programmer who moved to C/C++ and insists that all of his arrays start at 1, like God intended, and added some helper functions and macros to do this. Pity the developer who inherited that code and had to maintain it.

  • Offensive (Score:5, Funny)

    by 110010001000 ( 697113 ) on Sunday September 30, 2018 @07:40AM (#57398812) Homepage Journal
    I find that calling someone "stupid" (even yourself) is offensive and the imagery of "hitting with a mallet" is extremely violent. He shouldn't be allowed to work on open source projects.
    • I call myself stupid all the time, this lessens the blow of other people calling me stupid.

      • I always say that my all code should be idiot-proofed because I'm one of the idiots. But I do generally write good code.

  • by Anonymous Coward

    So you have a failed assertion. What happened? Fire up the debugger, breakpoint on abort. Breakpoint gets triggered, you get a backtrace. Can't imagine how you got there.

    Days of debugging later...

    The abort function is marked as "noreturn". Consequently instead of calling abort, the compiler saves a few bytes/cycles by jumping to a preexisting abort call, never mind the state of the stack frame. Of course, this single recycled abort call in the whole module is where all backtracks end up. Hooray.

    Now o

  • by mothlos ( 832302 ) on Sunday September 30, 2018 @09:15AM (#57399058)

    We have solutions to reduce this sort of problem (at least once you get past the learning curve), but the top programming languages tend to implement very few of them. Reasoning about state is difficult, particularly when that state can be altered in unexpected ways. It is difficult to be confident that your code does what you think it does when you don't have a computer-checked method of specifying your intentions separate from what your code does.

    There are no magic solutions here, at the least you will end up needing to spend more time writing in a specification language and that requires learning how it works. I would say that a gentle introduction to something like this is Elm [elm-lang.org] which has an aim of stripping down typed functional programming into something that doesn't really need a C.S. degree. Here is a video [youtube.com] which helps to explain what a better type system can do for your code. If you want to see something a bit more mind-bending check out Idris [idris-lang.org] which has a much more powerful specification language which can prevent things like off-by-one errors or unbounded recursion in many cases. Moving off the scale of usability a bit, there is ATS [ats-lang.org] which is a difficult language, but its specification language is able to make pointer arithmetic safe and doesn't bind you to immutable data structures. Hell, even Rust [rust-lang.org] is full of good ideas that help to avoid these issues. And if fault-tolerant distributed systems are your thing, you need to check out Erlang [erlang.org] (or its sibling Elixir [elixir-lang.org]) as there are so many great ideas that have been around for decades yet don't get nearly enough exposure.

    This doesn't prevent us all from occasionally falling into this trap, but the themes of the languages listed is to find ways to encourage (or force) you to get the little things right the first time with computer-verified specification and to isolate the search space where problems are likely to occur.

  • Whenever I deal with setting time, daylight savings, time zones etc., managers just assume it is going to be easy. And then the corner cases start popping up. What happens when a co-processor clock drifts 3 seconds ahead during the transition at the end of daylight savings and you had an event that started at 2am local time... Your 20 minute easy bug fix turns into a week of long hours and 2 weeks of testing for the test team. And don't get me started with NTP, that code is awesome but the jitter handli
  • --Try passing BASH commands over SSH to something that Requires Quotes to work right. There's a reason my hair is short.

  • I wish that they would sell it.
    It never does quite what I want,
    but only what I tell it.

  • Back in the day, I'd be given a programming task, and my boss would, naturally, want me to estimate how long it would take. Sometimes it looked like something I could do in maybe a day or two, but I always worried about that elusive bug that might pop up, where I'd get 95% of the coding done in that day or two, but then spend a week tracking down that one knotty problem.

  • Eric S. Raymond

    Just curious: is there another Eric Raymond with a different middle name that the open source community runs the risk of confusing with this Raymond? If not, why the (therefor apparently labored) inclusion of "S"?

    -- not criticizing, just genuinely curious

  • setgrey vs setgray

    'nuff said

  • Recently I spent "weeks" going behind a configuration problem with a RAID1 in an embedded system I am working with. One of the disks go out of the RAID in a casual way ...

    Then, I check the disks and they are OK, I search about my Linux version and some person indicated that "maybe" was because of the particular kernel version, so I improved the kernel. But the new kernel was not OK with my distribution, so I have to change it ... but the new distribution uses different versions of some key libraries forci

  • I can't remember the details now. (In particular, I cannot remember the date or who drove me home) But I can recall these kinds of bugs where you put in the "print" statement after every line, and figure, NOW it will be revealed... ...and the bug goes away. And I gradually removed print statements and brought the code back to not-inspected, and the bug stays gone.

    Your REAL nightmare would be to have it come back at that point, it would start to feel like the X-files. (It's close to that in Ellen Ullma

  • ... places where you think you are sure what is going on.

    "Assumption is the mother of all fuck up's!"

  • Sure, printf is your friend but I have been telling people that for decades now. Nobody ever listened to me when they decided to blame their own naivety on the language or the development suite, or me personally, instead.

  • Home page: http://www.catb.org/esr/pytogo... [catb.org]

    This is not too surprising given his recent work on reposurgeon, his previous statements that Python is simply not performant enough for converting the gcc repository from Subversion to git, and his exploration of Rust vs Go as systems programming languages.

  • by mark-t ( 151149 ) <markt AT nerdflat DOT com> on Sunday September 30, 2018 @02:33PM (#57399982) Journal
    I know what it is that I mean for the program to do, but sometimes will type exactly the opposite, all the while continuing to read it the way that I meant it. Even putting an assert in will not help because in close proximity to where I've accidentally created this kind of inverted condition, it is unfortunately quite likely I will repeat the mistake. And again, when I make these kinds of mistakes, I cannot easily feel nd them on my own because I see the code I thought I wrote instead of what is necessarily actually there.
    • In Python, the pass statement helps with these. You can always convert a single if-without-else construct into an if-else one, where one of the cases has the non-inverted condition.
  • I don't know how many days of my life have been lost chasing the SIGBUS on SPARC while porting libraries over to solaris.

    And don't get me started on code which assumes a null pointer is an empty string
  • Had one of these last week. I'd upgraded Groovy (used as a scripting engine) from 2.3 to 2.5 (and 2.4 which also exhibited the problem). Suddenly scripts that extended a custom base script couldn't instantiate the base class due to a missing constructor. The initial script was instantiating, and if I removed extending the base class it was able to execute.

    Of course, it was actually working in my IDE.

    After multiple days of logging, experimenting, configuring my IDE to (partially) replicate the problem, chasi

  • Instrumentation is nice, but try doing it on a smallish target (think microcontroller) which has to run in real-time, with mediocre and possibly buggy debug adapters.
    Shtoopid problems might be programmer hell. Shtoopid problems on a small target that is hard to instrument is the laparascopic version of programmer hell.
  • so working on this all day, and while driving home, or laying in bed or whatever... the solution pops in your head! you now know what is wrong.
    make haste to your desk, implement the thought of solution, which then... comes very close but still isn't perfect.
    repeat.

  • A classmate of mine spent 45min trying to debug a crash. Eventually he added some printfs here and there but they didn't trigger. So he added more and more. Still nothing. Then he tried to understand why a "shtoopid" printf didn't work... Eventually he figured out that he never actually saved the file in those 45min, that he had kept running the same binary over and over.

Life is a whim of several billion cells to be you for a while.

Working...