Skip to content

Commit 3c3585d

Browse files
break up other impl's
1 parent e68ba40 commit 3c3585d

File tree

8 files changed

+104
-110
lines changed

8 files changed

+104
-110
lines changed

libcxx/src/stacktrace/builder.cpp

Lines changed: 21 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,75 +11,44 @@
1111

1212
#include <__stacktrace/base.h>
1313

14-
#include "stacktrace/config.h"
1514
#include "stacktrace/linux.h"
1615
#include "stacktrace/macos.h"
1716
#include "stacktrace/tools.h"
1817
#include "stacktrace/unwind.h"
19-
#include "stacktrace/utils/debug.h"
20-
#include "stacktrace/utils/failed.h"
21-
#include "stacktrace/utils/fd.h"
22-
#include "stacktrace/win/dll.h"
2318
#include "stacktrace/win/impl.h"
2419

2520
_LIBCPP_BEGIN_NAMESPACE_STD
2621

2722
namespace __stacktrace {
2823

2924
_LIBCPP_NO_TAIL_CALLS _LIBCPP_NOINLINE void builder::build_stacktrace(size_t skip, size_t max_depth) {
30-
/*
31-
Here we declare stacktrace components or "backends" which will handle the different tasks:
32-
33-
(1) get the addresses from the call stack
34-
(2) identify program images in process virtual space (program binary, plus modules, shared/dynamic libs)
35-
(3) resolve using debug info, and possibly with an external tool on the $PATH
36-
(4+) extra passes to get symbols, in case 3 couldn't
37-
38-
Based on the macros defined in `config.h`, throw all backends we have available at the task. Ideally the #ifdef
39-
gauntlet below should result in one of each of the above functions: (1) collector, (2) mod_ident, (3) resolver, (4)
40-
symbolizer. If any are missing or duplicated that is still fine; we work with zero or all the available utilities.
41-
42-
All these classes do their best to provide any of the requested fields they can: symbol, filename, source line,
43-
substituting if needed with something reasonable. For example, if the source filename and line are not available
44-
then we will at least report that the address and symbol are in the module `c:\path\foo.exe`.
45-
46-
These components should also tolerate: missing data, weirdly-formatted data (e.g. from the external tools), or even
47-
already-populated data. We take care not to crash / abort / throw in any of these, and we'll silently fail. See
48-
`common/debug.h` for a debugging logger you can enable at runtime.
49-
*/
50-
51-
#if defined(_LIBCPP_STACKTRACE_WINDOWS)
25+
// First get the instruction addresses, populate __entries_
5226
win_impl dbghelp{*this};
53-
auto& collector = dbghelp;
54-
auto& mod_ident = dbghelp;
55-
auto& resolver = dbghelp;
56-
auto& symbolizer = dbghelp;
57-
#endif
58-
#if defined(_LIBCPP_STACKTRACE_COLLECT_UNWIND)
5927
unwind unwind{*this};
60-
auto& collector = unwind;
61-
#endif
62-
#if defined(_LIBCPP_STACKTRACE_MACOS)
28+
dbghelp.collect(skip + 1, max_depth);
29+
unwind.collect(skip + 1, max_depth);
30+
31+
// (Can't proceed if empty)
32+
if (!__entries_.size()) {
33+
return;
34+
}
35+
36+
// Associate addrs with binaries (ELF/MachO/etc.)
6337
macos macos{*this};
64-
auto& mod_ident = macos;
65-
auto& symbolizer = macos;
66-
#endif
67-
#if defined(_LIBCPP_STACKTRACE_LINUX)
6838
linux linux{*this};
69-
auto& mod_ident = linux;
70-
auto& symbolizer = linux;
71-
#endif
72-
#if defined(_LIBCPP_STACKTRACE_CAN_SPAWN_TOOLS)
39+
dbghelp.ident_modules();
40+
macos.ident_modules();
41+
linux.ident_modules();
42+
43+
// Resolve addresses to symbols, filename, linenumber
7344
spawner pspawn{*this};
74-
auto& resolver = pspawn;
75-
#endif
45+
dbghelp.resolve_lines();
46+
pspawn.resolve_lines();
7647

77-
collector.collect(skip + 1, max_depth); // First get the instruction addresses, populate __entries_
78-
if (__entries_.size()) { // (Can't proceed if empty)
79-
mod_ident.ident_modules(); // Associate addrs with binaries (ELF/MachO/etc.)
80-
resolver.resolve_lines(); // Resolve addresses to symbols, filename, linenumber
81-
symbolizer.symbolize(); // Populate missing symbols, if any.
82-
}
48+
// Populate missing symbols, if any.
49+
dbghelp.symbolize();
50+
macos.symbolize();
51+
linux.symbolize();
8352
}
8453

8554
} // namespace __stacktrace

