es.po update by rafa, add ms win10 cygwin port, add pulseaudio, new config flags...
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcsignals.C
index ed50cfb15d9e8ac38c630c3096c9ab2b77fce477..ffc8a1c156d4062adb38c80846620cb2f9e00080 100644 (file)
 #include "bckeyboard.h"
 #include "bcresources.h"
 #include "cstrdup.h"
+#include "filesystem.h"
 
 #include <ctype.h>
 #include <dirent.h>
+#ifndef NO_BTRACE
 #include <execinfo.h>
+#endif
 #include <fcntl.h>
 #include <pwd.h>
 #include <stdio.h>
@@ -37,7 +40,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
+#ifndef NO_PRCTL
 #include <sys/prctl.h>
+#endif
 #include <sys/types.h>
 
 BC_Signals* BC_Signals::global_signals = 0;
@@ -182,6 +187,7 @@ static const char* signal_titles[] =
 
 void BC_Signals::dump_stack(FILE *fp)
 {
+#ifndef NO_BTRACE
        void *buffer[256];
        int total = backtrace (buffer, 256);
        char **result = backtrace_symbols (buffer, total);
@@ -190,6 +196,7 @@ void BC_Signals::dump_stack(FILE *fp)
        {
                fprintf(fp, "%s\n", result[i]);
        }
+#endif
 }
 
 // Kill subprocesses
@@ -270,15 +277,18 @@ static void signal_entry_recoverable(int signum)
                getpid());
 }
 
+#ifndef NO_PRCTL
 // used to terminate child processes when program terminates
 static void handle_exit(int signum)
 {
 //printf("child %d exit\n", getpid());
        exit(0);
 }
+#endif
 
 void BC_Signals::set_sighup_exit(int enable)
 {
+#ifndef NO_PRCTL
        if( enable ) {
 // causes SIGHUP to be generated when parent dies
                signal(SIGHUP, handle_exit);
@@ -291,6 +301,7 @@ void BC_Signals::set_sighup_exit(int enable)
                signal(SIGHUP, signal_entry);
                prctl(PR_SET_PDEATHSIG, 0,0,0,0);
        }
+#endif
 }
 
 BC_Signals::BC_Signals()
@@ -379,20 +390,93 @@ const char* BC_Signals::sig_to_str(int number)
 }
 
 
+#ifndef NO_CTX
 #include <ucontext.h>
 #include <sys/wait.h>
 #include "thread.h"
 
 #if __i386__
 #define IP eip
+#define sigregs_t sigcontext
+
+static void reg_dump(FILE *fp,sigregs_t *rp)
+{
+       fprintf(fp,"REGS:\n");
+       fprintf(fp,"  gs: %04x:%04x\n", rp->gs,rp->__gsh);
+       fprintf(fp,"  fs: %04x:%04x\n", rp->fs,rp->__fsh);
+       fprintf(fp,"  es: %04x:%04x\n", rp->es,rp->__esh);
+       fprintf(fp,"  ds: %04x:%04x\n", rp->ds,rp->__dsh);
+       fprintf(fp," edi: %14p %d\n", (void*)rp->edi,rp->edi);
+       fprintf(fp," esi: %14p %d\n", (void*)rp->esi,rp->esi);
+       fprintf(fp," ebp: %14p %d\n", (void*)rp->ebp,rp->ebp);
+       fprintf(fp," esp: %14p %d\n", (void*)rp->esp,rp->esp);
+       fprintf(fp," ebx: %14p %d\n", (void*)rp->ebx,rp->ebx);
+       fprintf(fp," edx: %14p %d\n", (void*)rp->edx,rp->edx);
+       fprintf(fp," ecx: %14p %d\n", (void*)rp->ecx,rp->ecx);
+       fprintf(fp," eax: %14p %d\n", (void*)rp->eax,rp->eax);
+       fprintf(fp," trapno: %14p %d\n", (void*)rp->trapno,rp->trapno);
+       fprintf(fp," err: %14p %d\n", (void*)rp->err,rp->err);
+       fprintf(fp," eip: %14p %d\n", (void*)rp->eip,rp->eip);
+       fprintf(fp," cs: %04xd : %04x\n", rp->cs,rp->__csh);
+       fprintf(fp," eflags: %14p %d\n", (void*)rp->eflags,rp->eflags);
+       fprintf(fp," esp_at_signal: %p %d\n", (void*)rp->esp_at_signal,rp->esp_at_signal);
+       fprintf(fp," ss: %04xd : %04x\n", rp->ss,rp->__ssh);
+       fprintf(fp," oldmask: %14p %d\n", (void*)rp->oldmask,rp->oldmask);
+       fprintf(fp," cr2: %14p %d\n", (void*)rp->cr2,rp->cr2);
+       fprintf(fp,"\n");
+}
 #endif
