Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit aa468ab

Browse filesBrowse files
addaleaxtargos
authored andcommitted
src: unify native symbol inspection code
Use a single file, and a single interface, for inspecting symbols in the current process for debugging. PR-URL: #21238 Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 5d3dfed commit aa468ab
Copy full SHA for aa468ab

File tree

Expand file treeCollapse file tree

5 files changed

+199
-94
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+199
-94
lines changed
Open diff view settings
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+1-5Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@
316316
'src/cares_wrap.cc',
317317
'src/connection_wrap.cc',
318318
'src/connect_wrap.cc',
319+
'src/debug_utils.cc',
319320
'src/env.cc',
320321
'src/exceptions.cc',
321322
'src/fs_event_wrap.cc',
@@ -495,9 +496,6 @@
495496
'defines': [ 'HAVE_INSPECTOR=0' ]
496497
}],
497498
[ 'OS=="win"', {
498-
'sources': [
499-
'src/backtrace_win32.cc',
500-
],
501499
'conditions': [
502500
[ 'node_intermediate_lib_type!="static_library"', {
503501
'sources': [
@@ -506,8 +504,6 @@
506504
}],
507505
],
508506
'libraries': [ '-lpsapi.lib' ]
509-
}, { # POSIX
510-
'sources': [ 'src/backtrace_posix.cc' ],
511507
}],
512508
[ 'node_use_etw=="true"', {
513509
'defines': [ 'HAVE_ETW=1' ],
Collapse file

‎src/backtrace_posix.cc‎

Copy file name to clipboardExpand all lines: src/backtrace_posix.cc
-49Lines changed: 0 additions & 49 deletions
This file was deleted.
Collapse file

‎src/backtrace_win32.cc‎

Copy file name to clipboardExpand all lines: src/backtrace_win32.cc
-40Lines changed: 0 additions & 40 deletions
This file was deleted.
Collapse file

‎src/debug_utils.cc‎

Copy file name to clipboard
+180Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#include "debug_utils.h"
2+
#include "node_internals.h"
3+
4+
#ifdef __POSIX__
5+
#if defined(__linux__)
6+
#include <features.h>
7+
#endif
8+
9+
#if defined(__linux__) && !defined(__GLIBC__) || \
10+
defined(__UCLIBC__) || \
11+
defined(_AIX)
12+
#define HAVE_EXECINFO_H 0
13+
#else
14+
#define HAVE_EXECINFO_H 1
15+
#endif
16+
17+
#if HAVE_EXECINFO_H
18+
#include <cxxabi.h>
19+
#include <dlfcn.h>
20+
#include <execinfo.h>
21+
#include <unistd.h>
22+
#include <sys/mman.h>
23+
#include <stdio.h>
24+
#endif
25+
26+
#else // __POSIX__
27+
28+
#include <windows.h>
29+
#include <dbghelp.h>
30+
31+
#endif // __POSIX__
32+
33+
namespace node {
34+
35+
#ifdef __POSIX__
36+
#if HAVE_EXECINFO_H
37+
class PosixSymbolDebuggingContext final : public NativeSymbolDebuggingContext {
38+
public:
39+
PosixSymbolDebuggingContext() : pagesize_(getpagesize()) { }
40+
41+
SymbolInfo LookupSymbol(void* address) override {
42+
Dl_info info;
43+
const bool have_info = dladdr(address, &info);
44+
SymbolInfo ret;
45+
if (!have_info)
46+
return ret;
47+
48+
if (info.dli_sname != nullptr) {
49+
if (char* demangled = abi::__cxa_demangle(info.dli_sname, 0, 0, 0)) {
50+
ret.name = demangled;
51+
free(demangled);
52+
} else {
53+
ret.name = info.dli_sname;
54+
}
55+
}
56+
57+
if (info.dli_fname != nullptr) {
58+
ret.filename = info.dli_fname;
59+
}
60+
61+
return ret;
62+
}
63+
64+
bool IsMapped(void* address) override {
65+
void* page_aligned = reinterpret_cast<void*>(
66+
reinterpret_cast<uintptr_t>(address) & ~(pagesize_ - 1));
67+
return msync(page_aligned, pagesize_, MS_ASYNC) == 0;
68+
}
69+
70+
int GetStackTrace(void** frames, int count) override {
71+
return backtrace(frames, count);
72+
}
73+
74+
private:
75+
uintptr_t pagesize_;
76+
};
77+
78+
std::unique_ptr<NativeSymbolDebuggingContext>
79+
NativeSymbolDebuggingContext::New() {
80+
return std::unique_ptr<NativeSymbolDebuggingContext>(
81+
new PosixSymbolDebuggingContext());
82+
}
83+
84+
#else // HAVE_EXECINFO_H
85+
86+
std::unique_ptr<NativeSymbolDebuggingContext>
87+
NativeSymbolDebuggingContext::New() {
88+
return std::unique_ptr<NativeSymbolDebuggingContext>(
89+
new NativeSymbolDebuggingContext());
90+
}
91+
92+
#endif // HAVE_EXECINFO_H
93+
94+
#else // __POSIX__
95+
96+
class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext {
97+
public:
98+
Win32SymbolDebuggingContext() {
99+
current_process_ = GetCurrentProcess();
100+
USE(SymInitialize(process, nullptr, true));
101+
}
102+
103+
~Win32SymbolDebuggingContext() {
104+
USE(SymCleanup(process));
105+
}
106+
107+
SymbolInfo LookupSymbol(void* address) override {
108+
// Ref: https://msdn.microsoft.com/en-en/library/windows/desktop/ms680578(v=vs.85).aspx
109+
char info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
110+
SYMBOL_INFO* info = reinterpret_cast<SYMBOL_INFO*>(info_buf);
111+
char demangled[MAX_SYM_NAME];
112+
113+
info->MaxNameLen = MAX_SYM_NAME;
114+
info->SizeOfStruct = sizeof(SYMBOL_INFO);
115+
116+
SymbolInfo ret;
117+
const bool have_info = SymFromAddr(process,
118+
reinterpret_cast<DWORD64>(address),
119+
nullptr,
120+
info);
121+
if (have_info && strlen(info->Name) == 0) {
122+
if (UnDecorateSymbolName(info->Name,
123+
demangled_,
124+
sizeof(demangled_),
125+
UNDNAME_COMPLETE)) {
126+
ret.name = demangled_;
127+
} else {
128+
ret.name = info->Name;
129+
}
130+
}
131+
132+
return ret;
133+
}
134+
135+
bool IsMapped(void* address) override {
136+
MEMORY_BASIC_INFORMATION info;
137+
138+
if (VirtualQuery(address, &info, sizeof(info)) != info)
139+
return false;
140+
141+
return info.State == MEM_COMMIT && info.Protect != 0;
142+
}
143+
144+
int GetStackTrace(void** frames, int count) override {
145+
return CaptureStackBackTrace(0, count, frames, nullptr);
146+
}
147+
148+
private:
149+
HANDLE current_process_;
150+
};
151+
152+
NativeSymbolDebuggingContext::New() {
153+
return std::unique_ptr<NativeSymbolDebuggingContext>(
154+
new Win32SymbolDebuggingContext());
155+
}
156+
157+
#endif // __POSIX__
158+
159+
std::string NativeSymbolDebuggingContext::SymbolInfo::Display() const {
160+
std::string ret = name;
161+
if (!filename.empty()) {
162+
ret += " [";
163+
ret += filename;
164+
ret += ']';
165+
}
166+
return ret;
167+
}
168+
169+
void DumpBacktrace(FILE* fp) {
170+
auto sym_ctx = NativeSymbolDebuggingContext::New();
171+
void* frames[256];
172+
const int size = sym_ctx->GetStackTrace(frames, arraysize(frames));
173+
for (int i = 1; i < size; i += 1) {
174+
void* frame = frames[i];
175+
fprintf(fp, "%2d: %p %s\n",
176+
i, frame, sym_ctx->LookupSymbol(frame).Display().c_str());
177+
}
178+
}
179+
180+
} // namespace node
Collapse file

‎src/debug_utils.h‎

Copy file name to clipboardExpand all lines: src/debug_utils.h
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,24 @@ inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
8484
Debug(async_wrap, format.c_str(), std::forward<Args>(args)...);
8585
}
8686

87+
// Debug helper for inspecting the currently running `node` executable.
88+
class NativeSymbolDebuggingContext {
89+
public:
90+
static std::unique_ptr<NativeSymbolDebuggingContext> New();
91+
92+
class SymbolInfo {
93+
public:
94+
std::string name;
95+
std::string filename;
96+
97+
std::string Display() const;
98+
};
99+
100+
virtual ~NativeSymbolDebuggingContext() {}
101+
virtual SymbolInfo LookupSymbol(void* address) { return { "", "" }; }
102+
virtual bool IsMapped(void* address) { return false; }
103+
virtual int GetStackTrace(void** frames, int count) { return 0; }
104+
};
87105

88106
} // namespace node
89107

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.