forked from ZLMediaKit/ZLMediaKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSystem.cpp
More file actions
166 lines (150 loc) · 4.93 KB
/
Copy pathSystem.cpp
File metadata and controls
166 lines (150 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#if !defined(_WIN32)
#include <limits.h>
#include <sys/resource.h>
#include <sys/wait.h>
#if !defined(ANDROID)
#include <execinfo.h>
#endif//!defined(ANDROID)
#endif//!defined(_WIN32)
#include "System.h"
#include <signal.h>
#include <map>
#include <iostream>
#include "Util/logger.h"
#include "Util/NoticeCenter.h"
#include "Util/uv_errno.h"
using namespace toolkit;
const int MAX_STACK_FRAMES = 128;
#define BroadcastOnCrashDumpArgs int &sig,const vector<vector<string> > &stack
const char kBroadcastOnCrashDump[] = "kBroadcastOnCrashDump";
#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#endif
string System::execute(const string &cmd) {
FILE *fPipe = NULL;
fPipe = popen(cmd.data(), "r");
if(!fPipe){
return "";
}
string ret;
char buff[1024] = {0};
while(fgets(buff, sizeof(buff) - 1, fPipe)){
ret.append(buff);
}
pclose(fPipe);
return ret;
}
#if !defined(ANDROID) && !defined(_WIN32)
static void sig_crash(int sig) {
signal(sig, SIG_DFL);
void *array[MAX_STACK_FRAMES];
int size = backtrace(array, MAX_STACK_FRAMES);
char ** strings = backtrace_symbols(array, size);
vector<vector<string> > stack(size);
for (int i = 0; i < size; ++i) {
auto &ref = stack[i];
std::string symbol(strings[i]);
ref.emplace_back(symbol);
#if defined(__linux) || defined(__linux__)
static auto addr2line = [](const string &address) {
string cmd = StrPrinter << "addr2line -C -f -e " << exePath() << " " << address;
return System::execute(cmd);
};
size_t pos1 = symbol.find_first_of("[");
size_t pos2 = symbol.find_last_of("]");
std::string address = symbol.substr(pos1 + 1, pos2 - pos1 - 1);
ref.emplace_back(addr2line(address));
#endif//__linux
}
free(strings);
NoticeCenter::Instance().emitEvent(kBroadcastOnCrashDump,sig,stack);
}
#endif // !defined(ANDROID) && !defined(_WIN32)
void System::startDaemon() {
#ifndef _WIN32
static pid_t pid;
do{
pid = fork();
if(pid == -1){
WarnL << "fork失败:" << get_uv_errmsg();
//休眠1秒再试
sleep(1);
continue;
}
if(pid == 0){
//子进程
return;
}
//父进程,监视子进程是否退出
DebugL << "启动子进程:" << pid;
signal(SIGINT, [](int) {
WarnL << "收到主动退出信号,关闭父进程与子进程";
kill(pid,SIGINT);
exit(0);
});
do{
int status = 0;
if(waitpid(pid, &status, 0) >= 0) {
WarnL << "子进程退出";
//休眠1秒再启动子进程
sleep(1);
break;
}
DebugL << "waitpid被中断:" << get_uv_errmsg();
}while (true);
}while (true);
#endif // _WIN32
}
void System::systemSetup(){
#if !defined(_WIN32)
struct rlimit rlim,rlim_new;
if (getrlimit(RLIMIT_CORE, &rlim)==0) {
rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &rlim_new)!=0) {
rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max;
setrlimit(RLIMIT_CORE, &rlim_new);
}
InfoL << "core文件大小设置为:" << rlim_new.rlim_cur;
}
if (getrlimit(RLIMIT_NOFILE, &rlim)==0) {
rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_NOFILE, &rlim_new)!=0) {
rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max;
setrlimit(RLIMIT_NOFILE, &rlim_new);
}
InfoL << "文件最大描述符个数设置为:" << rlim_new.rlim_cur;
}
#ifndef ANDROID
signal(SIGSEGV, sig_crash);
signal(SIGABRT, sig_crash);
NoticeCenter::Instance().addListener(nullptr,kBroadcastOnCrashDump,[](BroadcastOnCrashDumpArgs){
stringstream ss;
ss << "## crash date:" << getTimeStr("%Y-%m-%d %H:%M:%S") << endl;
ss << "## exe: " << exeName() << endl;
ss << "## signal: " << sig << endl;
ss << "## stack: " << endl;
for (size_t i = 0; i < stack.size(); ++i) {
ss << "[" << i << "]: ";
for (auto &str : stack[i]){
ss << str << endl;
}
}
string stack_info = ss.str();
ofstream out(StrPrinter << exeDir() << "/crash." << getpid(), ios::out | ios::binary | ios::trunc);
out << stack_info;
out.flush();
cerr << stack_info << endl;
});
#endif// ANDROID
#endif//!defined(_WIN32)
}