cpp-common
trace.hh
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset: 2; -*-
2 
9 #pragma once
10 
11 #include <linux/prctl.h>
12 #include <string>
13 #include <sys/prctl.h>
14 #include <sys/wait.h>
15 #include <unistd.h>
16 
17 namespace nvsl {
19  __attribute__((visibility(("default")))) inline void dump_maps() {}
20 
22  static inline std::string get_stack_trace() {
23  char pid_buf[30];
24  sprintf(pid_buf, "%d", getpid());
25  char name_buf[512];
26  name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
27  prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
28 
29  std::string gdb_cmd = "/usr/bin/gdb -batch -quiet -ex bt " +
30  std::string(name_buf) + " " + std::string(pid_buf) +
31  " 2>&1";
32 
33  FILE *child_f = popen(gdb_cmd.c_str(), "r");
34  std::string output;
35 
36  if (child_f) {
37  char c;
38  while ((c = getc(child_f)) != EOF)
39  output += c;
40  }
41 
42  pclose(child_f);
43 
44  return output;
45  }
46 
47  inline int get_stack_depth(void) {
48  auto stack = get_stack_trace();
49  return std::count(stack.begin(), stack.end(), '\n');
50  }
51 
53  static inline void print_trace(bool start_gdb = true) {
54  char pid_buf[30];
55  sprintf(pid_buf, "%d", getpid());
56  char name_buf[512];
57  name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
58  prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
59  int child_pid = fork();
60  if (!child_pid) {
61  dup2(2, 1); // redirect output to stderr - edit: unnecessary?
62  if (start_gdb) {
63  execl("/usr/bin/gdb", "gdb", "-quiet", "-ex", "bt", name_buf, pid_buf,
64  NULL);
65  } else {
66  execl("/usr/bin/gdb", "gdb", "-batch", "-quiet", "-ex", "bt", name_buf,
67  pid_buf, NULL);
68  }
69  abort(); /* If gdb failed to start */
70  } else {
71  waitpid(child_pid, NULL, 0);
72  }
73  }
74 
75 } // namespace nvsl
nvsl::__attribute__
__attribute__((visibility(("default")))) inline void dump_maps()
Dump virtual memory mappings to a file.
Definition: trace.hh:19