1

I have two problems: a program I made am glitching out and making nearly unkillable processes, if either subproblem is solved I believe both problems will be easily resolved. I am running an early 2008 Macbook on OSX 10.6.8.

/Problem #1, coding:/

I've been playing around with the iRobot Create using termios.h I/O. I compile without warnings or errors and can run the program without a hitch. I am connecting to the robot by usb which explains the input "/dev/tty.usbserial".

 gcc simple.c -o simple
 ./simple /dev/tty.usbserial

The program starts by checking the arguments given, then tries to connect with the given argument (char * device is /dev/tty.usbserial) with the biscConnect() function. It fails on my mac.

//in file simple.c:
int main(int argc, char *argv[]){
if(argc!=2){
    printf("Put port... like /dev/tty.usbserial or something\n");
    exit(EXIT_FAILURE);
}
printf("Starting...\n");
biscConnect(argv[1]);
}
void biscConnect(char *device){
struct termios tty;

// Try to open the device from the input
    if((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK))==-1){
        fprintf(stderr, "Serial port at %s could not be opened: %s\n", device, strerror(errno));
        exit(EXIT_FAILURE);
    }
     tcflush (fd, TCIOFLUSH);
     tcgetattr(fd, &tty);
     tty.c_iflag     = IGNBRK | IGNPAR;
     tty.c_lflag     = 0;
     tty.c_oflag     = 0;
     tty.c_cflag     = CREAD | CS8 | CLOCAL;
     cfsetispeed(&tty, B57600);
     cfsetospeed(&tty, B57600);
     tcsetattr(fd, TCSANOW, &tty);

     //The code fails prior to this point
}

I would then send bytes to the robot to make it move if it didn't get stuck before then.

/Problem #2, unkillable processes:/ When I run the file, the terminal goes into a weird mode where the prompt is gone and I can type anything I want (usually signifying a process is running). I cannot exit using control-c. The only way I can seem to exit is closing the terminal window. This fails to kill the running process.

