3

In case of crash we dump the stack to get more information about the crash using below function:

static void dumpStack()
    {
        char buf[64];

        pid_t pid = getpid();

        sprintf( buf, "%d", pid );

        pid_t fork_result = vfork();

        int status;

        if( fork_result == 0 )

            execlp( "pstack", "pstack", buf, NULL );

        else if( fork_result > 0 )

            waitpid( fork_result, &status, 0 );

        else

            std::cerr << "vfork failed with err=%s" << strerror( errno ) << std::endl;
    }

in above code the parent stuck at waitPid forever. I checked the status of child process it became zombie:

Deepak@linuxPC:~$ ps aux | grep  21054

    700048982 21054 0.0  0.0      0     0 pts/0    Z+   03:01   0:00 [pstack] <defunct>

Also the stack printed by the child is also not complete. It just prints a single line and exits.

#0  0x00007f61cb48d26e in waitpid () from /lib64/libpthread.so.0

Not sure why parent is not able to reap the process.

Can you please help if i am missing anything here

Euler
  • 652
  • 3
  • 11
  • 24
  • You mean in case of parent process crash? How this function is going to be invoked? – user7860670 Sep 13 '19 at 07:53
  • 2
    Please provide a full [mcve] that can be copied and compiled as-is that demonstrates the problem, not just a single isolated function. – Shawn Sep 13 '19 at 07:55
  • 1
    Are you calling this function from a signal handler? Note that `vfork` is not [listed](http://man7.org/linux/man-pages/man7/signal-safety.7.html) as signal safe, and neither is `execlp`. You could probably use the Linux-specific [`backtrace`](http://man7.org/linux/man-pages/man3/backtrace.3.html) funciton but it's not listed as signal safe *either* (but has been used in signals examples elsewhere, like [this one](https://stackoverflow.com/questions/77005/how-to-automatically-generate-a-stacktrace-when-my-program-crashes)). – Some programmer dude Sep 13 '19 at 09:03
  • Avoid using [vfork](https://dwheeler.com/secure-programs/Secure-Programs-HOWTO/avoid-vfork.html), imho never use it – Soner from The Ottoman Empire Sep 13 '19 at 09:10

1 Answers1

0

First of all, you may be better off using the backtrace() function, see How to automatically generate a stacktrace when my program crashes

As for your code, if you are on 64-bit Linux (likely), pstack will not work. For me, it segfaulted. Furthermore, I agree with the comments on vfork() and execlp(). Also, you may need to execute your program as root. The code below works for me (prints parent's stack, but not sure that is very useful):

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <iostream>
#include <system_error>

using std::cout;

static void dumpStack() {
  char buf[64];
  pid_t result;
  pid_t pid = getpid();
  sprintf(buf, "/proc/%d/stack", pid );
  //cout << buf << '\n';                                                                                                         
  pid_t fork_result = vfork();
  int status;
  if( fork_result == 0 ) {
    //execlp( "pstack", "pstack", buf, NULL );                                                                                   
    cout << "Child before execlp\n";
    execlp("cat", "cat", buf, NULL);
    cout << "Child after execlp\n";  // Will not print, of course
  } else if( fork_result > 0 ) {
    result = waitpid( fork_result, &status, 0 );
    if (result < 0) {
      throw std::system_error(errno, std::generic_category());
    }
  } else {
    std::cerr << "vfork failed with err=%s" << strerror( errno ) << std::endl;
  }
  cout << std::endl;
}

int main() {
  dumpStack();

  return 0;
}
Erik Alapää
  • 2,585
  • 1
  • 14
  • 25