#define GDBHOOK_DEBUGGER "gdb" #define GDBHOOK_MODE "GDBHOOK_MODE" #define GDBHOOK_BELL_COUNT "GDBHOOK_BELL_COUNT" #define GDBHOOK_STD_BELL_COUNT 4 #define GDBHOOK_STDPREFIX "sig-hook" #define GDBHOOK_WAIT "GDBHOOK_WAIT" #define GDBHOOK_STD_WAIT 4 static int DbghWaitProc(char const * pszFileName); static void DbghSigHandler(int iSignal); static int DbghCleanupFiles(char const * pszPath); static char szProgram[256] = "", szPath[256] = ""; static int DbghWaitProc(char const * pszFileName) { char const * pszBellCnt = getenv(GDBHOOK_BELL_COUNT); int iBellCnt = (pszBellCnt != NULL) ? atoi(pszBellCnt): GDBHOOK_STD_BELL_COUNT; char const * pszWait = getenv(GDBHOOK_WAIT); int iWait = (pszWait != NULL) ? atoi(pszWait): GDBHOOK_STD_WAIT; volatile int iLoop = 0; while (!iLoop && (access(pszFileName, F_OK) == 0)) { if (iBellCnt > 0) fprintf(stderr, "%c", 7), --iBellCnt; sleep(iWait); } return (0); } static void DbghSigHandler(int iSignal) { char const * pszEnvVar = getenv(GDBHOOK_MODE); if ((pszEnvVar != NULL) && atoi(pszEnvVar)) { char szDbgFile[256] = ""; sprintf(szDbgFile, "%s%s.%d.%u.hook", szPath, GDBHOOK_STDPREFIX, iSignal, getpid()); FILE * pFile = fopen(szDbgFile, "w"); if (pFile != NULL) { time_t tFault = time(NULL); #ifdef SOLARIS fprintf(pFile, "#!/bin/sh\n" "#\n" "# Signal = %s (%d)\n" "# Time = %s" "# Pid = %u\n" "#\n" "%s %s %u\n\n", (iSignal < _sys_nsig) ? _sys_siglist[iSignal]: "????", iSignal, ctime(&tFault), getpid(), GDBHOOK_DEBUGGER, szProgram, getpid()); #else // #ifdef SOLARIS fprintf(pFile, "#!/bin/sh\n" "#\n" "# Signal = %s (%d)\n" "# Time = %s" "# Pid = %u\n" "#\n" "%s %s %u\n\n", (iSignal < _NSIG) ? _sys_siglist[iSignal]: "????", iSignal, ctime(&tFault), getpid(), GDBHOOK_DEBUGGER, szProgram, getpid()); #endif // #ifdef SOLARIS fclose(pFile); chmod(szDbgFile, 0755); DbghWaitProc(szDbgFile); signal(iSignal, SIG_DFL); } } else signal(iSignal, SIG_DFL); } static int DbghCleanupFiles(char const * pszPath) { glob_t globbuf; char szPattern[256] = ""; sprintf(szPattern, "%s*.hook", pszPath); if (glob(szPattern, 0, NULL, &globbuf) == 0) { for (int ii = 0; ii < globbuf.gl_pathc; ii++) unlink(globbuf.gl_pathv[ii]); } globfree(&globbuf); return (0); } int DbghInit(char const * pszProgram) { strcpy(szProgram, pszProgram); char const * pszSlash = strrchr(pszProgram, '/'); if (pszSlash != NULL) { int iPathLength = (int) (pszSlash - pszProgram) + 1; strncpy(szPath, pszProgram, iPathLength); szPath[iPathLength] = '\0'; } else strcpy(szPath, "./"); if (DbghCleanupFiles(szPath) < 0) return (-1); return (0); } int DbghInstall(void) { signal(SIGSEGV, DbghSigHandler); signal(SIGBUS, DbghSigHandler); signal(SIGFPE, DbghSigHandler); #ifdef LINUX signal(SIGSTKFLT, DbghSigHandler); #endif // #ifdef LINUX signal(SIGABRT, DbghSigHandler); return (0); } int DbghWaitPoint(char const * pszName) { char const * pszEnvVar = getenv(GDBHOOK_MODE); if ((pszEnvVar != NULL) && atoi(pszEnvVar)) { char szDbgFile[256] = ""; sprintf(szDbgFile, "%s%s.%u.hook", szPath, pszName, getpid()); FILE * pFile = fopen(szDbgFile, "w"); if (pFile != NULL) { time_t tFault = time(NULL); fprintf(pFile, "#!/bin/sh\n" "#\n" "# Time = %s" "# Pid = %u\n" "#\n" "%s %s %u\n\n", ctime(&tFault), getpid(), GDBHOOK_DEBUGGER, szProgram, getpid()); fclose(pFile); chmod(szDbgFile, 0755); DbghWaitProc(szDbgFile); } } return (0); } int DbghCleanup(void) { return (0); }