Domanda

"No functions registered by atexit() in the calling process image are registered in the new process image".

Here is code:

pid = fork();
if (pid == 0) {
    atexit(check_mem);
    return execv(...);
}

check_mem function not getting called after execv(). Because of above "line". Any hacks to get the function registered after execv call ??

Thanks in advance for your help.

È stato utile?

Soluzione

The perfect solution is using ptrace() as below :

pid = fork();
if (pid == 0) {
    ptrace(PTRACE_TRACEME, 0, 0, 0);
    return execve(...);
}

wait(NULL);
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACEEXIT);
ptrace(PTRACE_CONT, pid, 0, (void*)0);

    while(1){
    waitpid(pid, &status, 0);
    if((WSTOPSIG(status) == SIGTRAP) && (status & (PTRACE_EVENT_EXIT << 8)))
        break;

    ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
}

check_mem();

ptrace(PTRACE_CONT, pid, 0, 0);

Acknowledgments : www.wienand.org/junkcode/linux/stopper.c

Altri suggerimenti

atexit handlers will not execute when you exec* something.

execv replaces the current process image, including any atexit handlers you've registered, so there's really not a lot you can do - your code is gone.

A little tricky but doable - create a shared library (let's call it check_mem.so) with a a function like so:

__attribute__((constructor)) void runs_first(void) {
  atexit(check_mem);
};

Note that check_mem needs to be defined in the library, not your program.

Now in execve, put LD_PRELOAD=/path/to/check_mem.so into the environment variables passed to the program (last argument to execve).

What will happen is that when the new program will run it will load the your check_mem library and run the runs_first function before (almost) every other code.

It will only work if the program you are execve'ing is dynamically linked, but AFAIK that is the only limitation.

EDIT: as comment rightfully stated, it wont work on setuid programs either. I still think there is a good chance it'll cover your use case though.

Like nos said, exec replaces your process. You might try using < stdlib.h >'s int system (char *s) function instead to start a program with args. Unlike execve, system returns when the spawned process exits, e.g.

pid = fork();
if (pid == 0) {
    atexit(check_mem);
    system ("program arg1 arg2 ...");
    exit (0); /* Calls atexit handlers. */
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top