运行异常监控

 

只有非windows才启作用.linux异常监控

1 #ifndef ABTOR_WINDOWS
2     initLinuxDump(logdir.c_str());
3 #endif

 

 

  1 #pragma once
  2 
  3 #ifndef ABTOR_WINDOWS
  4 
  5 #include<stdio.h>
  6 #include<string.h>
  7 #include<stdlib.h>
  8 #include <signal.h>
  9 #include <execinfo.h>
 10 
 11 #include<sys/types.h>
 12 #include<unistd.h>
 13 #include<fcntl.h>
 14 
 15 #include <pthread.h>
 16 #include <sys/types.h>
 17 #include <sys/syscall.h>
 18 #include <string.h>
 19 
 20 static int _core_dump_signals[] = {
 21     /*SIGABRT,*/SIGFPE, SIGILL, SIGQUIT, SIGSEGV,
 22     SIGTRAP, SIGSYS, SIGBUS, SIGXCPU, SIGXFSZ
 23 #ifdef SIGEMT
 24     ,SIGEMT
 25 #endif
 26 };
 27 
 28 static char g_log_dir[1024] = {0};
 29 
 30 
 31 
 32 struct flock* file_lock(short type, short whence)
 33 {
 34     static struct flock ret ;
 35     ret.l_type = type ;
 36     ret.l_start = 0 ;
 37     ret.l_whence = whence ;
 38     ret.l_len = 0 ;
 39     ret.l_pid = getpid() ;
 40     return &ret ;
 41 }
 42 
 43 void saveBackTrace(int signalno)
 44 {
 45 
 46     char logFile[1024] = {0};
 47     FILE* fLog = NULL;
 48     sprintf(logFile,"%s/core.dump",g_log_dir);
 49     fLog = fopen(logFile,"w+");
 50     if(fLog == NULL)
 51     {
 52         return;
 53     }
 54     int fd = fileno(fLog);
 55     fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
 56 
 57     char buffer[4096] = {0};
 58     int count = readlink("/proc/self/exe", buffer, 4096);
 59     if(count > 0)
 60     {
 61         buffer[count] = '\n';
 62         buffer[count + 1] = 0;
 63         fwrite(buffer, 1, count + 1, fLog);
 64         fflush(fLog);
 65     }
 66 
 67 
 68 //#记录捕捉到的信号
 69     strcpy(buffer, "Catch signal: ");
 70     printf("Catch signal:%d\n",signalno);
 71     fflush(stdout);
 72     switch (signalno)
 73     {
 74         case SIGSEGV: strcat(buffer, "SIGSEGV\n");
 75             break;
 76         case SIGILL: strcat(buffer, "SIGILL\n");
 77             break;
 78         case SIGFPE: strcat(buffer, "SIGFPE\n");
 79             break;
 80         case SIGABRT: strcat(buffer, "SIGABRT\n");
 81             break;
 82         case SIGTERM: strcat(buffer, "SIGTERM\n");
 83             break;
 84         case SIGKILL: strcat(buffer, "SIGKILL\n");
 85             break;
 86         case SIGXFSZ: strcat(buffer, "SIGXFSZ\n");
 87 
 88             break;
 89         default: sprintf(buffer, "Catch signal: %d\n", signalno);
 90             break;
 91     }
 92     fwrite(buffer, 1, strlen(buffer), fLog);
 93     fflush(fLog);
 94 
 95 //#打印一些全局变量。去掉这个信息的打印,因为每个crash的thread id号都不一样,不方便判断crash是否一样。
 96     printf("thread lwpid: %u\n", syscall(SYS_gettid));
 97 //    sprintf(buffer, "thread lwpid: %u\n", syscall(SYS_gettid));
 98 //    fwrite(buffer, 1, strlen(buffer), fLog);
 99 //    fflush(fLog);
100 //    sprintf(buffer, "thread tid: %u\n", pthread_self());
101     printf("thread tid: %u\n", pthread_self());
102 //    fwrite(buffer, 1, strlen(buffer), fLog);
103 //    fflush(fLog);
104 
105     printf("1\n");
106     fflush(stdout);
107 //#打印堆栈信息
108     void* DumpArray[256];
109     int nSize = backtrace(DumpArray, 256);
110     char** symbols = backtrace_symbols(DumpArray, nSize);
111     printf("DumpArraySize:%d symbols:%p\n",nSize,symbols);
112     if (symbols)
113     {
114         if (nSize > 256)
115         {
116             nSize = 256;
117         }
118         if (nSize > 0)
119         {
120 #if 0
121             //定位源代码行
122             char cmd[264] = "addr2line -f -e ";
123             char buff1[256] = { 0 }, buff2[1024] = { 0 }, buff3[256] = { 0 };
124             char* prog = cmd + 16;
125             readlink("/proc/self/exe", prog, sizeof(cmd) - (prog-cmd)-1);// 获取进程的完整路径
126             int leftlen = strlen(cmd);
127             prog = cmd + leftlen;
128             leftlen = 263 - leftlen;
129             for (size_t i = 0; i < nSize; ++i)
130             {
131                 snprintf(prog, leftlen, " %p\n", DumpArray[i]);
132 
133                 FILE* fp = popen(cmd, "r");
134                 if (fp != NULL)
135                 {
136                     if (NULL != fgets(buff1, 255, fp))
137                     {
138 //                        fgets(buff2, 1023, fp);
139 //                        if (buff2[strlen(buff2) - 1] == '\n')
140 //                            buff2[strlen(buff2) - 1] = 0;
141                         if(buff1[0] == '\?')
142                         {
143                             fprintf(fLog, "%s\n",  symbols[i]+40);
144                             printf("%s\n",  symbols[i]+40);
145                         }
146                         else
147                         {
148                             snprintf(buff3, 255, "c++filt %s\n", buff1);//用c++filt 使函数名可视化
149                             FILE* fp2 = popen(buff3, "r");
150                             if (fp2 && fgets(buff3, 255, fp2)) {
151                                 fprintf(fLog, "%s %s\n", prog, buff3);
152                                 printf("%s %s\n", prog, buff3);
153                                 fflush(fLog);
154                                 pclose(fp2);
155                             }
156                             else
157                             {
158                                 fprintf(fLog, "%s %s\n", prog, buff1);
159                                 printf("%s %s\n", prog, buff1);
160                                 fflush(fLog);
161                             }
162                         }
163 
164 
165                     }
166                     pclose(fp);
167                 }
168             }
169 #else
170             for (int i = 0; i < nSize; i++)
171             {
172                 fwrite(symbols[i], 1, strlen(symbols[i]), fLog);
173                 fwrite("\n", 1, 1, fLog);
174                 fflush(fLog);
175                 printf("%s\n",symbols[i]);
176                 fflush(stdout);
177             }
178 #endif
179         }
180         free(symbols);
181     }
182     fcntl(fd, F_SETLK, file_lock(F_UNLCK, SEEK_SET));
183     fclose(fLog);
184     printf("2\n");
185     fflush(stdout);
186 
187     signal(signalno, SIG_DFL);
188     raise(signalno);
189     exit(3);
190 }
191 
192 
193 void initLinuxDump(const char* logPath)
194 {
195     //设置 信好的处理函数
196     strcpy(g_log_dir, logPath);
197 
198     signal(SIGSEGV, saveBackTrace);
199     for (int i = 0; i < (sizeof(_core_dump_signals) / sizeof((_core_dump_signals)[0])); i++)
200     {
201        signal(_core_dump_signals[i], saveBackTrace);
202     }
203 
204     // block SIGINT to all child process:
205     //sigset_t bset, oset;
206     //sigemptyset(&bset);
207     //sigaddset(&bset, SIGINT);
208     // equivalent to sigprocmask
209     //设置信号为阻塞信号
210     //if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0)
211     {
212        // printf("set thread signal mask error!");
213     }
214 
215 }
216 
217 
218 #endif

 

posted on 2020-11-12 16:49  kenny.wmh  阅读(94)  评论(0编辑  收藏  举报

导航