+
 #if __x86_64__
 #define IP rip
+#define sigregs_t sigcontext
+
+static void reg_dump(FILE *fp,sigregs_t *rp)
+{
+       fprintf(fp,"REGS:\n");
+       fprintf(fp,"  r8: %20p %jd\n", (void*)rp->r8,rp->r8);
+       fprintf(fp,"  r9: %20p %jd\n", (void*)rp->r9,rp->r9);
+       fprintf(fp," r10: %20p %jd\n", (void*)rp->r10,rp->r10);
+       fprintf(fp," r11: %20p %jd\n", (void*)rp->r11,rp->r11);
+       fprintf(fp," r12: %20p %jd\n", (void*)rp->r12,rp->r12);
+       fprintf(fp," r13: %20p %jd\n", (void*)rp->r13,rp->r13);
+       fprintf(fp," r14: %20p %jd\n", (void*)rp->r14,rp->r14);
+       fprintf(fp," r15: %20p %jd\n", (void*)rp->r15,rp->r15);
+       fprintf(fp," rdi: %20p %jd\n", (void*)rp->rdi,rp->rdi);
+       fprintf(fp," rsi: %20p %jd\n", (void*)rp->rsi,rp->rsi);
+       fprintf(fp," rbp: %20p %jd\n", (void*)rp->rbp,rp->rbp);
+       fprintf(fp," rbx: %20p %jd\n", (void*)rp->rbx,rp->rbx);
+       fprintf(fp," rdx: %20p %jd\n", (void*)rp->rdx,rp->rdx);
+       fprintf(fp," rax: %20p %jd\n", (void*)rp->rax,rp->rax);
+       fprintf(fp," rcx: %20p %jd\n", (void*)rp->rcx,rp->rcx);
+       fprintf(fp," rsp: %20p %jd\n", (void*)rp->rsp,rp->rsp);
+       fprintf(fp," rip: %20p %jd\n", (void*)rp->rip,rp->rip);
+       fprintf(fp," eflags: %14p %jd\n", (void*)rp->eflags,rp->eflags);
+       fprintf(fp,"  cs: %04x\n", rp->cs);
+       fprintf(fp,"  gs: %04x\n", rp->gs);
+       fprintf(fp,"  fs: %04x\n", rp->fs);
+       fprintf(fp," err: %20p %jd\n", (void*)rp->err,rp->err);
+       fprintf(fp," trapno: %20p %jd\n", (void*)rp->trapno,rp->trapno);
+       fprintf(fp," oldmask: %20p %jd\n", (void*)rp->oldmask,rp->oldmask);
+       fprintf(fp," cr2: %20p %jd\n", (void*)rp->cr2,rp->cr2);
+       fprintf(fp,"\n");
+}
+
+#endif
+
+#if __powerpc__ || __powerpc64__ || __powerpc64le__
+#include <asm/ptrace.h>
+#define IP nip
+#define sigregs_t pt_regs
+static void reg_dump(FILE *fp,sigregs_t *rp) {}
 #endif
+
 #ifndef IP
 #error gotta have IP
 #endif
 
