@@ -14,14 +14,21 @@ limitations under the License. */
1414
1515#pragma once
1616
17- #include < execinfo.h>
17+ #include < dlfcn.h> // for dladdr
18+ #include < execinfo.h> // for backtrace
1819#include < iomanip>
20+ #include < memory>
1921#include < sstream>
2022#include < stdexcept>
2123#include < string>
24+
2225#include " paddle/string/printf.h"
2326#include " paddle/string/to_string.h"
2427
28+ #ifdef __GNUC__
29+ #include < cxxabi.h> // for __cxa_demangle
30+ #endif
31+
2532#ifndef PADDLE_ONLY_CPU
2633
2734#include " paddle/platform/dynload/cublas.h"
@@ -39,6 +46,19 @@ limitations under the License. */
3946namespace paddle {
4047namespace platform {
4148
49+ namespace {
50+ #ifdef __GNUC__
51+ inline std::string demangle (std::string name) {
52+ int status = -4 ; // some arbitrary value to eliminate the compiler warning
53+ std::unique_ptr<char , void (*)(void *)> res{
54+ abi::__cxa_demangle (name.c_str (), NULL , NULL , &status), std::free};
55+ return (status == 0 ) ? res.get () : name;
56+ }
57+ #else
58+ inline std::string demangle (std::string name) { return name; }
59+ #endif
60+ }
61+
4262struct EnforceNotMet : public std ::exception {
4363 std::exception_ptr exp_;
4464 std::string err_str_;
@@ -48,15 +68,29 @@ struct EnforceNotMet : public std::exception {
4868 std::rethrow_exception (exp_);
4969 } catch (const std::exception& exp) {
5070 std::ostringstream sout;
71+
5172 sout << string::Sprintf (" %s at [%s:%d]" , exp.what (), f, l) << std::endl;
52- sout << " Call Stacks: " << std::endl;
73+ sout << " PaddlePaddle Call Stacks: " << std::endl;
74+
5375 void * call_stack[TRACE_STACK_LIMIT];
54- int sz = backtrace (call_stack, TRACE_STACK_LIMIT);
55- auto line = backtrace_symbols (call_stack, sz);
56- for (int i = 0 ; i < sz; ++i) {
57- sout << line[i] << std::endl;
76+ auto size = backtrace (call_stack, TRACE_STACK_LIMIT);
77+ auto symbols = backtrace_symbols (call_stack, size);
78+
79+ Dl_info info;
80+ for (int i = 0 ; i < size; ++i) {
81+ if (dladdr (call_stack[i], &info)) {
82+ auto demangled = demangle (info.dli_sname );
83+ auto addr_offset = static_cast <char *>(call_stack[i]) -
84+ static_cast <char *>(info.dli_saddr );
85+ sout << string::Sprintf (" %-3d %*0p %s + %zd\n " , i,
86+ 2 + sizeof (void *) * 2 , call_stack[i],
87+ demangled, addr_offset);
88+ } else {
89+ sout << string::Sprintf (" %-3d %*0p %s\n " , i, 2 + sizeof (void *) * 2 ,
90+ call_stack[i]);
91+ }
5892 }
59- free (line );
93+ free (symbols );
6094 err_str_ = sout.str ();
6195 }
6296 }
@@ -170,7 +204,7 @@ inline void throw_on_error(T e) {
170204 * PADDLE_ENFORCE_EQ(a, b);
171205 *
172206 * will raise an expression described as follows:
173- * "enforce a == b failed, 1 != 2" with detailed stack infomation .
207+ * "enforce a == b failed, 1 != 2" with detailed stack information .
174208 *
175209 * extra messages is also supported, for example:
176210 * PADDLE_ENFORCE(a, b, "some simple enforce failed between %d numbers", 2)
0 commit comments