[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] [patch] Fixup start_ip in unw_get_proc_info when no dw
From: |
Mark Wielaard |
Subject: |
[Libunwind-devel] [patch] Fixup start_ip in unw_get_proc_info when no dwarf info |
Date: |
Tue, 02 Oct 2007 15:42:40 +0200 |
Hi,
We use the following patch in frysk for unw_get_proc_info to get the
correct start_ip when dwarf_make_proc_info fails. In that case we need
to adjust the start_ip using unw_get_proc_name to get the right
procedure start. Since we are only interested in the offset this patch
also makes it so that a NULL bufp can be provided to unw_get_proc_name
(including a small documentation update). This way the base address
returned by unw_get_proc_info can always be reliably used in combination
with later offsets returned by unw_get_proc_name (without this patch
there is no way to know whether or not to use the offset because both
unw_get_proc_info and unw_get_proc_name seem to succeed just fine).
2006-09-16 Alexandre Oliva <address@hidden>
* src/x86/Gget_proc_info.c (unw_get_proc_info): Use
unw_get_proc_name to build a proper proc_info_t.
* src/x86_64/Gget_proc_info.c (unw_get_proc_info): Likewise.
* src/hppa/Gget_proc_info.c (unw_get_proc_info): Likewise.
2006-09-27 Alexandre Oliva <address@hidden>
* src/elfxx.c (lookup_symbol): Cope with NULL buf and zero buf_len.
* src/mi/Gget_proc_name.c (intern_string, get_proc_name): Likewise.
* src/hppa/Gget_proc_info.c (unw_get_proc_info): Use it.
* src/x86/Gget_proc_info.c (unw_get_proc_info): Likewise.
* src/x86_64/Gget_proc_info.c (unw_get_proc_info): Likewise.
* doc/unw_get_proc_name.tex: Document NULL buf and zero buf_len.
* doc/unw_create_addr_space.tex (get_proc_name): Likewise.
* doc/unw_get_proc_name.man: Rebuilt.
* doc/unw_create_addr_space.man: Likewise.
This doesn't introduce any test suite regressions (x86).
Cheers,
Mark
diff -r 5b0998e37265 doc/unw_create_addr_space.man
--- a/doc/unw_create_addr_space.man Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_create_addr_space.man Tue Oct 02 15:27:25 2007 +0200
@@ -413,6 +413,19 @@ pointed to by offp
(assuming the procedure is at least 0x80
bytes long).
.PP
+If bufp
+is NULL
+, buf_len
+is still verified to fit
+and offp
+is set. Passing buf_len
+as zero to indicate no
+limits on the buffer length is only safe if buf
+is NULL
+,
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
+.PP
On successful completion, the get_proc_name()
call\-back must
return zero. Otherwise, the negative value of one of the
diff -r 5b0998e37265 doc/unw_create_addr_space.tex
--- a/doc/unw_create_addr_space.tex Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_create_addr_space.tex Tue Oct 02 15:27:25 2007 +0200
@@ -229,6 +229,12 @@ pointed to by \Var{offp} (assuming the p
pointed to by \Var{offp} (assuming the procedure is at least 0x80
bytes long).
+If \Var{bufp} is \Const{NULL}, \Var{buf\_len} is still verified to fit
+and \Var{offp} is set. Passing \Var{buf\_len} as zero to indicate no
+limits on the buffer length is only safe if \Var{buf} is \Const{NULL},
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
+
On successful completion, the \Func{get\_proc\_name}() call-back must
return zero. Otherwise, the negative value of one of the
\Type{unw\_error\_t} error-codes may be returned.
diff -r 5b0998e37265 doc/unw_get_proc_name.man
--- a/doc/unw_get_proc_name.man Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_get_proc_name.man Tue Oct 02 15:27:25 2007 +0200
@@ -53,6 +53,19 @@ return a value of 0x80 in the word point
return a value of 0x80 in the word pointed to by offp
(assuming
the procedure is at least 0x80 bytes long).
+.PP
+If bufp
+is NULL
+, buf_len
+is still verified to fit
+and offp
+is set. Passing buf_len
+as zero to indicate no
+limits on the buffer length is only safe if buf
+is NULL
+,
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
.PP
Note that on some platforms there is no reliable way to distinguish
between procedure names and ordinary labels. Furthermore, if symbol
diff -r 5b0998e37265 doc/unw_get_proc_name.tex
--- a/doc/unw_get_proc_name.tex Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_get_proc_name.tex Tue Oct 02 15:27:25 2007 +0200
@@ -28,6 +28,12 @@ stack frame with an instruction-pointer
stack frame with an instruction-pointer value of 0x40003080 would
return a value of 0x80 in the word pointed to by \Var{offp} (assuming
the procedure is at least 0x80 bytes long).
+
+If \Var{bufp} is \Const{NULL}, \Var{buf\_len} is still verified to fit
+and \Var{offp} is set. Passing \Var{buf\_len} as zero to indicate no
+limits on the buffer length is only safe if \Var{buf} is \Const{NULL},
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
Note that on some platforms there is no reliable way to distinguish
between procedure names and ordinary labels. Furthermore, if symbol
diff -r 5b0998e37265 src/elfxx.c
--- a/src/elfxx.c Mon Sep 24 13:00:13 2007 +0200
+++ b/src/elfxx.c Tue Oct 02 15:27:25 2007 +0200
@@ -110,9 +110,13 @@ elf_w (lookup_symbol) (unw_addr_space_t
if ((Elf_W (Addr)) (ip - val) < min_dist)
{
min_dist = (Elf_W (Addr)) (ip - val);
- strncpy (buf, strtab + sym->st_name, buf_len);
- buf[buf_len - 1] = '\0';
- if (strlen (strtab + sym->st_name) >= buf_len)
+ buf_len--;
+ if (buf)
+ {
+ strncpy (buf, strtab + sym->st_name, buf_len);
+ buf[buf_len] = '\0';
+ }
+ if (strlen (strtab + sym->st_name) > buf_len)
ret = -UNW_ENOMEM;
}
}
diff -r 5b0998e37265 src/hppa/Gget_proc_info.c
--- a/src/hppa/Gget_proc_info.c Mon Sep 24 13:00:13 2007 +0200
+++ b/src/hppa/Gget_proc_info.c Tue Oct 02 15:27:25 2007 +0200
@@ -36,8 +36,13 @@ unw_get_proc_info (unw_cursor_t *cursor,
are missing DWARF unwind info. We don't want to fail in that
case, because those frames are uninteresting and just mark
the end of the frame-chain anyhow. */
+ unw_word_t offset;
+
+ if (unw_get_proc_name (cursor, NULL, 0, &offset) < 0)
+ offset = 0;
+
memset (pi, 0, sizeof (*pi));
- pi->start_ip = c->dwarf.ip;
+ pi->start_ip = c->dwarf.ip - offset;
pi->end_ip = c->dwarf.ip + 4;
return 0;
}
diff -r 5b0998e37265 src/mi/Gget_proc_name.c
--- a/src/mi/Gget_proc_name.c Mon Sep 24 13:00:13 2007 +0200
+++ b/src/mi/Gget_proc_name.c Tue Oct 02 15:27:25 2007 +0200
@@ -33,16 +33,25 @@ intern_string (unw_addr_space_t as, unw_
size_t i;
int ret;
- for (i = 0; i < buf_len; ++i)
+ buf_len--;
+
+ for (i = 0; i <= buf_len; ++i)
{
- if ((ret = fetch8 (as, a, &addr, (int8_t *) buf + i, arg)) < 0)
+ int8_t c, *p = buf ? (int8_t *)buf + i : &c;
+
+ if ((ret = fetch8 (as, a, &addr, p, arg)) < 0)
return ret;
- if (buf[i] == '\0')
+ if (*p == '\0')
return 0; /* copied full string; return success */
}
- buf[buf_len - 1] = '\0'; /* ensure string is NUL terminated */
- return -UNW_ENOMEM;
+ if (buf)
+ {
+ buf[buf_len] = '\0'; /* ensure string is NUL terminated */
+ return -UNW_ENOMEM;
+ }
+ else
+ return 0;
}
static inline int
@@ -53,7 +62,8 @@ get_proc_name (unw_addr_space_t as, unw_
unw_proc_info_t pi;
int ret;
- buf[0] = '\0'; /* always return a valid string, even if it's empty */
+ if (buf)
+ buf[0] = '\0'; /* always return a valid string, even if it's empty */
ret = unwi_find_dynamic_proc_info (as, ip, &pi, 1, arg);
if (ret == 0)
diff -r 5b0998e37265 src/x86/Gget_proc_info.c
--- a/src/x86/Gget_proc_info.c Mon Sep 24 13:00:13 2007 +0200
+++ b/src/x86/Gget_proc_info.c Tue Oct 02 15:27:25 2007 +0200
@@ -35,8 +35,13 @@ unw_get_proc_info (unw_cursor_t *cursor,
/* On x86, it's relatively common to be missing DWARF unwind
info. We don't want to fail in that case, because the
frame-chain still would let us do a backtrace at least. */
+ unw_word_t offset;
+
+ if (unw_get_proc_name (cursor, NULL, 0, &offset) < 0)
+ offset = 0;
+
memset (pi, 0, sizeof (*pi));
- pi->start_ip = c->dwarf.ip;
+ pi->start_ip = c->dwarf.ip - offset;
pi->end_ip = c->dwarf.ip + 1;
return 0;
}
diff -r 5b0998e37265 src/x86_64/Gget_proc_info.c
--- a/src/x86_64/Gget_proc_info.c Mon Sep 24 13:00:13 2007 +0200
+++ b/src/x86_64/Gget_proc_info.c Tue Oct 02 15:39:43 2007 +0200
@@ -38,8 +38,13 @@ unw_get_proc_info (unw_cursor_t *cursor,
are missing DWARF unwind info. We don't want to fail in that
case, because those frames are uninteresting and just mark
the end of the frame-chain anyhow. */
+ unw_word_t offset;
+
+ if (unw_get_proc_name (cursor, NULL, 0, &offset) < 0)
+ offset = 0;
+
memset (pi, 0, sizeof (*pi));
- pi->start_ip = c->dwarf.ip;
+ pi->start_ip = c->dwarf.ip - offset;
pi->end_ip = c->dwarf.ip + 1;
return 0;
}
- [Libunwind-devel] [patch] Fixup start_ip in unw_get_proc_info when no dwarf info,
Mark Wielaard <=