1. 使用发信号方式,在信号处理函数中调用: "sudo gcore %d", getpid()
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <ucontext.h>
#include <unistd.h>
void handler(int signo, siginfo_t *info, void *context)
{
ucontext_t* ctx = (ucontext_t*)context;
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
/* overwrite sigaction with caller's address */
trace[1] = (void *)ctx->uc_mcontext.gregs[REG_RIP];
messages = backtrace_symbols(trace, trace_size);
/* skip first stack frame (points here) */
printf("[bt] Execution path:\n");
for (i = 1; i < trace_size; ++i)
{
printf("[bt] #%d %s\n", i, messages[i]);
/* find first occurence of '(' or ' ' in message[i] and assume
* everything before that is the file name. (Don't go beyond 0 though
* (string terminator)*/
size_t p = 0;
while(messages[i][p] != '(' && messages[i][p] != ' ' && messages[i][p] != 0)
++p;
char syscom[256];
/* /usr/bin/addr2line */
sprintf(syscom,"addr2line %p -e %.*s", trace[i], p, messages[i]);
//last parameter is the file name of the symbol
system(syscom);
}
char cmd[64] = {0};
sprintf(cmd, "sudo gcore %d", getpid());
system(cmd);
return;
}
pthread_t id = 0;
bool bExit = false;
int main()
{
std::cout << "hello, world!" << std::endl;
std::thread td([=]()
{
id = pthread_self();
struct sigaction sa={0} ;
/* Install our signal handler */
sa.sa_sigaction = &handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
while(!bExit)
{
std::cout << "Hello waiter\n" << std::flush;
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(std::chrono::seconds(1));
};
std::cout << "bye" << std::endl;
});
td.detach();
std::cout << "input a integer" << std::endl;
int n = 0;
std::cin >> n;
if (id != 0)
pthread_kill(id, SIGALRM);
bExit = true;
std::this_thread::sleep_for(std::chrono::seconds(4));
return 0;
}
2. 编译
g++ -g -std=c++0x -pthread -rdynamic *.cpp -o bs