[前][次][番号順一覧][スレッド一覧]

ruby-changes:33346

From: naruse <ko1@a...>
Date: Wed, 26 Mar 2014 13:30:49 +0900 (JST)
Subject: [ruby-changes:33346] naruse:r45425 (trunk): * addr2line.c (fill_lines): loop reverse order not to overwrite

naruse	2014-03-26 13:30:43 +0900 (Wed, 26 Mar 2014)

  New Revision: 45425

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45425

  Log:
    * addr2line.c (fill_lines): loop reverse order not to overwrite
      the basis of base addresses comparison.
    
    * addr2line.c: use uintptr_t instead of intptr_t for poinrters.
    
    * addr2line.c (rb_dump_backtrace_with_lines): don't use syms.
    
    * vm_dump.c (rb_print_backtrace): ditto.
    
    * addr2line.h: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/addr2line.c
    trunk/addr2line.h
    trunk/vm_dump.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45424)
+++ ChangeLog	(revision 45425)
@@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Mar 26 13:25:54 2014  NARUSE, Yui  <naruse@r...>
+
+	* addr2line.c (fill_lines): loop reverse order not to overwrite
+	  the basis of base addresses comparison.
+
+	* addr2line.c: use uintptr_t instead of intptr_t for poinrters.
+
+	* addr2line.c (rb_dump_backtrace_with_lines): don't use syms.
+
+	* vm_dump.c (rb_print_backtrace): ditto.
+
+	* addr2line.h: ditto.
+
 Wed Mar 26 11:20:50 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* marshal.c (w_object): internal objects are not dumpable.
Index: addr2line.c
===================================================================
--- addr2line.c	(revision 45424)
+++ addr2line.c	(revision 45425)
@@ -111,8 +111,8 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/addr2line.c#L111
     int fd2;
     void *mapped2;
     size_t mapped_size2;
-    intptr_t base_addr;
-    intptr_t saddr;
+    uintptr_t base_addr;
+    uintptr_t saddr;
     const char *sname; /* function name */
 } line_info_t;
 
@@ -207,35 +207,15 @@ fill_filename(int file, char *include_di https://github.com/ruby/ruby/blob/trunk/addr2line.c#L207
     }
 }
 
-static int
-get_path_from_symbol(const char *symbol, const char **p, size_t *len)
-{
-    if (symbol[0] == '0') {
-	/* libexecinfo */
-	*p   = strchr(symbol, '/');
-	if (*p == NULL) return 0;
-	*len = strlen(*p);
-    }
-    else {
-	/* glibc */
-	const char *q;
-	*p   = symbol;
-	q   = strchr(symbol, '(');
-	if (q == NULL) return 0;
-	*len = q - symbol;
-    }
-    return 1;
-}
-
 static void
 fill_line(int num_traces, void **traces,
-	  intptr_t addr, int file, int line,
+	  uintptr_t addr, int file, int line,
 	  char *include_directories, char *filenames, line_info_t *lines, int offset)
 {
     int i;
     addr += lines[offset].base_addr;
     for (i = offset; i < num_traces; i++) {
-	intptr_t a = (intptr_t)traces[i];
+	uintptr_t a = (uintptr_t)traces[i];
 	/* We assume one line code doesn't result >100 bytes of native code.
        We may want more reliable way eventually... */
 	if (addr < a && a < addr + 100) {
@@ -434,11 +414,11 @@ parse_debug_line(int num_traces, void ** https://github.com/ruby/ruby/blob/trunk/addr2line.c#L414
 
 /* read file and fill lines */
 static void
-fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
+fill_lines(int num_traces, void **traces, int check_debuglink,
 	   line_info_t *current_line, line_info_t *lines, int offset);
 
 static void
-follow_debuglink(char *debuglink, int num_traces, void **traces, char **syms,
+follow_debuglink(char *debuglink, int num_traces, void **traces,
 		 line_info_t *current_line, line_info_t *lines, int offset)
 {
     /* Ideally we should check 4 paths to follow gnu_debuglink,
@@ -467,12 +447,12 @@ follow_debuglink(char *debuglink, int nu https://github.com/ruby/ruby/blob/trunk/addr2line.c#L447
     current_line->mapped2 = current_line->mapped;
     current_line->mapped_size2 = current_line->mapped_size;
     current_line->fd2 = current_line->fd;
-    fill_lines(num_traces, traces, syms, 0, current_line, lines, offset);
+    fill_lines(num_traces, traces, 0, current_line, lines, offset);
 }
 
 /* read file and fill lines */
 static void
-fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
+fill_lines(int num_traces, void **traces, int check_debuglink,
 	   line_info_t *current_line, line_info_t *lines, int offset)
 {
     int i, j;
@@ -534,7 +514,8 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L514
     shstr_shdr = shdr + ehdr->e_shstrndx;
     shstr = file + shstr_shdr->sh_offset;
 
-    for (i = offset; i < num_traces; i++) {
+    /* reverse order not to overwrite current_line->base_addr */
+    for (i = num_traces-1; i >= offset; i--) {
 	if (current_line->base_addr == lines[i].base_addr) {
 	    lines[i].line = -1;
 	    if (ehdr->e_type == ET_EXEC) {
@@ -577,16 +558,14 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L558
 	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 + current_line->base_addr;
+	    uintptr_t saddr = (uintptr_t)sym->st_value + current_line->base_addr;
 	    if (type != STT_FUNC) continue;
 #ifdef __powerpc64__
 	kprintf("%s %lx %lx\n",strtab + sym->st_name,sym->st_value,sym->st_size);
 #endif
 	    for (i = offset; i < num_traces; i++) {
-		intptr_t d = (intptr_t)traces[i] - saddr;
-		if (lines[i].line != -1)
-		    continue;
-		if (d <= 0 || d > (intptr_t)sym->st_size)
+		uintptr_t d = (uintptr_t)traces[i] - saddr;
+		if (lines[i].line != -1 || d <= 0 || d > (uintptr_t)sym->st_size)
 		    continue;
 		/* fill symbol name and addr from .symtab */
 		lines[i].sname = strtab + sym->st_name;
@@ -601,7 +580,7 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L580
 	   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,
+			     num_traces, traces,
 			     current_line, lines, offset);
 	}
 	goto finish;
@@ -628,7 +607,7 @@ fail: https://github.com/ruby/ruby/blob/trunk/addr2line.c#L607
 }
 
 void
-rb_dump_backtrace_with_lines(int num_traces, void **traces, char **syms)
+rb_dump_backtrace_with_lines(int num_traces, void **traces)
 {
     int i;
     /* async-signal unsafe */
@@ -637,14 +616,14 @@ rb_dump_backtrace_with_lines(int num_tra https://github.com/ruby/ruby/blob/trunk/addr2line.c#L616
 #ifdef HAVE_DLADDR
 # ifdef __linux__
 #  define PROC_SELF_EXE "/proc/self/exe"
-    intptr_t main_fbase;
+    uintptr_t main_fbase;
     char *main_path;
     {
 	Dl_info info;
 	void *handle = dlopen(NULL, RTLD_LAZY);
 	void *sym = dlsym(handle, "_start");
 	dladdr(sym, &info);
-	main_fbase = (intptr_t)info.dli_fbase;
+	main_fbase = (uintptr_t)info.dli_fbase;
     }
     {
 	ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
@@ -659,7 +638,7 @@ rb_dump_backtrace_with_lines(int num_tra https://github.com/ruby/ruby/blob/trunk/addr2line.c#L638
 	Dl_info info;
 	if (dladdr(traces[i], &info)) {
 	    /* this may set base addr even if executable is not shared object file */
-	    lines[i].base_addr = (intptr_t)info.dli_fbase;
+	    lines[i].base_addr = (uintptr_t)info.dli_fbase;
 # ifdef __linux__
 	    if (lines[i].base_addr == main_fbase) {
 		lines[i].path = main_path;
@@ -673,7 +652,7 @@ rb_dump_backtrace_with_lines(int num_tra https://github.com/ruby/ruby/blob/trunk/addr2line.c#L652
 	    lines[i].line = 0;
 	    if (info.dli_saddr) {
 		lines[i].sname = info.dli_sname;
-		lines[i].saddr = (intptr_t)info.dli_saddr;
+		lines[i].saddr = (uintptr_t)info.dli_saddr;
 	    }
 	}
     }
@@ -690,9 +669,6 @@ rb_dump_backtrace_with_lines(int num_tra https://github.com/ruby/ruby/blob/trunk/addr2line.c#L669
 	    path = lines[i].path;
 	    len = strlen(path);
 	}
-	else if (syms[i] && get_path_from_symbol(syms[i], &path, &len)) {
-	    lines[i].path = path;
-	}
 	else {
 	    continue;
 	}
@@ -700,47 +676,39 @@ rb_dump_backtrace_with_lines(int num_tra https://github.com/ruby/ruby/blob/trunk/addr2line.c#L676
 	strncpy(binary_filename, path, len);
 	binary_filename[len] = '\0';
 
-	fill_lines(num_traces, traces, syms, 1, &lines[i], lines, i);
+	fill_lines(num_traces, traces, 1, &lines[i], lines, i);
     }
 
     /* output */
     for (i = 0; i < num_traces; i++) {
 	line_info_t *line = &lines[i];
-
-	if (line->sname) {
-	    intptr_t addr = (intptr_t)traces[i];
-	    intptr_t d = addr - line->saddr;
-	    if (line->line <= 0) {
-		kprintf("%s(%s+0x%lx) [0x%lx]\n", line->path, line->sname,
-			d, addr);
-	    }
-	    else if (!line->filename) {
-		kprintf("%s(%s+0x%lx) [0x%lx] ???:%d\n", line->path, line->sname,
-			d, addr, line->line);
-	    }
-	    else if (line->dirname && line->dirname[0]) {
-		kprintf("%s(%s+0x%lx) [0x%lx] %s/%s:%d\n", line->path, line->sname,
-			d, addr, line->dirname, line->filename, line->line);
-	    }
-	    else {
-		kprintf("%s(%s+0x%lx) [0x%lx] %s:%d\n", line->path, line->sname,
-			d, addr, line->filename, line->line);
-	    }
-	    /* FreeBSD's backtrace may show _start and so on */
-	    if (strcmp("main", line->sname) == 0)
-		break;
+	uintptr_t addr = (uintptr_t)traces[i];
+	uintptr_t d = addr - line->saddr;
+	if (!line->path) {
+	    kprintf("[0x%lx]\n", addr);
+	}
+	else if (!line->saddr || !line->sname) {
+	    kprintf("%s [0x%lx]\n", line->path, addr);
 	}
 	else if (line->line <= 0) {
-	    kprintf("%s\n", syms[i]);
+	    kprintf("%s(%s+0x%lx) [0x%lx]\n", line->path, line->sname,
+		    d, addr);
 	}
 	else if (!line->filename) {
-	    kprintf("%s ???:%d\n", syms[i], line->line);
-	} else if (line->dirname && line->dirname[0]) {
-	    kprintf("%s %s/%s:%d\n", syms[i], line->dirname, line->filename, line->line);
+	    kprintf("%s(%s+0x%lx) [0x%lx] ???:%d\n", line->path, line->sname,
+		    d, addr, line->line);
+	}
+	else if (line->dirname && line->dirname[0]) {
+	    kprintf("%s(%s+0x%lx) [0x%lx] %s/%s:%d\n", line->path, line->sname,
+		    d, addr, line->dirname, line->filename, line->line);
 	}
 	else {
-	    kprintf("%s %s:%d\n", syms[i], line->filename, line->line);
+	    kprintf("%s(%s+0x%lx) [0x%lx] %s:%d\n", line->path, line->sname,
+		    d, addr, line->filename, line->line);
 	}
+	/* FreeBSD's backtrace may show _start and so on */
+	if (line->sname && strcmp("main", line->sname) == 0)
+	    break;
     }
 
     /* free */
Index: addr2line.h
===================================================================
--- addr2line.h	(revision 45424)
+++ addr2line.h	(revision 45425)
@@ -14,7 +14,7 @@ https://github.com/ruby/ruby/blob/trunk/addr2line.h#L14
 #ifdef USE_ELF
 
 void
-rb_dump_backtrace_with_lines(int num_traces, void **traces, char **syms);
+rb_dump_backtrace_with_lines(int num_traces, void **traces);
 
 #endif /* USE_ELF */
 
Index: vm_dump.c
===================================================================
--- vm_dump.c	(revision 45424)
+++ vm_dump.c	(revision 45425)
@@ -683,19 +683,18 @@ rb_print_backtrace(void) https://github.com/ruby/ruby/blob/trunk/vm_dump.c#L683
 #define MAX_NATIVE_TRACE 1024
     static void *trace[MAX_NATIVE_TRACE];
     int n = backtrace(trace, MAX_NATIVE_TRACE);
-    char **syms = backtrace_symbols(trace, n);
-
-    if (syms) {
 #ifdef USE_ELF
-	rb_dump_backtrace_with_lines(n, trace, syms);
+    rb_dump_backtrace_with_lines(n, trace);
 #else
+    char **syms = backtrace_symbols(trace, n);
+    if (syms) {
 	int i;
 	for (i=0; i<n; i++) {
 	    fprintf(stderr, "%s\n", syms[i]);
 	}
-#endif
 	free(syms);
     }
+#endif
 #elif defined(_WIN32)
     DWORD tid = GetCurrentThreadId();
     HANDLE th = (HANDLE)_beginthread(dump_thread, 0, &tid);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]