summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2017-07-13 16:44:37 +0300
committerDmitry Kozlov <xeb@mail.ru>2017-07-13 16:45:24 +0300
commit02b089165e54ac7600fa526c5881913f6b478a84 (patch)
tree2d643da9cae68da63b790564760550caaba1e2be
parente18b4071237c4772c71b36572b618beae6fc51ed (diff)
downloadaccel-ppp-02b089165e54ac7600fa526c5881913f6b478a84.tar.gz
accel-ppp-02b089165e54ac7600fa526c5881913f6b478a84.zip
improved SIGSEGV handler
-rw-r--r--accel-pppd/main.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/accel-pppd/main.c b/accel-pppd/main.c
index 02ada1d1..0f85c771 100644
--- a/accel-pppd/main.c
+++ b/accel-pppd/main.c
@@ -169,53 +169,55 @@ void core_restart(int soft)
static void sigsegv(int num)
{
- char cmd[PATH_MAX];
- char fname[128];
+ char cmd[128];
+ char dump[128];
char exec_file[PATH_MAX];
- struct rlimit lim;
pid_t pid;
- int status;
+ FILE *f;
+ int fd;
+ char pid_str[16];
+ unsigned int t;
pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
if (conf_dump) {
- FILE *f;
- unsigned int t = time(NULL);
-
+ t = time(NULL);
+ sprintf(pid_str, "%u", getpid());
+ sprintf(cmd, "cmd-%u", t);
chdir(conf_dump);
- sprintf(fname, "cmd-%u", t);
- f = fopen(fname, "w");
+ pid = fork();
+ if (pid == 0) {
+ printf("starting gdb...\n");
+ sprintf(dump, "dump-%u", t);
+ fd = open(dump, O_CREAT|O_TRUNC|O_WRONLY,0600);
+ if (fd == -1)
+ _exit(0);
+
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ close(fd);
+
+ f = fopen(cmd, "w");
if (!f)
- goto out;
- fprintf(f, "thread apply all bt full\ndetach\nquit\n");
+ _exit(0);
+ fprintf(f, "info shared\nthread apply all bt full\ngenerate-core-file core-%u\ndetach\nquit\n", t);
fclose(f);
- sprintf(exec_file, "/proc/%u/exe", getpid());
+ sprintf(exec_file, "/proc/%s/exe", pid_str);
readlink(exec_file, exec_file, PATH_MAX);
- sprintf(cmd, "gdb -x %s %s %d > dump-%u", fname, exec_file, getpid(), t);
-
- system(cmd);
-
- unlink(fname);
- }
-
-out:
- pid = fork();
- if (pid) {
- waitpid(pid, &status, 0);
- __core_restart(1);
- }
+ execlp("gdb", "gdb", "-x", cmd, exec_file, pid_str, NULL);
+ perror("exec");
+ _exit(0);
+ }
- if (conf_dump) {
- lim.rlim_cur = RLIM_INFINITY;
- lim.rlim_max = RLIM_INFINITY;
+ printf("waitpid: %i\n", waitpid(pid, NULL, 0));
- setrlimit(RLIMIT_CORE, &lim);
+ unlink(cmd);
}
- abort();
+ __core_restart(1);
}
static void shutdown_cb()