Merge lp:~thomas-voss/process-cpp/add_symbol_demangling_in_stack_traces into lp:process-cpp

Proposed by Thomas Voß
Status: Merged
Merged at revision: 34
Proposed branch: lp:~thomas-voss/process-cpp/add_symbol_demangling_in_stack_traces
Merge into: lp:process-cpp
Diff against target: 110 lines (+75/-0)
1 file modified
src/core/posix/fork.cpp (+75/-0)
To merge this branch: bzr merge lp:~thomas-voss/process-cpp/add_symbol_demangling_in_stack_traces
Reviewer Review Type Date Requested Status
Martin Pitt Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+203033@code.launchpad.net

Commit message

Add symbol demangling when printing the stack trace.

Description of the change

Add symbol demangling when printing the stack trace.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Martin Pitt (pitti) wrote :

A test for this would be nice (redirect stdout to a file, raise an exception in child, and ensure some expected functions are in the trace). But otherwise looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/core/posix/fork.cpp'
2--- src/core/posix/fork.cpp 2013-11-29 07:38:07 +0000
3+++ src/core/posix/fork.cpp 2014-01-24 11:03:09 +0000
4@@ -22,6 +22,9 @@
5 #include <iostream>
6 #include <system_error>
7
8+#include <cxxabi.h>
9+
10+#include <execinfo.h>
11 #include <unistd.h>
12
13 namespace
14@@ -32,6 +35,64 @@
15 if (rc == -1)
16 throw std::system_error(errno, std::system_category());
17 }
18+
19+std::tuple<std::string, bool> demangle(const std::string& symbol)
20+{
21+ int status = 1;
22+ auto result = abi::__cxa_demangle(symbol.c_str(),
23+ nullptr,
24+ nullptr,
25+ &status);
26+
27+ if (!result || status != 0)
28+ {
29+ return std::make_tuple(std::string(), false);
30+ }
31+
32+ std::string s{result};
33+ ::free(result);
34+
35+ return std::make_tuple(s, true);
36+}
37+
38+void print_backtrace(std::ostream& out)
39+{
40+ static const unsigned int max_frames=100;
41+ void *frames[max_frames];
42+
43+ auto frame_count = ::backtrace(frames, max_frames);
44+ auto symbols = ::backtrace_symbols(frames, frame_count);
45+
46+ for (int i = 0; i < frame_count; i++)
47+ {
48+ std::string symbol(symbols[i]);
49+
50+ auto first = symbol.find_first_of("(");
51+ auto last = symbol.find_last_of(")");
52+
53+ if (first != std::string::npos && last != std::string::npos)
54+ {
55+ auto mangled_symbol = symbol.substr(first+1,
56+ (last-1) - (first+1));
57+
58+ auto plus = mangled_symbol.find_first_of("+");
59+ if (plus != std::string::npos)
60+ mangled_symbol.erase(plus);
61+
62+ std::string demangled_symbol;
63+ bool successful;
64+
65+ std::tie(demangled_symbol, successful) = demangle(mangled_symbol);
66+
67+ if (successful)
68+ symbol = demangled_symbol;
69+ }
70+
71+ out << "\t" << std::hex << frames[i] << ": " << symbol << std::endl;
72+ }
73+
74+ ::free(symbols);
75+}
76 }
77
78 namespace core
79@@ -78,8 +139,15 @@
80 redirect_stream_to_fd(stderr_pipe.write_fd(), STDERR_FILENO);
81
82 result = main();
83+ } catch(const std::exception& e)
84+ {
85+ std::cerr << "core::posix::fork(): An unhandled std::exception occured in the child process:" << std::endl
86+ << "\t" << e.what() << std::endl;
87+ print_backtrace(std::cerr);
88 } catch(...)
89 {
90+ std::cerr << "core::posix::fork(): An unhandled exception occured in the child process." << std::endl;
91+ print_backtrace(std::cerr);
92 }
93
94 // We have to ensure that we exit here. Otherwise, we run into
95@@ -128,8 +196,15 @@
96 redirect_stream_to_fd(stderr_pipe.write_fd(), STDERR_FILENO);
97
98 result = main();
99+ } catch(const std::exception& e)
100+ {
101+ std::cerr << "core::posix::fork(): An unhandled std::exception occured in the child process:" << std::endl
102+ << "\t" << e.what() << std::endl;
103+ print_backtrace(std::cerr);
104 } catch(...)
105 {
106+ std::cerr << "core::posix::fork(): An unhandled exception occured in the child process." << std::endl;
107+ print_backtrace(std::cerr);
108 }
109
110 // We have to ensure that we exit here. Otherwise, we run into

Subscribers

People subscribed via source and target branches