Skip to content

Commit a30104f

Browse files
yfeldblumfacebook-github-bot
authored andcommitted
use dlsym to find _r_debug to simplify build configs
Summary: Rather than customizing the build rules to force `-fPIC` and static linkage on this one source, do everything in-source using `dlsym` and let the build rules be simplified. The `dlsym` result is cached permanently at module load time. It must happen at load time before any signal handlers are attached, since `dlsym` is not async-signal-safe. Reviewed By: jpporto Differential Revision: D71051318 fbshipit-source-id: 955793e7b589ad3376b3804c4c696a20dc311c2b
1 parent 67a7e31 commit a30104f

File tree

1 file changed

+49
-7
lines changed
  • third-party/folly/src/folly/debugging/symbolizer/detail

1 file changed

+49
-7
lines changed

third-party/folly/src/folly/debugging/symbolizer/detail/Debug.cpp

+49-7
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,70 @@
1616

1717
#include <folly/debugging/symbolizer/detail/Debug.h>
1818

19-
#include <folly/CppAttributes.h>
19+
#include <folly/Portability.h>
20+
21+
#ifndef _WIN32
22+
#include <dlfcn.h>
23+
#endif
2024

2125
#if FOLLY_HAVE_ELF
2226
#include <link.h>
2327
#endif
2428

2529
#if defined(__APPLE__) && !TARGET_OS_OSX
26-
#define NO_R_DEBUG
30+
#define FOLLY_DETAIL_HAS_R_DEBUG 0
2731
#elif !defined(__linux__) || !FOLLY_HAVE_ELF || !FOLLY_HAVE_DWARF
28-
#define NO_R_DEBUG
32+
#define FOLLY_DETAIL_HAS_R_DEBUG 0
33+
#else
34+
#define FOLLY_DETAIL_HAS_R_DEBUG 1
2935
#endif
3036

3137
namespace folly {
3238
namespace symbolizer {
3339
namespace detail {
3440

41+
#if FOLLY_DETAIL_HAS_R_DEBUG
42+
43+
/// There is a strong requirement of finding the true _r_debug in ld.so.
44+
///
45+
/// The previous code used the declaration of the extern variable as found in
46+
///
47+
/// #include <link.h>
48+
///
49+
/// The intention of using the extern variable is to get the toolchain to emit a
50+
/// GOT access, e.g. like:
51+
///
52+
/// mov rax, qword ptr [rip + _r_debug@GOTPCREL]
53+
///
54+
/// This works in typical conditions. However, in the case of compiling with:
55+
///
56+
/// -mcmodel=small -fno-pic
57+
///
58+
/// ie with non-pic and small-code-model, there is a different outcome. Here
59+
/// instead, the toolchain emits a COPY relocation to copy _r_debug into the
60+
/// executable and emits a direct non-GOT access to the copy like:
61+
///
62+
/// mov eax, offset _r_debug
63+
///
64+
/// This causes all accesses in ld.so to be redirected to the copy in the main
65+
/// executable, which is a valid approach.
66+
///
67+
/// However, LLDB specifically looks for _r_debug in ld.so. When the debugger
68+
/// inspects a process, the _r_debug in the executable has all of the current
69+
/// information about the link and load state, but the debugger looks only at
70+
/// the _r_debug in ld.so which is empty! This breaks debugging.
71+
static r_debug* r_debug_cache_;
72+
[[gnu::constructor(101)]] void r_debug_cache_init_() {
73+
r_debug_cache_ = static_cast<r_debug*>(dlsym(RTLD_DEFAULT, "_r_debug"));
74+
}
75+
76+
#endif
77+
3578
struct r_debug* get_r_debug() {
36-
#ifdef NO_R_DEBUG
37-
return nullptr;
38-
#else
39-
return &_r_debug;
79+
#if FOLLY_DETAIL_HAS_R_DEBUG
80+
return r_debug_cache_;
4081
#endif
82+
return nullptr;
4183
}
4284

4385
} // namespace detail

0 commit comments

Comments
 (0)