CScpp/Debug.cpp
changeset 0 5c129dd80d4f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CScpp/Debug.cpp	Thu Nov 21 14:55:10 2019 +0100
@@ -0,0 +1,80 @@
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <semaphore.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <execinfo.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include "Debug.h"
+#define ERR(e) perror(e), kill(0, SIGTERM), exit(EXIT_FAILURE)
+
+// independent utility staff
+
+int DebugC::debug = 0;
+char *DebugC::prg_name;
+long int DebugC::t0;
+sem_t *DebugC::semP;
+
+void DebugC::deb(int level) {
+	if (debug >= level) {
+		if(sem_wait(semP)< 0) ERR("LOG sem_wait");
+		struct timeval t;
+		gettimeofday(&t, NULL);
+		fprintf(stderr, "%09ld %s: %s\n", 1000000*t.tv_sec+t.tv_usec-t0, debid, s);
+		fflush(stderr);
+		if(sem_post(semP) < 0) ERR("LOG sem_post");
+	}
+}
+void DebugC::back_trace() {
+	if(sem_wait(semP)< 0) ERR("LOG sem_wait");
+
+   int j, nptrs;
+   void *buffer[24];
+   char **strings;
+
+   nptrs = backtrace(buffer, 24);
+
+   strings = backtrace_symbols(buffer, nptrs);
+   if (strings == NULL) {
+       ERR("ABORT backtrace_symbols");
+       exit(EXIT_FAILURE);
+   }
+
+   char shcmd[] = "sed -e 's/.*\\[\\(.*\\)\\]$/\\1/' | addr2line -fspe ";
+   char *cmdbuf = (char*)malloc(sizeof(shcmd) + 64);
+   strcpy(cmdbuf, shcmd);
+   strcat(cmdbuf, prg_name);
+	#define SIZE 640
+   char *resbuf = (char*)malloc(SIZE);;
+   for(j = 0; j < nptrs; j++) {
+   	int pc[2], po[2];
+   	if(pipe(pc) < 0) ERR("ABORT pipe");
+   	if(pipe(po) < 0) ERR("ABORT pipe");
+   	if(!fork()) {
+   		close(po[0]); dup2(po[1],1);
+   		close(pc[1]); dup2(pc[0],0);
+   		execl("/bin/bash", "/bin/bash", "-c", cmdbuf, (char *) NULL);
+   	}
+		if(write(pc[1], strings[j], strlen(strings[j])) < 0) ERR("ABORT write pipe");
+		if(write(pc[1], "\n", 1) < 0) ERR("ABORT write pipe");
+		close(pc[1]);
+		memset(resbuf, 0, SIZE);
+		if(read(po[0], resbuf, SIZE)) fprintf(stderr, "%s", resbuf);
+		for(int i = 0; i < 2; i++) close(po[i]), close(pc[i]);
+   }
+	if(sem_post(semP)< 0) ERR("LOG sem_post");
+   free(strings); free(cmdbuf); free(resbuf);
+}
+void DebugC::debug_init(char *prgname) {
+	struct timeval t;
+	DebugC::prg_name = prgname;
+	gettimeofday(&t, NULL);
+	DebugC::t0 = 1000000*t.tv_sec+t.tv_usec;
+	if((DebugC::semP = (sem_t*)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)) < 0) ERR("mmap");
+	if(sem_init(DebugC::semP, 1, 1) < 0) ERR("LOG sem_init");
+}
+