+// HAVE_CTX
+#endif
 
 static void handle_dump(int n, siginfo_t * info, void *sc)
 {
@@ -404,13 +488,16 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
 // it is not necessary to be root if ptrace is allowed via:
 // echo 0 > /proc/sys/kernel/yama/ptrace_scope (usually set to 1)
 //     if( uid != 0 ) return;
-       ucontext_t *uc = (ucontext_t *)sc;
        int pid = getpid(), tid = gettid();
-       struct sigcontext *c = (struct sigcontext *)&uc->uc_mcontext;
-       uint8_t *ip = (uint8_t *)c->IP;
+       void *ip = 0;
+#ifndef NO_CTX
+       ucontext_t *uc = (ucontext_t *)sc;
+       struct sigregs_t *c = (struct sigregs_t *)&uc->uc_mcontext;
+       ip = (void *)c->IP;
+#endif
        fprintf(stderr,"** %s at %p in pid %d, tid %d\n",
                n==SIGSEGV? "segv" : n==SIGINT? "intr" : "trap",
-               (void*)ip, pid, tid);
+               ip, pid, tid);
        FILE *fp = 0;
        char fn[PATH_MAX];
        if( BC_Signals::trap_path ) {
@@ -421,7 +508,7 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
                fprintf(stderr,"writing debug data to %s\n", fn);
                fprintf(fp,"** %s at %p in pid %d, tid %d\n",
                        n==SIGSEGV? "segv" : n==SIGINT? "intr" : "trap",
-                       (void*)c->IP, pid, tid);
+                       ip, pid, tid);
        }
        else {
                strcpy(fn, "stdout");
@@ -434,6 +521,7 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
                fprintf(fp,"        by %d:%d %s(%s)\n",
                        pw->pw_uid, pw->pw_gid, pw->pw_name, pw->pw_gecos);
        }
+       fprintf(fp,"\nOS:\n");  bc_copy_textfile(16, fp,"/etc/os-release");
        fprintf(fp,"\nCPUS: %d\n",   BC_Resources::get_machine_cpus());
        fprintf(fp,"\nCPUINFO:\n");  bc_copy_textfile(32, fp,"/proc/cpuinfo");
        fprintf(fp,"\nTHREADS:\n");  BC_Trace::dump_threads(fp);
@@ -450,6 +538,7 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
        fprintf(fp,"\nSTATUS:\n");   bc_copy_textfile(INT_MAX, fp,"/proc/%d/status",pid);
        fprintf(fp,"\nFD:\n");       bc_list_openfiles(INT_MAX, fp,"/proc/%d/fd", pid);
        fprintf(fp,"\nMAPS:\n");     bc_copy_textfile(INT_MAX, fp,"/proc/%d/maps",pid);
+#ifndef NO_CTX
        char proc_mem[64];
        if( tid > 0 && tid != pid )
                sprintf(proc_mem,"/proc/%d/task/%d/mem",pid,tid);
@@ -459,7 +548,7 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
        if( pfd >= 0 ) {
                fprintf(fp,"\nCODE:\n");
                for( int i=-32; i<32; ) {
-                       uint8_t v;  void *vp = (void *)(ip + i);
+                       uint8_t v;  void *vp = (void *)((char*)ip + i);
                        if( !(i & 7) ) fprintf(fp,"%p:  ", vp);
                        if( pread(pfd,&v,sizeof(v),(off_t)vp) != sizeof(v) ) break;
                        fprintf(fp,"%c%02x", !i ? '>' : ' ', v);
@@ -470,9 +559,11 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
        }
        else
                fprintf(fp,"err opening: %s, %m\n", proc_mem);
-
+       reg_dump(fp, c);
+#endif
        fprintf(fp,"\n\n");
        if( fp != stdout ) fclose(fp);
+#ifndef NO_GDB
        char cmd[1024], *cp = cmd;
        cp += sprintf(cp, "exec gdb /proc/%d/exe -p %d --batch --quiet "
                "-ex \"thread apply all info registers\" "
@@ -494,5 +585,6 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
        }
         char *const argv[4] = { (char*) "/bin/sh", (char*) "-c", cmd, 0 };
         execvp(argv[0], &argv[0]);
+#endif
 }