LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-28-2011, 09:21 AM   #1
gcubar
LQ Newbie
 
Registered: Jan 2011
Location: Cuba
Distribution: Debian Lenny
Posts: 3

Rep: Reputation: 0
Notify when a process closes


Hi colleagues,

It is possible to know when any process is closed? When I refer to any process, is a process that is not a child of my application.

I thought perhaps pipes in /proc/[pid]/fd/... could helpme, but really I have no idea how it could be.

Any ideas, or is this possible?

Best regards.
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 01-28-2011, 09:31 AM   #2
orgcandman
Member
 
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600

Rep: Reputation: 110Reputation: 110
Have you tried waitpid(PID_T, &status, 0) ?

edit - duh, waitpid is for children.

A few ways you can do this.

#1 - write a small "hook" application to be the parent. All it does is fork() + exec() and waitpid()

#2 - ptrace() attach to the app, and let it continue executing. When it is delivered a signal, you can intercept. If it would exit() normally, your ptrace() call should fail with ESRCH.

#3 - watch a pid file, or /proc/ filesystem.

Last edited by orgcandman; 01-28-2011 at 09:35 AM.
 
2 members found this post helpful.
Old 01-28-2011, 01:10 PM   #3
gcubar
LQ Newbie
 
Registered: Jan 2011
Location: Cuba
Distribution: Debian Lenny
Posts: 3

Original Poster
Rep: Reputation: 0
Thank you for your quick answer.

Quote:
Originally Posted by orgcandman View Post
#1 - write a small "hook" application to be the parent. All it does is fork() + exec() and waitpid()
This sounds a little difficult to implement, or at least to me. Because I don't understand why I need to execute the process any more with fork() + exec(). I repeat that the process is not handled for my applications and it's not a child neither.

Quote:
Originally Posted by orgcandman View Post
#2 - ptrace() attach to the app, and let it continue executing. When it is delivered a signal, you can intercept. If it would exit() normally, your ptrace() call should fail with ESRCH.
Ok, I'm a newbie on Linux. I saw that ptrace like this:

Code:
    pid_t pid = 10000;

    long rTrace = ptrace(PTRACE_ATTACH, pid, 0, 0);

    if(rTrace < 0)
      {
        cout << "ERROR: No. " << errno << endl;
      }
    else
      {
        cout << "Process attached!" << endl;
      }
trace any process in Linux, but, how i hope for the process and get the signal that tells me that the process is terminated? I have to use threads too?

Quote:
Originally Posted by orgcandman View Post
#3 - watch a pid file, or /proc/ filesystem.
What I look for in /proc/filesystems? However, I do not think that this is a good solution.

Thanks.
 
Old 01-29-2011, 12:45 AM   #4
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Quote:
Originally Posted by orgcandman View Post
#1 - write a small "hook" application to be the parent. All it does is fork() + exec() and waitpid()

#2 - ptrace() attach to the app, and let it continue executing. When it is delivered a signal, you can intercept. If it would exit() normally, your ptrace() call should fail with ESRCH.
The man page says:
Quote:
The ptrace() system call provides a means by which a parent process may observe and control the execution of another process,
Does it not mean that ptrace can work on the children of a particular process? If my understanding is wrong, correct me, if not, then OP has specified that he wants to observe unrelated processes too, how will the ptrace work in that case?
 
Old 01-29-2011, 01:03 AM   #5
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Quote:
Originally Posted by gcubar View Post
What I look for in /proc/filesystems?
Observe the below outputs, ps -el lists the PID of ALL the running processes and those processes have an entry in /proc.

The way to read and write /proc is shown here: http://tldp.org/LDP/lkmpg/2.6/html/x769.html
Code:
anisha@linux-uitj:~> ps -el
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0     1     0  0  80   0 -  2018 poll_s ?        00:00:00 init
1 S     0     2     0  0  75  -5 -     0 kthrea ?        00:00:00 kthreadd
1 S     0     3     2  0 -40   - -     0 migrat ?        00:00:00 migration/0
1 S     0     4     2  0  75  -5 -     0 ksofti ?        00:00:09 ksoftirqd/0
....
....
0 S  1000 28488     1  0  80   0 -  3107 wait   ?        00:00:00 firefox
....
0 S  1000 30020     1  0  80   0 - 76885 poll_s ?        00:00:03 okular
....
Code:
anisha@linux-uitj:~> cd /proc
anisha@linux-uitj:/proc> ls
1      17179  17240  1942   2334   26293  28502  44         diskstats    kpagecount     slabinfo
11     17180  17263  1943   2367   2634   28506  471        dma          kpageflags     softirqs
1172   17190  17266  1944   2368   267    29     5          dri          latency_stats  splash
1186   17191  17270  19567  2371   27     3      516        driver       loadavg        stat
12     17194  17426  19570  2373   28367  30     52         execdomains  locks          swaps
1215   17197  18     1960   2374   28368  30020  53         fb           mdstat         sys
13     17198  1811   1982   2377   28369  30493  631        filesystems  meminfo        sysrq-trigger
14     17199  1818   1984   24     28370  3071   645        fs           misc           sysvipc
16     17201  1827   2      24732  28371  31     692        ide          modules        timer_list
1622   17203  1828   20     25     28372  32     9          interrupts   mounts         timer_stats
1629   17205  18597  2016   2509   28373  32371  acpi       iomem        mtrr           tty
1646   17210  18598  2072   2522   28374  32583  asound     ioports      net            uptime
16746  17211  18600  21     2527   28375  33     buddyinfo  irq          pagetypeinfo   version
17071  17213  18604  2118   2572   28376  357    bus        kallsyms     partitions     vmallocinfo
17074  17215  19     22438  2578   28377  38     cmdline    kcore        sched_debug    vmstat
17079  17221  1916   2289   2582   28379  39     config.gz  kdb          schedstat      zoneinfo
17080  17225  1919   2298   26     28380  4      cpuinfo    key-users    scsi
17106  17232  1920   23     26261  28488  43     devices    kmsg         self
 
