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