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

ruby-changes:33506

From: naruse <ko1@a...>
Date: Mon, 14 Apr 2014 19:08:11 +0900 (JST)
Subject: [ruby-changes:33506] naruse:r45587 (trunk): * addr2line.c (fill_lines): get base addrs in fill_lines to use it

naruse	2014-04-14 19:08:04 +0900 (Mon, 14 Apr 2014)

  New Revision: 45587

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

  Log:
    * addr2line.c (fill_lines): get base addrs in fill_lines to use it
      with dladdr_fbases introduced at r45563.
      it didn't get before if the executalbe is not pie.

  Modified files:
    trunk/ChangeLog
    trunk/addr2line.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45586)
+++ ChangeLog	(revision 45587)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Apr 14 18:44:45 2014  NARUSE, Yui  <naruse@r...>
+
+	* addr2line.c (fill_lines): get base addrs in fill_lines to use it
+	  with dladdr_fbases introduced at r45563.
+	  it didn't get before if the executalbe is not pie.
+
 Mon Apr 14 18:05:48 2014  NARUSE, Yui  <naruse@r...>
 
 	* addr2line.c (main_exe_path): support FreeBSD.
Index: addr2line.c
===================================================================
--- addr2line.c	(revision 45586)
+++ addr2line.c	(revision 45587)
@@ -417,7 +417,7 @@ parse_debug_line(int num_traces, void ** https://github.com/ruby/ruby/blob/trunk/addr2line.c#L417
 }
 
 /* read file and fill lines */
-static void
+static uintptr_t
 fill_lines(int num_traces, void **traces, int check_debuglink,
 	   obj_info_t **objp, line_info_t *lines, int offset);
 
@@ -459,7 +459,7 @@ follow_debuglink(char *debuglink, int nu https://github.com/ruby/ruby/blob/trunk/addr2line.c#L459
 }
 
 /* read file and fill lines */
-static void
+static uintptr_t
 fill_lines(int num_traces, void **traces, int check_debuglink,
 	   obj_info_t **objp, line_info_t *lines, int offset)
 {
@@ -475,23 +475,24 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L475
     ElfW(Shdr) *symtab_shdr = NULL, *strtab_shdr = NULL;
     ElfW(Shdr) *dynsym_shdr = NULL, *dynstr_shdr = NULL;
     obj_info_t *obj = *objp;
+    uintptr_t dladdr_fbase = 0;
 
     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);
@@ -501,7 +502,7 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L502
 	int e = errno;
 	close(fd);
 	kprintf("mmap: %s\n", strerror(e));
-	return;
+	goto fail;
     }
 
     ehdr = (ElfW(Ehdr) *)file;
@@ -511,10 +512,9 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L512
 	 * it match non-elf file.
 	 */
 	close(fd);
-	return;
+	goto fail;
     }
 
-    if (ehdr->e_type == ET_EXEC) obj->base_addr = 0;
     obj->fd = fd;
     obj->mapped = file;
     obj->mapped_size = (size_t)filesize;
@@ -557,8 +557,7 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L557
     if (offset == -1) {
 	/* main executable */
 	offset = 0;
-	if (ehdr->e_type != ET_EXEC && dynsym_shdr && dynstr_shdr) {
-	    /* PIE (position-independent executable) */
+	if (dynsym_shdr && dynstr_shdr) {
 	    char *strtab = file + dynstr_shdr->sh_offset;
 	    ElfW(Sym) *symtab = (ElfW(Sym) *)(file + dynsym_shdr->sh_offset);
 	    int symtab_count = (int)(dynsym_shdr->sh_size / sizeof(ElfW(Sym)));
@@ -572,11 +571,18 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L571
 		s = dlsym(h, strtab + sym->st_name);
 		if (!s) continue;
 		if (dladdr(s, &info)) {
-		    obj->base_addr = (uintptr_t)info.dli_fbase;
+		    dladdr_fbase = (uintptr_t)info.dli_fbase;
 		    break;
 		}
 	    }
-	} /* otherwise, base address is 0 */
+	    if (ehdr->e_type == ET_EXEC) {
+		obj->base_addr = 0;
+	    }
+	    else {
+		/* PIE (position-independent executable) */
+		obj->base_addr = dladdr_fbase;
+	    }
+	}
     }
 
     if (!symtab_shdr) {
@@ -613,13 +619,17 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L619
 			     num_traces, traces,
 			     objp, lines, offset);
 	}
-	return;
+	goto finish;
     }
 
     parse_debug_line(num_traces, traces,
 		     file + debug_line_shdr->sh_offset,
 		     debug_line_shdr->sh_size,
 		     obj, lines, offset);
+finish:
+    return dladdr_fbase;
+fail:
+    return (uintptr_t)-1;
 }
 
 #define HAVE_MAIN_EXE_PATH
@@ -674,23 +684,13 @@ rb_dump_backtrace_with_lines(int num_tra https://github.com/ruby/ruby/blob/trunk/addr2line.c#L684
     if ((len = main_exe_path()) > 0) {
 	main_path = (char *)alloca(len + 1);
 	if (main_path) {
-	    obj_info_t *o;
+	    uintptr_t addr;
 	    memcpy(main_path, binary_filename, len+1);
 	    append_obj(&obj);
-	    o = obj; /* obj may be chaneged with gnu_debuglink */
 	    obj->path = main_path;
-	    fill_lines(num_traces, traces, 1, &obj, lines, -1);
-
-	    /* set dladdr.dli_fbase */
-	    if (o->base_addr) { /* PIE */
-		dladdr_fbases[0] = (void *)o->base_addr;
-	    }
-	    else { /* non PIE */
-		/* base addr is 0, but get dli_fbase to skip with dladdr */
-		Dl_info info;
-		if (dladdr(traces[i], &info)) {
-		    dladdr_fbases[0] = info.dli_fbase;
-		}
+	    addr = fill_lines(num_traces, traces, 1, &obj, lines, -1);
+	    if (addr != (uintptr_t)-1) {
+		dladdr_fbases[0] = (void *)addr;
 	    }
 	}
     }

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

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