Old 01-29-2011, 02:03 AM   #6
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.
You can use GDB as a higher-level interface to ptrace() syscall.
For example:
  1. Create couple of files:
    Code:
    # file: eval-on-exit.gdb
    catch syscall exit
    catch syscall exit_group
    commands 1 2         # catchpoints
    shell './script.sh'  # run any program you want
    cont
    end
    
    cont
    Code:
    #!/bin/bash
    # file: script.sh
    # make it executable: chmod +x script.sh
    echo 'End hook started'
  2. Run the process in question if it is not yet. In this example I assume 'gvim' process is running.
  3. Now attach GDB to a running process (gvim here):
    Code:
    gdb -batch -x eval-on-exit.gdb --quiet  --pid=`pidof gvim`

When `gvim' exits (you type :q) `script.sh' will be executed. Here is a test run
Code:
$ gdb -batch -x eval-on-exit.gdb --quiet --pid=`pidof gvim`
[Thread debugging using libthread_db enabled]
0xb7835424 in __kernel_vsyscall ()
Catchpoint 1 (syscall 'exit' [1])
Catchpoint 2 (syscall 'exit_group' [252])

Catchpoint 2 (call to syscall 'exit_group'), 0xb7835424 in __kernel_vsyscall ()
End hook started

Program exited normally.
In my opinion this approach has a number of drawbacks (slow, do not work if SIGINT recieved etc) and simple polling of /proc should be used if you do not need to make some actions just before the process exit.

P.S. Following command allow gdb to attach to a running process without root priviledges (Ubuntu 10.10 and later):
Code:
# echo 0 > /proc/sys/kernel/yama/ptrace_scope

Last edited by firstfire; 01-29-2011 at 02:10 AM.
 
Old 01-30-2011, 06:28 PM   #7
gcubar
LQ Newbie
 
Registered: Jan 2011
Location: Cuba
Distribution: Debian Lenny
Posts: 3

Original Poster
Rep: Reputation: 0
Well, this is an approximation of a possible solution to my question and thanks to their answer I can expose there here. This is the code where I put two variants of notification: through the 'sigaction' and through the 'waitpid' within the cycle.

Any comments or corrections are always welcome.

Code:
#include <errno.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <string.h>

#include <iostream>

extern int errno;

using namespace std;

void sa_sigchld_handler(int signum)
  {
    cout << "*** SIGCHLD" << endl;
  }

int main()
  {
    pid_t childPid = 7817;

    // attach process with pid = childPid
    long rTrace = ptrace(PTRACE_ATTACH, childPid, 0, 0);

    if(rTrace < 0)
      {
        cout << "ERROR #" << errno << ": ";
        cout.flush();
        perror("");
      }
    else
      {
        int exitStatus;
        cout << "Process attached!" << endl;

        // wait for child process change the state
        if(waitpid(childPid, &exitStatus, WNOHANG) > 0)
          {
            bool childStopped = WIFSTOPPED(exitStatus);

            if(childStopped)
              {
                // do the process continue
                rTrace = ptrace(PTRACE_CONT, childPid, 0, 0);
                if(rTrace < 0)
                  {
                    cout << "Don't could continue!" << endl;
                    cout << "ERROR #" << errno << ": ";
                    cout.flush();
                    perror("");
                  }
                else
                  {
                    cout << "Process continues!" << endl;
                  }
              }
          }

        // connect sigaction
        struct sigaction action;
        struct sigaction oldAction;
        memset(&action, 0, sizeof(action));
        action.sa_handler = sa_sigchld_handler;
        action.sa_flags = SA_NOCLDSTOP;
        sigaction(SIGCHLD, &action, &oldAction);

        do {
          if(waitpid(childPid, &exitStatus, WNOHANG) > 0)
            {
              bool crashed = !WIFEXITED(exitStatus);
              int exitCode = WEXITSTATUS(exitStatus);
              int signalCode = WIFSIGNALED(exitStatus);
              int stopSignal = WSTOPSIG(exitStatus);
              cout << "This process dead with exitCode " << exitCode
                  << ", crashed? " << bool(crashed)
                  << ", signaled? " << signalCode
                  << ", stopedSignal? " << stopSignal
                  ;

              break;
            }
          else
            {
              //cout << "Process not deaded!" << endl;
            }
        } while(true);
      }

    return 0;
  }
Thanks any more.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
audio notify thingy, which process is it? KaKaj Fedora 2 12-27-2010 02:49 AM
notify-osd process with acute memory leak? Valvebox Linux - Desktop 1 08-03-2010 02:58 PM
using notify-send ashikahamed Ubuntu 0 05-02-2008 06:09 AM
Would you notify the BSA scott_R General 17 11-24-2003 01:11 AM
Notify No Nezar Linux - Networking 0 08-05-2001 03:20 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:49 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration