* addr2line.c: Follow .gnu_debuglink section.
A user of distribution provided ruby will see line info if s/he has a debug package for ruby. patched by Shinichiro Hamaji [ruby-dev:42655] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29987 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3632f4cf1c
commit
22b2c63855
@ -1,3 +1,10 @@
|
|||||||
|
Wed Dec 1 09:28:27 2010 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
|
* addr2line.c: Follow .gnu_debuglink section.
|
||||||
|
A user of distribution provided ruby will see line
|
||||||
|
info if s/he has a debug package for ruby.
|
||||||
|
patched by Shinichiro Hamaji [ruby-dev:42655]
|
||||||
|
|
||||||
Wed Dec 1 07:42:42 2010 Ryan Davis <ryand-ruby@zenspider.com>
|
Wed Dec 1 07:42:42 2010 Ryan Davis <ryand-ruby@zenspider.com>
|
||||||
|
|
||||||
* lib/minitest/*.rb: Imported minitest 2.0.0 r5952.
|
* lib/minitest/*.rb: Imported minitest 2.0.0 r5952.
|
||||||
@ -23,7 +30,7 @@ Tue Nov 30 16:29:19 2010 NARUSE, Yui <naruse@ruby-lang.org>
|
|||||||
|
|
||||||
* vm_dump.c: undef HAVE_BACKTRACE when the OS is FreeBSD (in other
|
* vm_dump.c: undef HAVE_BACKTRACE when the OS is FreeBSD (in other
|
||||||
words backtrace() is libexecinfo) and it is optimized.
|
words backtrace() is libexecinfo) and it is optimized.
|
||||||
This temporary hack should be also applied to other libexecinfo
|
This temporary hack may be also applied to other libexecinfo
|
||||||
environments.
|
environments.
|
||||||
|
|
||||||
Tue Nov 30 16:23:23 2010 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue Nov 30 16:23:23 2010 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
97
addr2line.c
97
addr2line.c
@ -386,14 +386,71 @@ parse_debug_line(int num_traces, void **traces,
|
|||||||
|
|
||||||
/* read file and fill lines */
|
/* read file and fill lines */
|
||||||
static void
|
static void
|
||||||
fill_lines(int num_traces, void **traces, char **syms,
|
fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
|
||||||
char *file, line_info_t *lines)
|
line_info_t *current_line, line_info_t *lines);
|
||||||
|
|
||||||
|
static void
|
||||||
|
follow_debuglink(char *debuglink, int num_traces, void **traces, char **syms,
|
||||||
|
line_info_t *current_line, line_info_t *lines)
|
||||||
|
{
|
||||||
|
/* Ideally we should check 4 paths to follow gnu_debuglink,
|
||||||
|
but we handle only one case for now as this format is used
|
||||||
|
by some linux distributions. See GDB's info for detail. */
|
||||||
|
static const char global_debug_dir[] = "/usr/lib/debug";
|
||||||
|
char *p, *subdir;
|
||||||
|
|
||||||
|
p = strrchr(binary_filename, '/');
|
||||||
|
if (!p) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p[1] = '\0';
|
||||||
|
|
||||||
|
subdir = (char *)alloca(strlen(binary_filename) + 1);
|
||||||
|
strcpy(subdir, binary_filename);
|
||||||
|
strcpy(binary_filename, global_debug_dir);
|
||||||
|
strncat(binary_filename, subdir,
|
||||||
|
PATH_MAX - strlen(binary_filename) - 1);
|
||||||
|
strncat(binary_filename, debuglink,
|
||||||
|
PATH_MAX - strlen(binary_filename) - 1);
|
||||||
|
|
||||||
|
munmap(current_line->mapped, current_line->mapped_size);
|
||||||
|
close(current_line->fd);
|
||||||
|
fill_lines(num_traces, traces, syms, 0, current_line, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read file and fill lines */
|
||||||
|
static void
|
||||||
|
fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
|
||||||
|
line_info_t *current_line, line_info_t *lines)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *shstr;
|
char *shstr;
|
||||||
char *section_name;
|
char *section_name;
|
||||||
ElfW(Ehdr) *ehdr;
|
ElfW(Ehdr) *ehdr;
|
||||||
ElfW(Shdr) *shdr, *shstr_shdr, *debug_line_shdr = NULL;
|
ElfW(Shdr) *shdr, *shstr_shdr;
|
||||||
|
ElfW(Shdr) *debug_line_shdr = NULL, *gnu_debuglink_shdr = NULL;
|
||||||
|
int fd;
|
||||||
|
off_t filesize;
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
fd = open(binary_filename, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
filesize = lseek(fd, 0, SEEK_END);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
/* async-signal unsafe */
|
||||||
|
file = (char *)mmap(NULL, filesize, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
if (file == MAP_FAILED) {
|
||||||
|
int e = errno;
|
||||||
|
close(fd);
|
||||||
|
fprintf(stderr, "mmap: %s\n", strerror(e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_line->fd = fd;
|
||||||
|
current_line->mapped = file;
|
||||||
|
current_line->mapped_size = filesize;
|
||||||
|
|
||||||
for (i = 0; i < num_traces; i++) {
|
for (i = 0; i < num_traces; i++) {
|
||||||
const char *path;
|
const char *path;
|
||||||
@ -415,11 +472,19 @@ fill_lines(int num_traces, void **traces, char **syms,
|
|||||||
if (!strcmp(section_name, ".debug_line")) {
|
if (!strcmp(section_name, ".debug_line")) {
|
||||||
debug_line_shdr = shdr + i;
|
debug_line_shdr = shdr + i;
|
||||||
break;
|
break;
|
||||||
|
} else if (!strcmp(section_name, ".gnu_debuglink")) {
|
||||||
|
gnu_debuglink_shdr = shdr + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!debug_line_shdr) {
|
if (!debug_line_shdr) {
|
||||||
/* this file doesn't have .debug_line section */
|
/* This file doesn't have .debug_line section,
|
||||||
|
let's check .gnu_debuglink section instead. */
|
||||||
|
if (gnu_debuglink_shdr && check_debuglink) {
|
||||||
|
follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
|
||||||
|
num_traces, traces, syms,
|
||||||
|
current_line, lines);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,12 +527,9 @@ void
|
|||||||
rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
|
rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fd;
|
|
||||||
/* async-signal unsafe */
|
/* async-signal unsafe */
|
||||||
line_info_t *lines = (line_info_t *)calloc(num_traces,
|
line_info_t *lines = (line_info_t *)calloc(num_traces,
|
||||||
sizeof(line_info_t));
|
sizeof(line_info_t));
|
||||||
off_t filesize;
|
|
||||||
char *file;
|
|
||||||
|
|
||||||
/* Note that line info of shared objects might not be shown
|
/* Note that line info of shared objects might not be shown
|
||||||
if we don't have dl_iterate_phdr */
|
if we don't have dl_iterate_phdr */
|
||||||
@ -495,26 +557,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
|
|||||||
strncpy(binary_filename, path, len);
|
strncpy(binary_filename, path, len);
|
||||||
binary_filename[len] = '\0';
|
binary_filename[len] = '\0';
|
||||||
|
|
||||||
fd = open(binary_filename, O_RDONLY);
|
fill_lines(num_traces, trace, syms, 1, &lines[i], lines);
|
||||||
if (fd < 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
filesize = lseek(fd, 0, SEEK_END);
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
/* async-signal unsafe */
|
|
||||||
file = (char *)mmap(NULL, filesize, PROT_READ, MAP_SHARED, fd, 0);
|
|
||||||
if (file == MAP_FAILED) {
|
|
||||||
int e = errno;
|
|
||||||
close(fd);
|
|
||||||
fprintf(stderr, "mmap: %s\n", strerror(e));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lines[i].fd = fd;
|
|
||||||
lines[i].mapped = file;
|
|
||||||
lines[i].mapped_size = filesize;
|
|
||||||
|
|
||||||
fill_lines(num_traces, trace, syms, file, lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf may not be async-signal safe */
|
/* fprintf may not be async-signal safe */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user