Skip to content

Commit 0c3c609

Browse files
authored
Merge pull request #3463 from gangliao/bug
Demangle exception call stack for PADDLE_ENFORCE
2 parents ffbb0be + ffbb4c1 commit 0c3c609

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

paddle/platform/enforce.h

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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. */
3946
namespace paddle {
4047
namespace 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+
4262
struct 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

Comments
 (0)