libcxx/src/stacktrace/linux.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "stacktrace/linux.h"
910
#include "stacktrace/config.h"
1011

1112
#if defined(_LIBCPP_STACKTRACE_LINUX)
@@ -16,11 +17,9 @@
1617
# include <stacktrace>
1718
# include <unistd.h>
1819

19-
# include <__stacktrace/base.h>
20-
2120
# include "stacktrace/config.h"
22-
# include "stacktrace/linux.h"
23-
# include "stacktrace/utils.h"
21+
# include "stacktrace/utils/fd.h"
22+
# include "stacktrace/utils/image.h"
2423

2524
_LIBCPP_BEGIN_NAMESPACE_STD
2625
namespace __stacktrace {
@@ -112,4 +111,16 @@ void linux::symbolize() {
112111
} // namespace __stacktrace
113112
_LIBCPP_END_NAMESPACE_STD
114113

114+
#else
115+
116+
_LIBCPP_BEGIN_NAMESPACE_STD
117+
namespace __stacktrace {
118+
119+
void linux::ident_modules() {}
120+
void linux::symbolize() {}
121+
void linux::resolve_main_elf_syms(std::string_view main_elf_name) {}
122+
123+
} // namespace __stacktrace
124+
_LIBCPP_END_NAMESPACE_STD
125+
115126
#endif // _LIBCPP_STACKTRACE_LINUX

libcxx/src/stacktrace/linux.h

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@
99
#ifndef _LIBCPP_STACKTRACE_LINUX_H
1010
#define _LIBCPP_STACKTRACE_LINUX_H
1111

12+
#include <__stacktrace/base.h>
13+
14+
_LIBCPP_BEGIN_NAMESPACE_STD
15+
namespace __stacktrace {
16+
17+
struct linux {
18+
builder& builder_;
19+
void ident_modules();
20+
void symbolize();
21+
22+
private:
23+
void resolve_main_elf_syms(std::string_view elf_name);
24+
};
25+
26+
} // namespace __stacktrace
27+
_LIBCPP_END_NAMESPACE_STD
28+
1229
#include "stacktrace/config.h"
1330

1431
#if defined(_LIBCPP_STACKTRACE_LINUX)
@@ -23,30 +40,18 @@
2340
# include <string_view>
2441
# include <unistd.h>
2542

26-
# include <__stacktrace/base.h>
27-
28-
# include "stacktrace/config.h"
29-
# include "stacktrace/utils.h"
43+
# include "stacktrace/utils/image.h"
3044

3145
_LIBCPP_BEGIN_NAMESPACE_STD
3246
namespace __stacktrace {
3347

34-
struct linux {
35-
builder& builder_;
36-
void ident_modules();
37-
void symbolize();
38-
39-
private:
40-
void resolve_main_elf_syms(std::string_view elf_name);
41-
};
42-
4348
struct images {
4449
// How many images this contains, including the left/right sentinels.
4550
unsigned count_{0};
46-
std::array<image, k_max_images + 2> images_{};
51+
std::array<image, image::kMaxImages + 2> images_{};
4752

4853
int add(dl_phdr_info& info) {
49-
assert(count_ < k_max_images);
54+
assert(count_ < image::kMaxImages);
5055
auto isFirst = (count_ == 0);
5156
auto& image = images_.at(count_++);
5257
image.loaded_at_ = info.dlpi_addr;
@@ -60,7 +65,7 @@ struct images {
6065
image.name_ = buffer;
6166
}
6267
}
63-
return count_ == k_max_images; // return nonzero if we're at the limit
68+
return count_ == image::kMaxImages; // return nonzero if we're at the limit
6469
}
6570

6671
static int callback(dl_phdr_info* info, size_t, void* self) { return (*(images*)(self)).add(*info); }

libcxx/src/stacktrace/macos.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "stacktrace/macos.h"
910
#include "stacktrace/config.h"
1011

1112
#if defined(_LIBCPP_STACKTRACE_MACOS)
@@ -18,44 +19,34 @@
1819

1920
# include <__stacktrace/base.h>
2021

21-
# include "stacktrace/macos.h"
22+
# include "stacktrace/utils/image.h"
2223

2324
_LIBCPP_BEGIN_NAMESPACE_STD
2425
namespace __stacktrace {
2526

26-
constexpr unsigned kMaxImages = 256;
27-
28-
struct Image {
29-
uintptr_t loadedAt{};
30-
intptr_t slide{};
31-
std::string_view name{};
32-
bool operator<(Image const& rhs) const { return loadedAt < rhs.loadedAt; }
33-
operator bool() const { return !name.empty(); }
34-
};
35-
36-
void ident_module(alloc& alloc, entry_base& entry, unsigned& index, Image* images) {
27+
void ident_module(alloc& alloc, entry_base& entry, unsigned& index, image* images) {
3728
if (entry.__addr_actual_) {
38-
while (images[index].loadedAt > entry.__addr_actual_) {
29+
while (images[index].loaded_at_ > entry.__addr_actual_) {
3930
--index;
4031
}
41-
while (images[index + 1].loadedAt <= entry.__addr_actual_) {
32+
while (images[index + 1].loaded_at_ <= entry.__addr_actual_) {
4233
++index;
4334
}
4435
auto& image = images[index];
4536
if (image) {
46-
entry.__addr_unslid_ = entry.__addr_actual_ - images[index].slide;
47-
entry.__file_ = alloc.make_str(images[index].name);
37+
entry.__addr_unslid_ = entry.__addr_actual_ - images[index].slide_;
38+
entry.__file_ = alloc.make_str(images[index].name_);
4839
}
4940
}
5041
}
5142

5243
bool enum_modules(unsigned& count, auto& images) {
53-
count = std::min(kMaxImages, _dyld_image_count());
44+
count = std::min(image::kMaxImages, size_t(_dyld_image_count()));
5445
for (size_t i = 0; i < count; i++) {
55-
auto& image = images[i];
56-
image.slide = _dyld_get_image_vmaddr_slide(i);
57-
image.loadedAt = uintptr_t(_dyld_get_image_header(i));
58-
image.name = _dyld_get_image_name(i);
46+
auto& image = images[i];
47+
image.slide_ = _dyld_get_image_vmaddr_slide(i);
48+
image.loaded_at_ = uintptr_t(_dyld_get_image_header(i));
49+
image.name_ = _dyld_get_image_name(i);
5950
}
6051
images[count++] = {0uz, 0}; // sentinel at low end
6152
images[count++] = {~0uz, 0}; // sentinel at high end
@@ -65,7 +56,7 @@ bool enum_modules(unsigned& count, auto& images) {
6556

6657
void macos::ident_modules() {
6758
static unsigned imageCount;
68-
static std::array<Image, kMaxImages + 2> images;
59+
static std::array<image, image::kMaxImages + 2> images;
6960
static bool atomicInitialized = enum_modules(imageCount, images);
7061
(void)atomicInitialized;
7162

@@ -76,7 +67,7 @@ void macos::ident_modules() {
7667
}
7768

7869
// First image (the main program) is at index 1
79-
builder_.__main_prog_path_ = builder_.__alloc_.make_str(images.at(1).name);
70+
builder_.__main_prog_path_ = builder_.__alloc_.make_str(images.at(1).name_);
8071

8172
unsigned index = 1; // Starts at one, and is moved by 'ident_module'
8273
for (auto& entry : builder_.__entries_) {
@@ -107,4 +98,15 @@ void macos::symbolize() {
10798
} // namespace __stacktrace
10899
_LIBCPP_END_NAMESPACE_STD
109100

101+
#else
102+
103+
_LIBCPP_BEGIN_NAMESPACE_STD
104+
namespace __stacktrace {
105+
106+
void macos::ident_modules() {}
107+
void macos::symbolize() {}
108+
109+
} // namespace __stacktrace
110+
_LIBCPP_END_NAMESPACE_STD
111+
110112
#endif // _LIBCPP_STACKTRACE_MACOS

libcxx/src/stacktrace/tools.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
# include <__stacktrace/entry.h>
2929

3030
# include "stacktrace/tools.h"
31-
# include "stacktrace/utils.h"
3231

3332
_LIBCPP_BEGIN_NAMESPACE_STD
3433
namespace __stacktrace {

libcxx/src/stacktrace/utils/image.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,21 @@
1010
#define _LIBCPP_STACKTRACE_UTILS_IMAGE
1111

1212
#include <__config>
13-
#include <cerrno>
14-
#include <string_view>
15-
#include <unistd.h>
13+
#include <__stacktrace/base.h>
1614

1715
_LIBCPP_BEGIN_NAMESPACE_STD
1816
namespace __stacktrace {
1917

20-
constexpr unsigned k_max_images = 256;
18+
struct image {
19+
constexpr static size_t kMaxImages = 256;
2120

22-
struct _LIBCPP_HIDE_FROM_ABI image {
2321
uintptr_t loaded_at_{};
2422
intptr_t slide_{};
2523
std::string_view name_{};
2624
bool is_main_prog_{};
2725

28-
_LIBCPP_HIDE_FROM_ABI bool operator<(image const& rhs) const { return loaded_at_ < rhs.loaded_at_; }
29-
_LIBCPP_HIDE_FROM_ABI operator bool() const { return !name_.empty(); }
26+
bool operator<(image const& rhs) const { return loaded_at_ < rhs.loaded_at_; }
27+
operator bool() const { return !name_.empty(); }
3028
};
3129

3230
} // namespace __stacktrace

libcxx/src/stacktrace/win/impl.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "stacktrace/win/impl.h"
910
#include <__config>
1011

12+
_LIBCPP_BEGIN_NAMESPACE_STD
13+
namespace __stacktrace {
14+
std::mutex win_impl::mutex_;
15+
} // namespace __stacktrace
16+
_LIBCPP_END_NAMESPACE_STD
17+
1118
#if defined(_LIBCPP_WIN32API)
1219
// windows.h must be first
1320
# include <windows.h>
@@ -34,7 +41,6 @@ so we claim a lock in the `WinDebugAPIs` constructor.
3441
*/
3542

3643
// Statically-initialized
37-
std::mutex gWindowsAPILock;
3844
DbgHelpDLL dbg;
3945
PSAPIDLL ps;
4046

@@ -53,7 +59,7 @@ size_t moduleCount; // 0 IFF module enumeration failed
5359

5460
} // namespace
5561

56-
win_impl::WinDebugAPIs(builder& trace) : builder_(trace), guard_(gWindowsAPILock) {
62+
win_impl::global_init() {
5763
if (!globalInitialized) {
5864
// Cannot proceed without these DLLs:
5965
if (!dbg) {
@@ -84,7 +90,7 @@ win_impl::WinDebugAPIs(builder& trace) : builder_(trace), guard_(gWindowsAPILock
8490
(*dbg.SymSetOptions)(symOptions);
8591
}
8692

87-
win_impl::~WinDebugAPIs() {
93+
win_impl::~win_impl() {
8894
if (symsInitialized) {
8995
(*dbg.SymCleanup)(proc);
9096
symsInitialized = false;
@@ -204,15 +210,15 @@ _LIBCPP_END_NAMESPACE_STD
204210

205211
// Not_LIBCPP_WIN32API
206212

207-
# include "stacktrace/win/impl.h"
208-
209213
_LIBCPP_BEGIN_NAMESPACE_STD
210214
namespace __stacktrace {
211215

216+
void win_impl::global_init() {}
212217
void win_impl::collect(size_t skip, size_t max_depth) {}
213218
void win_impl::ident_modules() {}
214219
void win_impl::symbolize() {}
215220
void win_impl::resolve_lines() {}
221+
win_impl::~win_impl() {}
216222

217223
} // namespace __stacktrace
218224
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)