|
@@ -158,12 +158,281 @@ void RunServer() {
|
|
|
}
|
|
|
|
|
|
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <fcntl.h>
|
|
|
+#include <string.h>
|
|
|
+#include <signal.h>
|
|
|
+#include <execinfo.h>
|
|
|
+
|
|
|
+#include <QDateTime>
|
|
|
+#include <QDir>
|
|
|
+
|
|
|
+void out_stack(char *sig);
|
|
|
+void signal_exit(int dunno)
|
|
|
+{
|
|
|
+ char* signal_str = (char*)" ";
|
|
|
+ char dunno_str[10] = {0};
|
|
|
+ sprintf(dunno_str, "%d", dunno);
|
|
|
+ switch (dunno)
|
|
|
+ {
|
|
|
+ case 1:
|
|
|
+ signal_str = (char*)"SIGHUP(1)";
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ signal_str = (char*)"SIGINT(2:CTRL_C)"; //CTRL_C
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ signal_str = (char*)"SIGQUIT(3)";
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ {
|
|
|
+ signal_str = (char*)"SIGABRT(6)";
|
|
|
+ out_stack(signal_str);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 9:
|
|
|
+ signal_str = (char*)"SIGKILL(9)";
|
|
|
+ break;
|
|
|
+ case 15:
|
|
|
+ signal_str = (char*)"SIGTERM(15 KILL)"; //kill
|
|
|
+ break;
|
|
|
+ case 11:
|
|
|
+ {
|
|
|
+ signal_str = (char*)"SIGSEGV(11)"; //SIGSEGV
|
|
|
+ out_stack(signal_str);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ signal_str = (char*)"OTHER";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ exit(0);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+size_t get_executable_path( char* processdir,char* processname, size_t len)
|
|
|
+{
|
|
|
+ char* path_end;
|
|
|
+ int nsize;
|
|
|
+ if((nsize =readlink("/proc/self/exe", processdir,len)) <=0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ processdir[nsize] = '\0';
|
|
|
+ path_end = strrchr(processdir, '/');
|
|
|
+ if(path_end == NULL)
|
|
|
+ return -1;
|
|
|
+ ++path_end;
|
|
|
+
|
|
|
+
|
|
|
+ strcpy(processname, path_end);
|
|
|
+ *path_end = '\0';
|
|
|
+
|
|
|
+ return (size_t)(path_end - processdir);
|
|
|
+}
|
|
|
+
|
|
|
+void savetofile(char * stroutput)
|
|
|
+{
|
|
|
+ qDebug("save file");
|
|
|
+ char strpath[1024];
|
|
|
+ QDateTime dt = QDateTime::currentDateTime();
|
|
|
+ char path[1000];
|
|
|
+ char processname[1024];
|
|
|
+ get_executable_path(path, processname, 1000);
|
|
|
+ snprintf(strpath,255,"%s/log/%s-%d-%s.log",getenv("HOME"),processname, getpid(),dt.toString("yyyyMMddhhmmsszzz").toLatin1().data());
|
|
|
+
|
|
|
+
|
|
|
+ char strdir[1024];
|
|
|
+ snprintf(strdir,255,"%s/log",getenv("HOME"));
|
|
|
+ QDir xdir;
|
|
|
+ xdir.setPath(strdir);
|
|
|
+ if(!xdir.exists())
|
|
|
+ {
|
|
|
+ qDebug("create dir %s",strdir);
|
|
|
+ xdir.mkdir(strdir);
|
|
|
+ }
|
|
|
+
|
|
|
+ qDebug("%s\n",strpath);
|
|
|
+ FILE* file = fopen(strpath,"w+");
|
|
|
+
|
|
|
+ if(file != nullptr)
|
|
|
+ {
|
|
|
+ fwrite(stroutput,strnlen(stroutput,6000),1,file);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ fclose(file);
|
|
|
+}
|
|
|
+
|
|
|
+static void output_addrline(char addr[],char * strtem)
|
|
|
+{
|
|
|
+ char cmd[256];
|
|
|
+ char line[256];
|
|
|
+ char addrline[32]={0,};
|
|
|
+ char *str1, *str2;
|
|
|
+ FILE* file;
|
|
|
+
|
|
|
+ snprintf(strtem,1000," ");
|
|
|
+
|
|
|
+// str1 = strchr(addr,'[');
|
|
|
+// str2 = strchr(addr, ']');
|
|
|
+
|
|
|
+ str1 = strchr(addr,'(');
|
|
|
+ str2 = strchr(addr, ')');
|
|
|
+ if(str1 == NULL || str2 == NULL)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if((str2 -str1 -2)<=0)
|
|
|
+ {
|
|
|
+// printf("can't find address,please use -g compile.");
|
|
|
+// strncpy(strtem,"can't find address,please use -g compile.",256);
|
|
|
+ str1 = strchr(addr,'[');
|
|
|
+ str2 = strchr(addr, ']');
|
|
|
+ if(str1 == NULL || str2 == NULL)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if((str2 -str1 -2)<=0)
|
|
|
+ {
|
|
|
+ printf("can't find address,please use -g compile.");
|
|
|
+ strncpy(strtem,"can't find address,please use -g compile.",256);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(addrline, str1 + 1, str2 -str1 -1);
|
|
|
+ snprintf(cmd, sizeof(cmd), "addr2line -e /proc/%d/exe %s ", getpid(), addrline);
|
|
|
+ qDebug("%s\n",cmd);
|
|
|
+
|
|
|
+
|
|
|
+ file = popen(cmd, "r");
|
|
|
+ if(NULL != fgets(line, 256, file))
|
|
|
+ {
|
|
|
+ printf("%s\n", line);
|
|
|
+ snprintf(strtem,1000,"%s\n",line);
|
|
|
+ }
|
|
|
+ if(strnlen(line,255) == 0)
|
|
|
+ {
|
|
|
+ printf("no addr.\n");
|
|
|
+ }
|
|
|
+ pclose(file);
|
|
|
+}
|
|
|
+
|
|
|
+static void proc_addrline(int64_t xaddr,char * strtem)
|
|
|
+{
|
|
|
+ char cmd[256];
|
|
|
+ char line[256];
|
|
|
+ FILE* file;
|
|
|
+
|
|
|
+ snprintf(strtem,1000," ");
|
|
|
+ snprintf(cmd, sizeof(cmd), "addr2line -e /proc/%d/exe %x ", getpid(), xaddr);
|
|
|
+ qDebug("%s\n",cmd);
|
|
|
+
|
|
|
+ file = popen(cmd, "r");
|
|
|
+ if(NULL != fgets(line, 256, file))
|
|
|
+ {
|
|
|
+ printf("%s\n", line);
|
|
|
+ snprintf(strtem,1000,"%s\n",line);
|
|
|
+ }
|
|
|
+ if(strnlen(line,255) == 0)
|
|
|
+ {
|
|
|
+ printf("no addr.\n");
|
|
|
+ }
|
|
|
+ pclose(file);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void out_stack(char *sig)
|
|
|
+{
|
|
|
+ void *array[32];
|
|
|
+ size_t size;
|
|
|
+ char **strings;
|
|
|
+ size_t i;
|
|
|
+
|
|
|
+ char stroutput[6000];
|
|
|
+ char strtem[1000];
|
|
|
+
|
|
|
+ snprintf(stroutput,3000," ");
|
|
|
+ printf("%s\n", sig);
|
|
|
+ qDebug("%s\n", sig);
|
|
|
+ size = backtrace (array, 32);
|
|
|
+ //该函数用于获取当前线程的调用堆栈,获取的信息将会被存放在array中,
|
|
|
+ //它是一个指针列表。参数 32 用来指定array中可以保存多少个void* 元素。
|
|
|
+ //函数返回值是实际获取的指针个数,最大不超过32大小.
|
|
|
+ strings = backtrace_symbols (array, size);
|
|
|
+
|
|
|
+ /* backtrace_symbols将从backtrace函数获取的信息转化为一个字符串数组.
|
|
|
+ * 参数array应该是从backtrace函数获取的指针数组,
|
|
|
+ * size是该数组中的元素个数(backtrace的返回值)
|
|
|
+ * 函数返回值是一个指向字符串数组的指针,它的大小同array相同.
|
|
|
+ * 每个字符串包含了一个相对于array中对应元素的可打印信息.
|
|
|
+ * 它包括函数名,函数的偏移地址,和实际的返回地址
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (NULL == strings)
|
|
|
+ {
|
|
|
+ printf("backtrace_symbols\n");
|
|
|
+ return ;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ qDebug("size is %d",(int)size);
|
|
|
+
|
|
|
+ for (i = 0; i <size; i++)
|
|
|
+ {
|
|
|
+// qDebug("i is %d",i);
|
|
|
+ printf("%s\n",strings[i]);
|
|
|
+// snprintf(strtem,1000,"%s\n",strings[i]);
|
|
|
+// strncat(stroutput,strtem,6000);
|
|
|
+// output_addrline(strings[i],strtem);
|
|
|
+// strncat(stroutput,strtem,6000);
|
|
|
+ }
|
|
|
+
|
|
|
+ for(i=0;i<size;i++)
|
|
|
+ {
|
|
|
+ int64_t xaddr = (int64_t)((int *)array[i]);
|
|
|
+ printf("addr is %x\n", xaddr);
|
|
|
+ snprintf(strtem,1000,"addr is %x\n", xaddr);
|
|
|
+ strncat(stroutput,strtem,6000);
|
|
|
+ proc_addrline(xaddr,strtem);
|
|
|
+ strncat(stroutput,strtem,6000);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ free(strings);
|
|
|
+
|
|
|
+ savetofile(stroutput);
|
|
|
+
|
|
|
+ QTime x;
|
|
|
+ x.start();
|
|
|
+ while((unsigned int)(x.elapsed())<100)
|
|
|
+ {
|
|
|
+ // qDebug("hello");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
|
QCoreApplication a(argc, argv);
|
|
|
|
|
|
+ signal(SIGABRT, signal_exit);
|
|
|
+ signal(SIGTERM, signal_exit);
|
|
|
+ signal(SIGSEGV, signal_exit);
|
|
|
+
|
|
|
+// int * p = 0;
|
|
|
+
|
|
|
+// *p = 1;
|
|
|
+
|
|
|
snprintf(gstrport,255,"50061");
|
|
|
|
|
|
int nRtn = GetOptLong(argc,argv);
|