Commit df02de68 authored by Monty's avatar Monty

Fixed my_addr_resolve (cherry picked from 10.6)

When a server is compiled with -fPIE, my_addr_resolve needs to
subtract the info.dli_fbase from symbol addresses in memory for
addr2line to recognize them.  When a server is compiled without -fPIE,
my_addr_resolve should not do it.  Unfortunately not all compilers
define __PIE__ when -fPIE was used (e.g. older gcc doesn't), so we
have to resort to run-time detection.
parent 881918bf
...@@ -170,6 +170,7 @@ static pid_t pid; ...@@ -170,6 +170,7 @@ static pid_t pid;
static char addr2line_binary[1024]; static char addr2line_binary[1024];
static char output[1024]; static char output[1024];
static struct pollfd poll_fds; static struct pollfd poll_fds;
static void *addr_offset;
int start_addr2line_fork(const char *binary_path) int start_addr2line_fork(const char *binary_path)
{ {
...@@ -297,7 +298,6 @@ static int addr_resolve(void *ptr, my_addr_loc *loc) ...@@ -297,7 +298,6 @@ static int addr_resolve(void *ptr, my_addr_loc *loc)
int my_addr_resolve(void *ptr, my_addr_loc *loc) int my_addr_resolve(void *ptr, my_addr_loc *loc)
{ {
Dl_info info; Dl_info info;
int error;
if (!dladdr(ptr, &info)) if (!dladdr(ptr, &info))
return 1; return 1;
...@@ -307,7 +307,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) ...@@ -307,7 +307,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
/* /*
We use dli_fname in case the path is longer than the length of We use dli_fname in case the path is longer than the length of
our static string. We don't want to allocate anything our static string. We don't want to allocate anything
dynamicaly here as we are in a "crashed" state. dynamically here as we are in a "crashed" state.
*/ */
if (start_addr2line_fork(info.dli_fname)) if (start_addr2line_fork(info.dli_fname))
{ {
...@@ -318,10 +318,22 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) ...@@ -318,10 +318,22 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
} }
/* Save result for future comparisons. */ /* Save result for future comparisons. */
strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary)); strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
/*
Check if we should use info.dli_fbase as an offset or not
for the base program. This is depending on if the compilation is
done with PIE or not.
*/
addr_offset= info.dli_fbase;
#ifndef __PIE__
if (strcmp(info.dli_fname, my_progname) == 0 &&
addr_resolve((void*) my_addr_resolve, loc) == 0 &&
strcmp(loc->func, "my_addr_resolve") == 0)
addr_offset= 0;
#endif
} }
if (!(error= addr_resolve((void*) (ptr - info.dli_fbase), loc)))
return 0; return addr_resolve((void*) (ptr - addr_offset), loc);
return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment