summaryrefslogtreecommitdiff
path: root/addr2line.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-03-25 23:55:39 (GMT)
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-03-25 23:55:39 (GMT)
commit633b2fc9d738ff11b28f2cd85abb73fbc85ee091 (patch)
treece3098adef368fcb66263e6b23013e54d694a77c /addr2line.c
parentdf0034f89002c38bee77e17f2fd5a0502d902460 (diff)
* addr2line.c (fill_lines): don't run fill_lines multiple times.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'addr2line.c')
-rw-r--r--addr2line.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/addr2line.c b/addr2line.c
index cda6744..4a5a24d 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -489,20 +489,20 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
fd = open(binary_filename, O_RDONLY);
if (fd < 0) {
- return;
+ goto fail;
}
filesize = lseek(fd, 0, SEEK_END);
if (filesize < 0) {
int e = errno;
close(fd);
kprintf("lseek: %s\n", strerror(e));
- return;
+ goto fail;
}
#if SIZEOF_OFF_T > SIZEOF_SIZE_T
if (filesize > (off_t)SIZE_MAX) {
close(fd);
kprintf("Too large file %s\n", binary_filename);
- return;
+ goto fail;
}
#endif
lseek(fd, 0, SEEK_SET);
@@ -512,7 +512,7 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
int e = errno;
close(fd);
kprintf("mmap: %s\n", strerror(e));
- return;
+ goto fail;
}
ehdr = (ElfW(Ehdr) *)file;
@@ -522,7 +522,7 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
* it match non-elf file.
*/
close(fd);
- return;
+ goto fail;
}
current_line->fd = fd;
@@ -534,13 +534,11 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
shstr_shdr = shdr + ehdr->e_shstrndx;
shstr = file + shstr_shdr->sh_offset;
- if (ehdr->e_type == ET_EXEC) {
- /*
- * if object file type is ET_EXEC, base address must be 0
- */
- intptr_t current_base_addr = current_line->base_addr;
- for (i = 0; i < num_traces; i++) {
- if (current_base_addr == lines[i].base_addr) {
+ for (i = offset; i < num_traces; i++) {
+ if (current_line->base_addr == lines[i].base_addr) {
+ lines[i].line = -1;
+ if (ehdr->e_type == ET_EXEC) {
+ /* if object type is ET_EXEC, base address must be 0 */
lines[i].base_addr = 0;
}
}
@@ -576,12 +574,11 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
for (j = 0; j < symtab_count; j++) {
ElfW(Sym) *sym = &symtab[j];
int type = ELF_ST_TYPE(sym->st_info);
- intptr_t saddr = (intptr_t)sym->st_value + lines[offset].base_addr;
+ intptr_t saddr = (intptr_t)sym->st_value + current_line->base_addr;
if (type != STT_FUNC) continue;
for (i = offset; i < num_traces; i++) {
intptr_t d = (intptr_t)traces[i] - saddr;
- const char *path = lines[i].path;
- if (!path || strcmp(lines[offset].path, path) != 0)
+ if (lines[i].line != -1)
continue;
if (d <= 0 || d > (intptr_t)sym->st_size)
continue;
@@ -601,13 +598,27 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
num_traces, traces, syms,
current_line, lines, offset);
}
- return;
+ goto finish;
}
parse_debug_line(num_traces, traces,
file + debug_line_shdr->sh_offset,
debug_line_shdr->sh_size,
lines);
+finish:
+ for (i = offset; i < num_traces; i++) {
+ if (lines[i].line == -1) {
+ lines[i].line = -2;
+ }
+ }
+ return;
+fail:
+ for (i = offset; i < num_traces; i++) {
+ if (current_line->base_addr == lines[i].base_addr) {
+ lines[i].line = -2;
+ }
+ }
+ return;
}
void
@@ -666,7 +677,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces, char **syms)
const char *path = NULL;
size_t len;
- if (lines[i].line > 0) continue;
+ if (lines[i].line) continue;
if (lines[i].path) {
path = lines[i].path;