• spootle (unregistered)

    It's always fun to see really bad code, only to realise it's your own.

  • First (unregistered)

    "To add insult to injury. I went back into the cvs repository to find out who did it. It was a piece of code I wrote, fresh out of university, when I first joined."

    Now that is funny. But we have all written WTF code at some point...

    (and sory about the "first" posting)

  • null reference (unregistered)
    "To add insult to injury. I went back into the cvs repository to find out who did it. It was a piece of code I wrote, fresh out of university, when I first joined."

    I'm beginning to discover similar little gems in my own code which I also wrote fresh out of college. <sigh>

  • Skurry (cs)

    // this comment always lies

  • Einsidler (cs) in reply to Skurry
    Skurry:
    // this comment always lies

    // both this comment and that comment always tell the truth

  • akatherder (cs)

    I did a web search to see how detrimental kill(getpid(), 9) would really be. It's surprisingly common in online code examples. So I guess that means it works, but probably causes ugly side effects.

    // Reading this comment will give you 'the clap'

  • dkf (unregistered)
    kill( getpid(), 9 );
    For when you positively absolutely must die and dump core...
  • KattMan (cs) in reply to dkf
    dkf:
    kill( getpid(), 9 );
    For when you positively absolutely must die and dump core...

    I dumped my core and it smelled like something died.

  • A Nonny Mouse (cs)

    i once worked on a system with two other developers, where because of our strict coding standards, all our code ended up looking pretty similar. we also all had goldfish-like memory spans and couldn't remember what code we'd worked on. whenever we found wtf-y code, whoever lost rock-paper-scissors got to fix it :)

  • A nony mouse (unregistered) in reply to dkf
    dkf:
    kill( getpid(), 9 );
    For when you positively absolutely must die and dump core...

    Have you ever seen a core from sig9? sig11 (or many others), on the other hand...

  • rawsteak (cs)

    maybe this is not the right place or the right time, but i am fresh out of university, and i read this site everyday to make sure i do not repeat mistakes of old, or worse, become The Brilliant Paula Bean

  • Ancient_Hacker (cs)

    I once worked on a system that had lots of weird features. One was you could simulate keypresses.

    So a lot of programmers would end their programs, not with a call to exit(), but with "keypress( "^C" );"

    Sigh.

  • Michael (unregistered) in reply to rawsteak
    Comment held for moderation.
  • John Cowan (unregistered)
    kill(getpid(), 9)
    is actually the only way to guarantee immediate termination. If you call exit(), then any routine registered by atexit() will get control (and if that routine never returns, the process never dies). If you call _exit(), you may be hung up waiting for asynchronous I/O to complete. If you try to kill yourself with any other signal, a trap handler may be invoked, with the same potential consequences as an atexit() handler.
  • poochner (cs) in reply to Ancient_Hacker
    Ancient_Hacker:
    I once worked on a system that had lots of weird features. One was you could simulate keypresses.

    So a lot of programmers would end their programs, not with a call to exit(), but with "keypress( "^C" );"

    Sigh.

    If that is a ^ followed by a C, that's a true WTF. If it comes out as C with the Ctrl key held down, not so much, since you can set up a handler for that to manage resource cleanup. On *nix, that would depend on what keys you have mapped in your tty settings, I suppose. On w32, it's set in stone.

    The problem with kill 9, is it can't be caught, so all your atexit / onexit funcs, destructors, blah blah get skipped. It's like shooting yourself in the head before writing the suicide note.

  • Rich (unregistered) in reply to John Cowan
    John Cowan:
    kill(getpid(), 9)
    is actually the only way to guarantee immediate termination. If you call exit(), then any routine registered by atexit() will get control (and if that routine never returns, the process never dies). If you call _exit(), you may be hung up waiting for asynchronous I/O to complete. If you try to kill yourself with any other signal, a trap handler may be invoked, with the same potential consequences as an atexit() handler.

    You can't even guarantee it with SIGKILL. Processes can get in certain weird states where the kernel won't let you kill them even with kill -9. Linux calls this Uninterruptible Sleep, and we get this all the time with our flaky NFS servers. The kernel essentially says "i can't trust the device drivers underneath you so it can't let you run", but for some reason decides to not let you kill it either, forcing an eventual reboot. A cool side effect; for some reason the processes are still in the run queue though they can never be scheduled, and you'll see load averages of 30 or 100 and cpu utilization around 5%.

    BTW: instead of kill(getpid(), SIGNAL) you could always call raise(SIGNAL). raise() is actually a part of ANSI C library, where kill() and getpid() are part of posix (ANSI C can not guarantee there's something like a pid). It may be me being picky, but someone who doesn't know about raise() probably won't fully comprehend the damage he may cause by calling raise(SIGKILL). Those exit handlers are there for a reason.

  • Rich (unregistered) in reply to dkf
    dkf:
    kill( getpid(), 9 );
    For when you positively absolutely must die and dump core...

    Pretty good, but:

    1. won't dump core, SIGKILL never does, and never can dump core.
    2. sometimes the kernel won't let you kill a process with SIGKILL. I've seen it on Linux, and i think i remember it on solaris as well. When device drivers get in weird states,sometimes the kernel just throws up it's hands and says "whatever dude"
  • Anonymous (unregistered) in reply to Michael
    Comment held for moderation.
  • Ben Hutchings (unregistered) in reply to Rich
    You can't even guarantee it with SIGKILL. Processes can get in certain weird states where the kernel won't let you kill them even with kill -9.
    This process is trying to kill itself, therefore it's not in interruptible sleep. (Or at least, one thread is not. I'm not sure whether SIGKILL would work if one thread is running and another is in uninterruptible sleep.)
    BTW: instead of kill(getpid(), SIGNAL) you could always call raise(SIGNAL). raise() is actually a part of ANSI C library
    raise() is part of standard C, but SIGKILL isn't.
  • obediah (cs) in reply to Rich
    Rich:
    John Cowan:
    kill(getpid(), 9)
    is actually the only way to guarantee immediate termination. If you call exit(), then any routine registered by atexit() will get control (and if that routine never returns, the process never dies). If you call _exit(), you may be hung up waiting for asynchronous I/O to complete. If you try to kill yourself with any other signal, a trap handler may be invoked, with the same potential consequences as an atexit() handler.

    You can't even guarantee it with SIGKILL. Processes can get in certain weird states where the kernel won't let you kill them even with kill -9. Linux calls this Uninterruptible Sleep, and we get this all the time with our flaky NFS servers. The kernel essentially says "i can't trust the device drivers underneath you so it can't let you run", but for some reason decides to not let you kill it either, forcing an eventual reboot. A cool side effect; for some reason the processes are still in the run queue though they can never be scheduled, and you'll see load averages of 30 or 100 and cpu utilization around 5%.

    BTW: instead of kill(getpid(), SIGNAL) you could always call raise(SIGNAL). raise() is actually a part of ANSI C library, where kill() and getpid() are part of posix (ANSI C can not guarantee there's something like a pid). It may be me being picky, but someone who doesn't know about raise() probably won't fully comprehend the damage he may cause by calling raise(SIGKILL). Those exit handlers are there for a reason.

    I was going to post something about needing to guarantee immediate termination being a clue you've probably made a poor design decision somewhere, but in light of your input, I think it would be better to just replace kill(getpid(), 9) with sync; sync; halt; (or whatever the surefire way to nuke your system is these days), you know for when you really really need to terminate immediatly.

  • Pat (unregistered) in reply to Rich

    I think he meant:

    kill( getpid(), SIGSEGV);

    ^_^

  • Alelksis (unregistered)

    The true WTF here are the comments ;-)

  • Kinglink (unregistered)

    The day you say "what type of idiot wrote this crap" and then find out you were the idiot, is the day you are no longer a newbie.

    Note: If you haven't had that experience, you might (but not necessarily) qualify for "expert" classification as was written in the "Failing the turning test" article.

  • Spectre (cs)
    kill( getpid(), 9 );

    Ha! Even n00bs know that before SIGKILL, you need to send yourself SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGTSTP and SIGSTOP, to ensure that cleanup occurs.

    Still, that's so uncreative... Process termination is a nontrivial task. It shouldn't be done by an unimaginative person.

    BusinessAbstractionLayer::FunctionRetriever(ASSERT_FUNCTION_RETRIEVER)->GetFunction("assert").Invoker()(HardwareAbstractionLevel::Constants::GetFalse(true)); // enterprisey!
    
    system("killall fooapp"); // you just can't trust yourself
    
    ((void(*)(void))0)(); // terminate gracefully
    
    cout << "Press `reset` to continue..."; for (; ; ); //user-oriented programming
    
    __asm {cli
       hlt}; // The Real Programmers' Way
    
    !@#$%^&**()_+=-[]}{;'\|":?><>?\| /* Exit at compile-time! (If won't accidentally happen to be a valid C++ construct) */
    
    </silly>
  • James (unregistered)

    So, I'm basically conversant in Linux but the ancient architectural underpinnings are pretty mysterious -- I don't know much about the signal systems. Can somebody point me to a (online) primer?

  • DaveK (cs) in reply to rawsteak
    rawsteak:
    maybe this is not the right place or the right time, but i am fresh out of university, and i read this site everyday to make sure i do not repeat mistakes of old, or worse, become The Brilliant Paula Bean

    Nah, you don't need to do that. The only thing you need to do is learn how to edit the CVS history file, so you can reassign all your bad check-ins to somebody else's user name, and steal the credit for their good check-ins as your own.

    sed -i CVSROOT/history -e 's/|username1|/|username2|/g'

    is all you need to know in order to found a successful career in computing!

  • Al (unregistered)

    kill( getpid(), 9 );

    We had an intern who did an even worse version of that:

    char command[64]; sprintf(command, "kill -9 %d", getpid()); system(command);

  • Glenn (unregistered)

    Better than kill(-1,9). This kills all processes owned by the user.

    I was once using a broken API which incorrectly returned -1 as the PID of a spawned process. I never called kill(), but other folks' code did. The API idiots didn't think returning -1 was a problem when I notified them of potential issues. Two weeks later, management slammed them for screwing up the schedule.

  • Hoho (unregistered) in reply to Glenn

    Better than kill(-1,9). This kills all processes owned by the user.

    Well, that kind of makes sense...the user might have started more than one instance of your program.

    Actually, shutdown might be even more appropriate...to ensure that the system is in consistent state when execution resumes.

  • ben (unregistered)

    If ran an English-language equivalent of this site, this post would be quoted. I can't understand what he's trying to say in logical terms, it doesn't parse as human language. Are the two stories in the first paragraph related to each other? Does the catching-signal-nine thing relate to the next, quoted bit, about terminating processes? Is this the same story as the next one? It's a word-melange just spewed out there in stream-of-consciousness style, not a coherent narrative.

  • Anonymous (unregistered) in reply to James
    Comment held for moderation.
  • chrismcb (cs) in reply to First
    First:
    (and sory about the "first" posting)

    Really? Are you truley, sincerely sorry? Or are you just saying your sorry?

    Me thinks if you were really sorry you wouldn't have written the idiotic "first1" post in the first place.

  • MichaelWojcik (cs) in reply to Rich
    Rich:
    sometimes the kernel won't let you kill a process with SIGKILL. I've seen it on Linux, and i think i remember it on solaris as well. When device drivers get in weird states,sometimes the kernel just throws up it's hands and says "whatever dude"

    That can happen on any Unix implementation I'm familiar with, and I wouldn't call it a "weird state" - it's a normal part of the Unix process state machine.

    The traditional Unix kernel checked for pending signals (ie examined the signal bitmask in the process table entry) during context switches from kernel to user mode, and when entering and leaving some sleep states. Modern kernels seem to have pretty much continued this design; innovation has mostly come in the form of additional interruptible sleep states, eg the "slow system call" state.

    (See Bach, Design of the UNIX Operating System, 7.2.)

    The "real-time" signals are handled differently, but that's not relevant here.

    No ordinary signal, including SIGKILL, will have any effect on a process (beyond updating the signal bitmask) until it makes one of those transitions. As long as the process stays in kernel mode, or in a sleep state that the kernel can't awaken it from, the signal won't be processed.

    What successfully raising signal 9 for a process does mean is that once it transitions out of user mode (if it's currently in user mode), it will not be able to execute any more instructions in user mode (barring exotic kernel functionality that clears the signal-9 bit in the PTE).

  • jon787 (cs) in reply to Glenn
    Glenn:
    I was once using a broken API which incorrectly returned -1 as the PID of a spawned process. I never called kill(), but other folks' code did. The API idiots didn't think returning -1 was a problem when I notified them of potential issues. Two weeks later, management slammed them for screwing up the schedule.

    I'm not quite sure what "incorrectly" involves here, but returning -1 on error where a PID is normally returned is how fork() behaves. Now if they are randomly returning -1 instead of the real pid then that is a WTF.

    Spectre:
    system("killall fooapp"); // you just can't trust yourself

    Of course on Solaris killall behaves slightly differently than on Linux... If that code runs as root it would be very entertaining.

  • cat (unregistered)
    Comment held for moderation.
  • Charles Duffy (unregistered) in reply to obediah
    obediah:
    I was going to post something about needing to guarantee immediate termination being a clue you've probably made a poor design decision somewhere, but in light of your input, I think it would be better to just replace kill(getpid(), 9) with sync; sync; halt; (or whatever the surefire way to nuke your system is these days), you know for when you really really need to terminate immediatly.

    Halt isn't really all that good -- it doesn't operate immediately, it can be canceled, it depends on your init working correctly, etc. Much better (when you really need to die) to signal your NPS to kill power to your host.

    (Of course, this has much more use in a case where you're part of a shared-resource cluster and you want to make sure the other system is dead... but details, details).

  • Maximander (unregistered) in reply to Spectre
    system("killall fooapp"); // you just can't trust yourself
    Maybe on linux... I'd use
    pkill -9 fooapp
    if I were you though... someone might run your app on real unix and your code would be all kinds of fun or you might want to check that
    id
    doesn't return 0.

    On Solaris, killall does NOT take a process name; it kills all processes.

    CAPTCHA: "paint" (a good argument for pkill -9, no?

  • Peter (unregistered)

    How come no one notices that the real WTF is the writer proposing the storing of a Input to Hash map.

    What is the point of Hashing something for security if you are just going to go and store the input somewhere with the associated hash???

  • Ebbe (unregistered) in reply to Kinglink
    Kinglink:
    Note: If you haven't had that experience, you might (but not necessarily) qualify for "expert" classification as was written in the "Failing the turning test" article.
    Ahemm...

    It's the Turing test. An overzealous spell-checker at work here?

  • csrster (unregistered)

    I'm not sure I really understand the java example. Is the wtf just that it's a pointless thing to do? Here's a self-contained example:

    public class Dumb {

    private static Class dumb_class;

    static { try { dumb_class = Class.forName("Dumb"); } catch (ClassNotFoundException e) {System.out.println(e.getMessage());} }

    public static void main(String[] args) { Dumb an_object= new Dumb(); System.out.println("Created object: " + an_object + " in class " + dumb_class); }

    }

    I'm surprised this thing actually runs. Doesn't the Class.forClass() call try to instantiate the class recursively?

  • csrster (unregistered)

    And wtf is the "Factory Handler Pattern" anyway? Google didn't help.

  • ender (cs) in reply to Spectre
    Spectre:
    !@#$%^&**()_+=-[]}{;'\|":?><>?\| /* Exit at compile-time! (If won't accidentally happen to be a valid C++ construct) */
    For a moment there I thought you were trying to write perl.
  • Kitgerrits (unregistered) in reply to Maximander
    Maximander:
    On Solaris, killall does NOT take a process name; it kills all processes.

    Ooh! I just found a new way of logging out as a user. (assuming it correctly kills the shell and SSH process)

  • AlliXSenoS (unregistered) in reply to Kitgerrits
    Kitgerrits:
    Ooh! I just found a new way of logging out as a user. (assuming it correctly kills the shell and SSH process)

    kill -9 -1 as a user always worked fine for me

  • - (unregistered) in reply to John Cowan
    John Cowan:
    kill(getpid(), 9)
    is actually the only way to guarantee immediate termination. If you call exit(), then any routine registered by atexit() will get control (and if that routine never returns, the process never dies). If you call _exit(), you may be hung up waiting for asynchronous I/O to complete. If you try to kill yourself with any other signal, a trap handler may be invoked, with the same potential consequences as an atexit() handler.

    /me abort()s John

  • Joe McCarthy (unregistered) in reply to chrismcb
    chrismcb:
    First:
    (and sory about the "first" posting)

    Really? Are you truley, sincerely sorry? Or are you just saying your sorry?

    Me thinks if you were really sorry you wouldn't have written the idiotic "first1" post in the first place.

    Actually, YOU should appologize for using the archaic phrase "me thinks"... gosh, that's annoying! Where are you, Ren Fest?

    I personally don't mind "first" posts - in fact, what's wrong with those? Maybe the twelve that come afterward?

    "me thinks" is more annoying than "fist".

    CAPTCHA: tesla (he never said "me thinks" but was always first)

  • Palmyst (unregistered) in reply to csrster
    csrster:
    I'm not sure I really understand the java example. Is the wtf just that it's a pointless thing to do? ... I'm surprised this thing actually runs. Doesn't the Class.forClass() call try to instantiate the class recursively?

    The class loader will not load the class again if it is already in the process of being loaded, so that part is fine. It is a slightly tricky issue that is taken care of in the JVM.

    However, if you are already in the Class, and you need a handle to the class, the correct method is to use the static member named "class" of that class, not to use forClass(). And if you need the class of an object, you should use getClass() on it.

    So rewrite as

    dumb_class = Dumb.class;

  • Palmyst (unregistered) in reply to Palmyst
    Palmyst:
    the correct method is to use the static member named "class" of that class, not to use forClass().

    forName(). There is not forClass(). Don't use Class.forName(), instead just use .class on the class.

    Tongue twister, might also be mind twister.

  • Richard (unregistered)
    The usual way to end a program in C is to simply perform an exit in the code.

    I thought the usual way was to

    return
    from
    main()
    ?

  • Anonymous (unregistered) in reply to Charles Duffy

    Halt isn't really all that good -- it doesn't operate immediately, it can be canceled, it depends on your init working correctly, etc.

    That's what "halt -f" is for. Immediate shutdown, bypassing init.

Leave a comment on “Early Termination”

Log In or post as a guest

Replying to comment #:

« Return to Article