alternative method of resolving addresses for safemalloc and crash handler.

don't link with libbfd, exec addr2line, if it's available at run time
This commit is contained in:
Sergei Golubchik 2012-03-13 13:34:24 +01:00
parent 1cbc3790d3
commit 00f2e3139f
2 changed files with 71 additions and 1 deletions

View file

@ -56,7 +56,11 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
#endif
#endif
#ifdef HAVE_BFD_H
#ifndef _WIN32
#define MY_ADDR_RESOLVE_FORK
#endif
#if defined(HAVE_BFD_H) || defined(MY_ADDR_RESOLVE_FORK)
#define HAVE_MY_ADDR_RESOLVE 1
#endif

View file

@ -129,4 +129,70 @@ err:
yet another - just execute addr2line or eu-addr2line, whatever available,
pipe the addresses to it, and parse the output
*/
#include <m_string.h>
#include <ctype.h>
static int in[2], out[2];
static int initialized= 0;
int my_addr_resolve(void *ptr, my_addr_loc *loc)
{
char input[32], *s;
char output[1024];
size_t len;
len= my_safe_snprintf(input, sizeof(input), "0x%p\n", ptr);
if (write(in[1], input, len) <= 0)
return 1;
if (read(out[0], output, sizeof(output)) <= 0)
return 1;
loc->func= s= output;
while (*s != '\n')
s++;
*s++= 0;
loc->file= s;
while (*s != ':')
s++;
*s++= 0;
loc->line= 0;
while (isdigit(*s))
loc->line = loc->line * 10 + (*s++ - '0');
*s = 0;
loc->file= strip_path(loc->file);
return 0;
}
const char *my_addr_resolve_init()
{
if (!initialized)
{
pid_t pid;
if (pipe(in) < 0)
return "pipe(in)";
if (pipe(out) < 0)
return "pipe(out)";
pid = fork();
if (pid == -1)
return "fork";
if (!pid) /* child */
{
dup2(in[0], 0);
dup2(out[1], 1);
close(in[0]);
close(in[1]);
close(out[0]);
close(out[1]);
execlp("addr2line", "addr2line", "-C", "-f", "-e", my_progname, NULL);
exit(1);
}
close(in[0]);
close(out[1]);
initialized= 1;
}
return 0;
}
#endif