I can easily look up the pid but the Activity Monitor but the Force Quit fails to kill the process, kill -9 [pid] fails, killall [program name] fails etc. despite acknowledging the existence of the program. The only way to force terminate the process seems to be to physically close off the power from the computer and reboot it (ie shuting down doesn't work because it tries, and fails, to terminate the process(es)). I am wasting a terrible amount of time if to debug the program I need to power-cycle my laptop every run! I can continually create more process but am unable to delete them.

I think if I knew the parent process I might be able to kill these "zombie" processes but I don't know what the parent is.

Any ideas on how to get rid of these processes without power-cycling would be tremendous help, thanks!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
nico
  • 2,022
  • 4
  • 23
  • 37
  • 2
    You can't kill zombies; they're the undead processes. You can kill the zombie's parent process, in which case, the zombies are inherited by the init process which promptly puts them out of their misery. – Jonathan Leffler Jul 14 '13 at 22:43
  • @JonathanLeffler: Don't zombies get harvested regularly anyway? – Kerrek SB Jul 14 '13 at 22:46
  • @JonathanLeffler: I see, so would it be possible to kill the parent which would, in turn kill the child? The problem is I don't know who the parent is. – nico Jul 14 '13 at 22:48
  • Please look here at possible solutions on how to fight zombies: http://stackoverflow.com/questions/16078985/why-zombie-processes-exist/16167157#16167157 – mvp Jul 14 '13 at 22:49
  • @mvp: Okay, that's helpful please post an answer so I can select you as best answer. – nico Jul 14 '13 at 22:50
  • @KerrekSB: The formal definition of a zombie is a process that has exited whose parent has not exited and is not ignoring dead children (has not set SIG_IGN for SIGCHLD) and has not yet waited for the zombie child process. AFAIK, such processes are only harvested when the parent process dies or when the parent process waits for the child's exit status. When the init process inherits an orphaned zombie, it simply waits for the exit status of any child and substantially ignores it, but that removes the zombie from the process list. – Jonathan Leffler Jul 14 '13 at 22:55
  • You should be able to tell a zombie's parent process from the `ps` listing showing the zombie. If you can't, that may mean that the process is not a zombie (it might be still 'live', but locked in an uninterruptible system call in the relevant device driver, for instance). All this is straight-forward POSIX-ish theory. I'm not aware of any particular twists for Mac OS X, but BSD (on which it is based) has more system calls in this area than most Unix derivatives. – Jonathan Leffler Jul 14 '13 at 22:59
  • @JohnSmith: if you think that my linked answer is the best, you should vote it up and close (or ask for closing) of this question as duplicate. It would be strange for me to create link-only answer to my own other answer – mvp Jul 14 '13 at 23:02
  • You have at least 5 systems calls (`tcflush()`, `tcgetattr()`, `cfsetispeed()`, `cfsetospeed()` and `tcsetattr()` that all return an error status that you ignore. You might be able to afford that once you've got the program working (difficult judgement call), but when anything is going wrong, one of the first things to do is check that functions that report failure are not reporting failure that you ignore. – Jonathan Leffler Jul 14 '13 at 23:29

2 Answers2

1

You can find out who birthed that undead process by running ps ef or using htop.

PID   TTY      STAT   TIME COMMAND
21138 tty1     T      0:00 sudo /usr/bin/aura -Akax open_watcom openwatcom-extras-hg HOME=/home/hav3lock USER=hav3lock SHELL=/bin/zsh TERM=linux PATH=/usr/local/sbin:/u
21139 tty1     T      0:00  \_ /usr/bin/aura -Akax open_watcom openwatcom-extras-hg TERM=linux PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/
22111 tty1     Z      0:00      \_ [su] <defunct>`

In the above I have a zombie process who's momma is /usr/bin/aura, a process spawned by sudo /usr/bin/aura.

Running sudo kill -9 21138 will kill the parent, thereby subsequently killing its zombie spawn.

PID   TTY      STAT   TIME COMMAND
23858 pts/9    S+     0:00 sudo sudo ps ef LANG=en_US.utf8 DISPLAY=:0 SHLVL=3 LOGNAME=hav3lock XDG_VTNR=1 PWD=/home/hav3lock/sy.l/repos/pub_rel/slen/linux/src HG=/usr/b
23860 pts/9    S+     0:00  \_ sudo ps ef LANG=en_US.utf8 DISPLAY=:0 LS_COLORS=no=0:fi=0:di=34:ln=00;96:or=91;4:mi=00;31;9:mh=01;37:pi=33;7:so=01;35:do=35:bd=01;33:cd=9
23861 pts/9    R+     0:00      \_ ps ef LANG=en_US.utf8 DISPLAY=:0 LS_COLORS=no=0:fi=0:di=34:ln=00;96:or=91;4:mi=00;31;9:mh=01;37:pi=33;7:so=01;35:do=35:bd=01;33:cd=93
13405 tty2     S<sl+   3:49 X :0 HOME=/home/hav3lock USER=hav3lock SHELL=/bin/zsh TERM=linux PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/ve`
Alexej Magura
  • 4,833
  • 3
  • 26
  • 40
  • Note, I used `ps ef` for this post; not `htop`. Also, I should note that I was running **ps ef** using **sudo**. – Alexej Magura Jul 14 '13 at 22:59
  • Killing 21138 might or might not kill 21139, and the zombie won't go until 21138 dies. – Jonathan Leffler Jul 14 '13 at 23:00
  • Okay, I get this: 501 1507 1 0 0:00.00 ?? 0:00.01 ./simple /dev/tty.usbserial but how does that help? It doesn't *seem* to give a parent; it just acknowledges its existence. – nico Jul 14 '13 at 23:03
  • So to find a given zombie's parent, just run: `sudo ps ef | sudo awk '{print $1 "\t" $2 "\t" $3 "\t" $5 " " $6 " "}' | grep -w Z --before-context=20` and be sure to adjust the **--before-context** accordingly. [here's where I got my info](http://how-to.wikia.com/wiki/How_to_display_and_kill_zombie_processes) – Alexej Magura Jul 14 '13 at 23:15
  • you can swap `-w Z` for the process id of the zombie who's parent you're looking for. (tried to edit my previous comment, SO complained.) – Alexej Magura Jul 14 '13 at 23:24
  • Humm, I'm confused. I get this output: `Nico 1536 0.0 2434832 176` but I still cannot seem to get the nicely formatted table you were getting in your second code example. I'm running `sudo ps aux | sudo awk '{ print $1 "\t" $2 "\t" $3 "\t" $5 " " $6 " " }' | grep -w 1536`. How do I know the `--before-context` number (if I'm even running the right command). Thanks for the help. – nico Jul 14 '13 at 23:35
  • run `sudo ps ef`, `aux` gives you different output. So run the same command that you entered in your comment, but use `ef` instead of `aux`. see `man ps` for more details. NOTE: using `-ef` does not seem to provide the same output as `ef` – Alexej Magura Jul 15 '13 at 00:47
  • I found a ***way*** easier way to find this info. just run `ps -p[PID] -ostat,ppid,pid` where PID is the process id of the zombie--it'll give you the PPID (parent process id) which you can then use with `kill -9` like so: `ps -p27760 -ostat,ppid,pid ; sudo kill -9 27759` `STAT PPID PID Z 27759 27760` `[1] + killed aura-as-root -Akax open_watcom` – Alexej Magura Jul 15 '13 at 01:01
1

On Mac OS X 10.8.4, I created a program zombie from zombie.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    pid_t pid;

    if ((pid = fork()) >= 0)
    {
        if (pid == 0)
        {
            printf("%d: committing suicide (parent %d)\n", (int)getpid(), (int)getppid());
            exit(0);
        }
        else
        {
            printf("%d: going to sleep for a while - child %d might die while I snooze\n",
                (int)getpid(), (int)pid);
            sleep(30);
            printf("%d: awake\n", (int)getpid());
        }
    }
    return 0;
}

When I ran it in one terminal window, the output was:

$ ./zombie
2443: going to sleep for a while - child 2444 might die while I snooze
2444: committing suicide (parent 2443)
2443: awake
$

In another terminal window, running ps -f produced:

  UID   PID  PPID   C STIME   TTY           TIME CMD
  503   260   249   0 12:42PM ttys004    0:00.08 -bash
  503  2443   260   0  5:11PM ttys004    0:00.00 ./zombie
  503  2444  2443   0  5:11PM ttys004    0:00.00 (zombie)

The parenthesize (zombie) is the defunct process, and the name in parentheses is the original name of the process. When I copied the program to living-dead, the corresponding output was:

  UID   PID  PPID   C STIME   TTY           TIME CMD
  503   260   249   0 12:42PM ttys004    0:00.09 -bash
  503  2454   260   0  5:13PM ttys004    0:00.00 ./living-dead
  503  2455  2454   0  5:13PM ttys004    0:00.00 (living-dead)

(On most systems, the defunct process is marked as <defunct> or something similar.)

Clearly, the value in the PPID column identifies the parent process of the zombie, and the various process IDs match the output from the programs themselves.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    @Alexej: thanks for the edit. However, since the program produces different output each time it is run (different PIDs), the past tense is correct — the details in the examples are historically accurate and, while representative of what anyone would see, are distinctly different from what anyone else would see. – Jonathan Leffler Jul 15 '13 at 15:49