Updates to the rest of the debuginfo module to track directory names.

The only interesting part is a change of signature of
VG_(get_filename_linenum) so that callers can optionally request
directory info too.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3909
This commit is contained in:
Julian Seward 2005-06-13 17:39:06 +00:00
parent 56b4d07c7d
commit 90e98b737e
7 changed files with 97 additions and 28 deletions

View File

@ -165,8 +165,12 @@ static Int BB_retranslations = 0;
static void get_debug_info(Addr instr_addr, Char file[FILE_LEN],
Char fn[FN_LEN], Int* line)
{
Bool found_file_line = VG_(get_filename_linenum)(instr_addr, file,
FILE_LEN, line);
Bool found_file_line = VG_(get_filename_linenum)(
instr_addr,
file, FILE_LEN,
NULL, 0, NULL,
line
);
Bool found_fn = VG_(get_fnname)(instr_addr, fn, FN_LEN);
if (!found_file_line) {

View File

@ -69,7 +69,9 @@ typedef
UShort size:LOC_SIZE_BITS; /* byte size; we catch overflows of this */
UInt lineno:LINENO_BITS; /* source line number, or zero */
/* Word 3 */
Char* filename; /* source filename */
Char* filename; /* source filename */
/* Word 4 */
Char* dirname; /* source directory name */
}
RiLoc;
@ -231,7 +233,10 @@ struct _SegInfo {
Char *VG_(addStr) ( SegInfo* si, Char* str, Int len );
void VG_(addScopeInfo) ( SegInfo* si, Addr this, Addr next, Scope *scope);
void VG_(addLineInfo) ( SegInfo* si, Char* filename, Addr this, Addr next, Int lineno, Int entry);
void VG_(addLineInfo) ( SegInfo* si,
Char* filename,
Char* dirname, /* NULL is allowable */
Addr this, Addr next, Int lineno, Int entry);
void VG_(addCfiSI) ( SegInfo* si, CfiSI* cfisi );
/* Non-fatal -- use vg_panic if terminal. */

View File

@ -1414,7 +1414,7 @@ void VG_(read_debuginfo_stabs) ( SegInfo* si,
if (line.addr != 0) {
/* finish off previous line */
VG_(addLineInfo)(si, file.name, line.addr,
VG_(addLineInfo)(si, file.name, NULL, line.addr,
addr, line.no + line.ovf * LINENO_OVERFLOW, i);
}
@ -1446,7 +1446,7 @@ void VG_(read_debuginfo_stabs) ( SegInfo* si,
if (line.addr != 0) {
/* there was a previous */
VG_(addLineInfo)(si, file.name, line.addr,
VG_(addLineInfo)(si, file.name, NULL, line.addr,
addr, line.no + line.ovf * LINENO_OVERFLOW, i);
}
@ -1555,7 +1555,7 @@ void VG_(read_debuginfo_stabs) ( SegInfo* si,
}
if (line.addr) {
VG_(addLineInfo)(si, file.name, line.addr,
VG_(addLineInfo)(si, file.name, NULL, line.addr,
addr, line.no + line.ovf * LINENO_OVERFLOW, i);
line.addr = 0;
}

View File

@ -248,11 +248,12 @@ void addLoc ( SegInfo* si, RiLoc* loc )
void VG_(addLineInfo) ( SegInfo* si,
Char* filename,
Char* dirname, /* NULL == directory is unknown */
Addr this,
Addr next,
Int lineno,
Int entry /* only needed for debug printing */
)
)
{
static const Bool debug = False;
RiLoc loc;
@ -262,7 +263,9 @@ void VG_(addLineInfo) ( SegInfo* si,
if (this == next) return;
if (debug)
VG_(printf)(" src %s line %d %p-%p\n", filename, lineno, this, next);
VG_(printf)( " src %s %s line %d %p-%p\n",
dirname ? dirname : (Char*)"(unknown)",
filename, lineno, this, next );
/* Maximum sanity checking. Some versions of GNU as do a shabby
* job with stabs entries; if anything looks suspicious, revert to
@ -314,6 +317,7 @@ void VG_(addLineInfo) ( SegInfo* si,
loc.size = (UShort)size;
loc.lineno = lineno;
loc.filename = filename;
loc.dirname = dirname;
if (0) VG_(message)(Vg_DebugMsg,
"addLoc: addr %p, size %d, line %d, file %s",
@ -2242,21 +2246,43 @@ Bool VG_(get_linenum)( Addr a, UInt* lineno )
return True;
}
/* Map a code address to a (filename, line number) pair.
Returns True if successful.
/* Map a code address to a filename/line number/dir name info.
See prototype for detailed description of behaviour.
*/
Bool VG_(get_filename_linenum)( Addr a,
Char* filename, Int n_filename,
UInt* lineno )
Bool VG_(get_filename_linenum) ( Addr a,
/*OUT*/Char* filename, Int n_filename,
/*OUT*/Char* dirname, Int n_dirname,
/*OUT*/Bool* dirname_available,
/*OUT*/UInt* lineno )
{
SegInfo* si;
Int locno;
vg_assert( (dirname == NULL && dirname_available == NULL)
||
(dirname != NULL && dirname_available != NULL) );
search_all_loctabs ( a, &si, &locno );
if (si == NULL)
return False;
VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
*lineno = si->loctab[locno].lineno;
if (dirname) {
/* caller wants directory info too .. */
vg_assert(n_dirname > 0);
if (si->loctab[locno].dirname) {
/* .. and we have some */
*dirname_available = True;
VG_(strncpy_safely)(dirname, si->loctab[locno].dirname,
n_dirname);
} else {
/* .. but we don't have any */
*dirname_available = False;
*dirname = 0;
}
}
return True;
}
@ -2267,7 +2293,7 @@ Bool VG_(get_filename_linenum)( Addr a,
static Addr regaddr_from_tst(Int regno, ThreadArchState *arch)
{
#if defined(VGA_x86)
/* This is the Intel register encoding -- integer regs. */
/* This is the Intel register encoding -- integer regs. */
# define R_STACK_PTR 4
# define R_FRAME_PTR 5
switch (regno) {
@ -2282,7 +2308,7 @@ static Addr regaddr_from_tst(Int regno, ThreadArchState *arch)
default: return 0;
}
#elif defined(VGA_amd64)
/* This is the Intel register encoding -- integer regs. */
/* This is the AMD64 register encoding -- integer regs. */
# define R_STACK_PTR 7
# define R_FRAME_PTR 6
switch (regno) {
@ -2358,7 +2384,8 @@ Variable *VG_(get_scope_variables)(ThreadId tid)
Char file[100];
Int line;
if (!VG_(get_filename_linenum)(sr->addr, file, sizeof(file), &line))
if (!VG_(get_filename_linenum)(sr->addr, file, sizeof(file),
NULL, 0, NULL, &line))
file[0] = 0;
VG_(printf)("found scope range %p: eip=%p (%s:%d) size=%d scope=%p\n",
@ -2366,7 +2393,9 @@ Variable *VG_(get_scope_variables)(ThreadId tid)
}
distance = 0;
for(scope = si->scopetab[scopeidx].scope; scope != NULL; scope = scope->outer, distance++) {
for (scope = si->scopetab[scopeidx].scope;
scope != NULL;
scope = scope->outer, distance++) {
UInt i;
for(i = 0; i < scope->nsyms; i++) {
@ -2435,6 +2464,10 @@ Variable *VG_(get_scope_variables)(ThreadId tid)
return list;
}
# undef R_STACK_PTR
# undef R_FRAME_PTR
#endif /* TEST */
/* Print into buf info on code address, function name and filename */
@ -2477,11 +2510,16 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf)
static UChar buf_fn[BUF_LEN];
static UChar buf_obj[BUF_LEN];
static UChar buf_srcloc[BUF_LEN];
static UChar buf_dirname[BUF_LEN];
Bool know_dirinfo = False;
Bool know_fnname = VG_(get_fnname) (eip, buf_fn, BUF_LEN);
Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN);
Bool know_srcloc = VG_(get_filename_linenum)(eip, buf_srcloc,
BUF_LEN, &lineno);
Bool know_srcloc = VG_(get_filename_linenum)(
eip,
buf_srcloc, BUF_LEN,
buf_dirname, BUF_LEN, &know_dirinfo,
&lineno
);
if (VG_(clo_xml)) {
Bool human_readable = True;
@ -2506,6 +2544,12 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf)
APPEND("</fn>");
}
if (know_srcloc) {
if (know_dirinfo) {
APPEND(maybe_newline);
APPEND("<dir>");
APPEND(buf_dirname);
APPEND("</dir>");
}
APPEND(maybe_newline);
APPEND("<file>");
APPEND_ESC(buf_srcloc);
@ -2552,6 +2596,7 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf)
# undef APPEND
# undef APPEND_ESC
# undef BUF_LEN
}
/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */

View File

@ -737,7 +737,8 @@ Char *VG_(describe_addr)(ThreadId tid, Addr addr)
if (debug) {
Char file[100];
Int line;
if (!VG_(get_filename_linenum)(eip, file, sizeof(file), &line))
if (!VG_(get_filename_linenum)(eip, file, sizeof(file),
NULL, 0, NULL, &line))
file[0] = 0;
VG_(printf)("describing address %p for tid=%d @ %s:%d\n", addr, tid, file, line);
}
@ -1047,7 +1048,8 @@ Char *VG_(describe_addr)(ThreadId tid, Addr addr)
if (addr != found->valuep)
bprintf(describe_addr_addbuf, 0, "+%d", addr - found->valuep);
if (VG_(get_filename_linenum)(eip, file, sizeof(file), &line))
if (VG_(get_filename_linenum)(eip, file, sizeof(file),
NULL, 0, NULL, &line))
bprintf(describe_addr_addbuf, 0, " at %s:%d", file, line, addr);
}
}

View File

@ -2730,7 +2730,8 @@ static void hg_pp_Error ( Error* err )
pp_state(extra->lasttouched.state),
unpackTLS(extra->lasttouched.tls)->tid);
if (VG_(get_filename_linenum)(ip, file, sizeof(file), &line)) {
if (VG_(get_filename_linenum)(ip, file, sizeof(file),
NULL, 0, NULL, &line)) {
VG_(message)(Vg_UserMsg, " at %p: %y (%s:%u)",
ip, ip, file, line);
} else if (VG_(get_objname)(ip, file, sizeof(file))) {

View File

@ -47,11 +47,23 @@ extern Bool VG_(get_linenum) ( Addr a, UInt* linenum );
extern Bool VG_(get_fnname_w_offset)
( Addr a, Char* fnname, Int n_fnname );
/* This one is more efficient if getting both filename and line number,
because the two lookups are done together. */
/* This one is the most general. It gives filename, line number and
optionally directory name. filename and linenum may not be NULL.
dirname may be NULL, meaning that the caller does not want
directory name info, in which case dirname_available must also be
NULL. If dirname is non-null, directory info is written to it, if
it is available; if not available, '\0' is written to the first
byte. In either case *dirname_available is set to indicate whether
or not directory information was available.
Returned value indicates whether any filename/line info could be
found. */
extern Bool VG_(get_filename_linenum)
( Addr a, Char* filename, Int n_filename,
UInt* linenum );
( Addr a,
/*OUT*/Char* filename, Int n_filename,
/*OUT*/Char* dirname, Int n_dirname,
/*OUT*/Bool* dirname_available,
/*OUT*/UInt* linenum );
/* Succeeds only if we find from debug info that 'a' is the address of the
first instruction in a function -- as opposed to VG_(get_fnname) which