[#42564] [Ruby 1.9-Feature#4043][Open] グローバル関数current_classの提案 — Makoto Kishimoto <redmine@...>

Feature #4043: =E3=82=B0=E3=83=AD=E3=83=BC=E3=83=90=E3=83=AB=E9=96=A2=E6=95=

15 messages 2010/11/11
[#42774] Re: [Ruby 1.9-Feature#4043][Open] グローバル関数current_classの提案 — Yukihiro Matsumoto <matz@...> 2010/12/16

まつもと ゆきひろです

[#42834] Re: [Ruby 1.9-Feature#4043][Open] グローバル関数current_classの提案 — "KISHIMOTO, Makoto" <ksmakoto@...4u.or.jp> 2010/12/21

きしもとです

[#42835] Re: [Ruby 1.9-Feature#4043][Open] グローバル関数current_classの提案 — Yukihiro Matsumoto <matz@...> 2010/12/21

まつもと ゆきひろです

[#42838] Re: [Ruby 1.9-Feature#4043][Open] グローバル関数current_classの提案 — "KISHIMOTO, Makoto" <ksmakoto@...4u.or.jp> 2010/12/21

きしもとです

[#42845] Re: [Ruby 1.9-Feature#4043][Open] グローバル関数current_classの提案 — Yukihiro Matsumoto <matz@...> 2010/12/21

まつもと ゆきひろです

[#42577] Rubyのバグレポートのガイドライン — "Shota Fukumori (sora_h)" <sorah@...>

sora_hです。

11 messages 2010/11/15
[#42588] Re: Rubyのバグレポートのガイドライン — Yugui <yugui@...> 2010/11/18

2010/11/15 Shota Fukumori (sora_h) <sorah@tubusu.net>:

[#42638] Enumerable#categorize — Tanaka Akira <akr@...>

enumerable から hash を生成するメソッドとして

25 messages 2010/11/27
[#42643] Re: Enumerable#categorize — Yukihiro Matsumoto <matz@...> 2010/11/27

まつもと ゆきひろです

[ruby-dev:42655] [Ruby 1.9-Feature#4096][Open] Follow .gnu_debuglink section.

From: Shinichiro Hamaji <redmine@...>
Date: 2010-11-29 01:38:36 UTC
List: ruby-dev #42655
Feature #4096: Follow .gnu_debuglink section.
http://redmine.ruby-lang.org/issues/show/4096

起票者: Shinichiro Hamaji
ステータス: Open, 優先度: Normal

浜地です。

先日取り込んでいただいた行情報のパッチですが、
ディストリビューションなんかが配布する ruby バイナリは、

# debug 情報を持っていない
/usr/bin/ruby
# debug 情報を持っている
# debug package をインストールした場合に存在する。
/usr/lib/debug/usr/bin/ruby

とかいう感じで二つに別れています。
バグレポートする人の中には debug package を入れている人も
いるかもしれませんし、これに対応するのは一定の価値があるかもなぁ
ということで書いたパッチです。

Subject: [PATCH] Follow .gnu_debuglink section.

With this patch, a user of distribution provided ruby will see line
info if s/he has a debug package for ruby.
---
 addr2line.c |   97 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 70 insertions(+), 27 deletions(-)

diff --git a/addr2line.c b/addr2line.c
index 443333f..97bd652 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -382,14 +382,71 @@ parse_debug_line(int num_traces, void **traces,
 
 /* read file and fill lines */
 static void
-fill_lines(int num_traces, void **traces, char **syms,
-	   char *file, line_info_t *lines)
+fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
+	   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;
     char *shstr;
     char *section_name;
     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++) {
 	const char *path;
@@ -411,11 +468,19 @@ fill_lines(int num_traces, void **traces, char **syms,
 	if (!strcmp(section_name, ".debug_line")) {
 	    debug_line_shdr = shdr + i;
 	    break;
+	} else if (!strcmp(section_name, ".gnu_debuglink")) {
+	    gnu_debuglink_shdr = shdr + i;
 	}
     }
 
     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;
     }
 
@@ -458,12 +523,9 @@ void
 rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
 {
     int i;
-    int fd;
     /* async-signal unsafe */
     line_info_t *lines = (line_info_t *)calloc(num_traces,
 					       sizeof(line_info_t));
-    off_t filesize;
-    char *file;
 
     /* Note that line info of shared objects might not be shown
        if we don't have dl_iterate_phdr */
@@ -491,26 +553,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
 	strncpy(binary_filename, path, len);
 	binary_filename[len] = '\0';
 
-	fd = open(binary_filename, O_RDONLY);
-	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);
+	fill_lines(num_traces, trace, syms, 1, &lines[i], lines);
     }
 
     /* fprintf may not be async-signal safe */
-- 
1.7.2.3


----------------------------------------
http://redmine.ruby-lang.org

In This Thread

Prev Next