|
0
|
1 |
#include <sys/time.h>
|
|
|
2 |
#include <stdio.h>
|
|
|
3 |
#include <stdlib.h>
|
|
|
4 |
#include <sys/mman.h>
|
|
|
5 |
#include <semaphore.h>
|
|
|
6 |
#include <sys/types.h>
|
|
|
7 |
#include <signal.h>
|
|
|
8 |
#include <execinfo.h>
|
|
|
9 |
#include <string.h>
|
|
|
10 |
#include <unistd.h>
|
|
|
11 |
#include <sys/wait.h>
|
|
|
12 |
#include "Debug.h"
|
|
|
13 |
#define ERR(e) perror(e), kill(0, SIGTERM), exit(EXIT_FAILURE)
|
|
|
14 |
|
|
|
15 |
// independent utility staff
|
|
|
16 |
|
|
|
17 |
int DebugC::debug = 0;
|
|
|
18 |
char *DebugC::prg_name;
|
|
|
19 |
long int DebugC::t0;
|
|
|
20 |
sem_t *DebugC::semP;
|
|
|
21 |
|
|
|
22 |
void DebugC::deb(int level) {
|
|
|
23 |
if (debug >= level) {
|
|
|
24 |
if(sem_wait(semP)< 0) ERR("LOG sem_wait");
|
|
|
25 |
struct timeval t;
|
|
|
26 |
gettimeofday(&t, NULL);
|
|
|
27 |
fprintf(stderr, "%09ld %s: %s\n", 1000000*t.tv_sec+t.tv_usec-t0, debid, s);
|
|
|
28 |
fflush(stderr);
|
|
|
29 |
if(sem_post(semP) < 0) ERR("LOG sem_post");
|
|
|
30 |
}
|
|
|
31 |
}
|
|
|
32 |
void DebugC::back_trace() {
|
|
|
33 |
if(sem_wait(semP)< 0) ERR("LOG sem_wait");
|
|
|
34 |
|
|
|
35 |
int j, nptrs;
|
|
|
36 |
void *buffer[24];
|
|
|
37 |
char **strings;
|
|
|
38 |
|
|
|
39 |
nptrs = backtrace(buffer, 24);
|
|
|
40 |
|
|
|
41 |
strings = backtrace_symbols(buffer, nptrs);
|
|
|
42 |
if (strings == NULL) {
|
|
|
43 |
ERR("ABORT backtrace_symbols");
|
|
|
44 |
exit(EXIT_FAILURE);
|
|
|
45 |
}
|
|
|
46 |
|
|
|
47 |
char shcmd[] = "sed -e 's/.*\\[\\(.*\\)\\]$/\\1/' | addr2line -fspe ";
|
|
|
48 |
char *cmdbuf = (char*)malloc(sizeof(shcmd) + 64);
|
|
|
49 |
strcpy(cmdbuf, shcmd);
|
|
|
50 |
strcat(cmdbuf, prg_name);
|
|
|
51 |
#define SIZE 640
|
|
|
52 |
char *resbuf = (char*)malloc(SIZE);;
|
|
|
53 |
for(j = 0; j < nptrs; j++) {
|
|
|
54 |
int pc[2], po[2];
|
|
|
55 |
if(pipe(pc) < 0) ERR("ABORT pipe");
|
|
|
56 |
if(pipe(po) < 0) ERR("ABORT pipe");
|
|
|
57 |
if(!fork()) {
|
|
|
58 |
close(po[0]); dup2(po[1],1);
|
|
|
59 |
close(pc[1]); dup2(pc[0],0);
|
|
|
60 |
execl("/bin/bash", "/bin/bash", "-c", cmdbuf, (char *) NULL);
|
|
|
61 |
}
|
|
|
62 |
if(write(pc[1], strings[j], strlen(strings[j])) < 0) ERR("ABORT write pipe");
|
|
|
63 |
if(write(pc[1], "\n", 1) < 0) ERR("ABORT write pipe");
|
|
|
64 |
close(pc[1]);
|
|
|
65 |
memset(resbuf, 0, SIZE);
|
|
|
66 |
if(read(po[0], resbuf, SIZE)) fprintf(stderr, "%s", resbuf);
|
|
|
67 |
for(int i = 0; i < 2; i++) close(po[i]), close(pc[i]);
|
|
|
68 |
}
|
|
|
69 |
if(sem_post(semP)< 0) ERR("LOG sem_post");
|
|
|
70 |
free(strings); free(cmdbuf); free(resbuf);
|
|
|
71 |
}
|
|
|
72 |
void DebugC::debug_init(char *prgname) {
|
|
|
73 |
struct timeval t;
|
|
|
74 |
DebugC::prg_name = prgname;
|
|
|
75 |
gettimeofday(&t, NULL);
|
|
|
76 |
DebugC::t0 = 1000000*t.tv_sec+t.tv_usec;
|
|
|
77 |
if((DebugC::semP = (sem_t*)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)) < 0) ERR("mmap");
|
|
|
78 |
if(sem_init(DebugC::semP, 1, 1) < 0) ERR("LOG sem_init");
|
|
|
79 |
}
|
|
|
80 |
|