mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 02:18:37 +00:00
Cleaned up the mess that was the treatment of "below main" functions such as
'__libc_start_main', in Massif, m_debuginfo and m_stacktrace. As part of this, --show-below-main is now visible to tools, and Massif pays attention to it. Improved the description of --show-below-main=yes in the manual. Replaced some instances of "__libc_start_main" in the test *.exp files with "(below main)", which is what will actually be seen. Also updated scalar.stderr.exp*, which should make it get closer to actually passing. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9131
This commit is contained in:
parent
947f9faaba
commit
a8c9970a34
@ -50,7 +50,7 @@
|
||||
#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC
|
||||
#include "pub_core_xarray.h"
|
||||
#include "pub_core_oset.h"
|
||||
#include "pub_core_stacktrace.h" // VG_(get_StackTrace)
|
||||
#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency
|
||||
|
||||
#include "priv_misc.h" /* dinfo_zalloc/free */
|
||||
#include "priv_d3basics.h" /* ML_(pp_GX) */
|
||||
@ -1111,6 +1111,7 @@ Bool get_sym_name ( Bool demangle, Addr a, Char* buf, Int nbuf,
|
||||
if (demangle) {
|
||||
VG_(demangle) ( True/*do C++ demangle*/,
|
||||
di->symtab[sno].name, buf, nbuf );
|
||||
|
||||
} else {
|
||||
VG_(strncpy_safely) ( buf, di->symtab[sno].name, nbuf );
|
||||
}
|
||||
@ -1226,6 +1227,44 @@ Bool VG_(get_fnname_Z_demangle_only) ( Addr a, Char* buf, Int nbuf )
|
||||
# undef N_TMPBUF
|
||||
}
|
||||
|
||||
Vg_FnNameKind VG_(get_fnname_kind) ( Char* name )
|
||||
{
|
||||
if (VG_STREQ("main", name)) {
|
||||
return Vg_FnNameMain;
|
||||
|
||||
} else if (
|
||||
#if defined(VGO_linux)
|
||||
VG_STREQ("__libc_start_main", name) || // glibc glibness
|
||||
VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness
|
||||
#elif defined(VGO_aix5)
|
||||
VG_STREQ("__start", name) || // AIX aches
|
||||
#else
|
||||
# error Unknown OS
|
||||
#endif
|
||||
0) {
|
||||
return Vg_FnNameBelowMain;
|
||||
|
||||
} else {
|
||||
return Vg_FnNameNormal;
|
||||
}
|
||||
}
|
||||
|
||||
Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip )
|
||||
{
|
||||
// We don't need a big buffer; all the special names are small.
|
||||
#define BUFLEN 50
|
||||
Char buf[50];
|
||||
|
||||
// We don't demangle, because it's faster not to, and the special names
|
||||
// we're looking for won't be demangled.
|
||||
if (VG_(get_fnname_nodemangle) ( ip, buf, BUFLEN )) {
|
||||
buf[BUFLEN-1] = '\0'; // paranoia
|
||||
return VG_(get_fnname_kind)(buf);
|
||||
} else {
|
||||
return Vg_FnNameNormal; // Don't know the name, treat it as normal.
|
||||
}
|
||||
}
|
||||
|
||||
/* Looks up data_addr in the collection of data symbols, and if found
|
||||
puts its name (or as much as will fit) into dname[0 .. n_dname-1],
|
||||
which is guaranteed to be zero terminated. Also data_addr's offset
|
||||
|
||||
@ -29,12 +29,13 @@
|
||||
*/
|
||||
|
||||
#include "pub_core_basics.h"
|
||||
#include "pub_core_debuginfo.h" // XXX: circular dependency
|
||||
#include "pub_core_demangle.h"
|
||||
#include "pub_core_libcassert.h"
|
||||
#include "pub_core_libcbase.h"
|
||||
#include "pub_core_libcprint.h"
|
||||
#include "pub_core_mallocfree.h"
|
||||
#include "pub_core_options.h"
|
||||
#include "pub_core_libcassert.h"
|
||||
#include "pub_core_libcprint.h"
|
||||
|
||||
#include "vg_libciface.h"
|
||||
#include "demangle.h"
|
||||
@ -121,21 +122,24 @@ void VG_(demangle) ( Bool do_cxx_demangle,
|
||||
VG_(strncpy_safely)(result, orig, result_size);
|
||||
}
|
||||
|
||||
/* Do the below-main hack */
|
||||
// 13 Mar 2005: We used to check here that the demangler wasn't leaking
|
||||
// by calling the (now-removed) function VG_(is_empty_arena)(). But,
|
||||
// very rarely (ie. I've heard of it twice in 3 years), the demangler
|
||||
// does leak. But, we can't do much about it, and it's not a disaster,
|
||||
// so we just let it slide without aborting or telling the user.
|
||||
|
||||
/* Do the below-main hack */
|
||||
// Finally, to reduce the endless nuisance of multiple different names
|
||||
// for "the frame below main()" screwing up the testsuite, change all
|
||||
// known incarnations of said into a single name, "(below main)".
|
||||
if (0==VG_(strcmp)("__libc_start_main", result)
|
||||
|| 0==VG_(strcmp)("generic_start_main", result)
|
||||
|| 0==VG_(strcmp)("__start", result)) /* on AIX */
|
||||
VG_(strncpy_safely)(result, "(below main)", 13);
|
||||
|
||||
// known incarnations of said into a single name, "(below main)", if
|
||||
// --show-below-main=yes.
|
||||
// XXX: this makes a circular dependency between m_demangle and
|
||||
// m_debuginfo.
|
||||
if ( ! VG_(clo_show_below_main) &&
|
||||
Vg_FnNameBelowMain == VG_(get_fnname_kind)(result))
|
||||
{
|
||||
VG_(strncpy_safely)(result, "(below main)", result_size);
|
||||
}
|
||||
# undef N_ZBUF
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#include "pub_core_basics.h"
|
||||
#include "pub_core_vki.h"
|
||||
#include "pub_core_threadstate.h"
|
||||
#include "pub_core_debuginfo.h"
|
||||
#include "pub_core_debuginfo.h" // XXX: circular dependency
|
||||
#include "pub_core_aspacemgr.h" // For VG_(is_addressable)()
|
||||
#include "pub_core_libcbase.h"
|
||||
#include "pub_core_libcassert.h"
|
||||
@ -531,11 +531,7 @@ void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt n_ips )
|
||||
void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
|
||||
StackTrace ips, UInt n_ips )
|
||||
{
|
||||
#define MYBUF_LEN 50 // only needs to be long enough for
|
||||
// the names specially tested for
|
||||
|
||||
Bool main_done = False;
|
||||
Char mybuf[MYBUF_LEN]; // ok to stack allocate mybuf[] -- it's tiny
|
||||
Int i = 0;
|
||||
|
||||
vg_assert(n_ips > 0);
|
||||
@ -545,16 +541,11 @@ void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
|
||||
// Stop after the first appearance of "main" or one of the other names
|
||||
// (the appearance of which is a pretty good sign that we've gone past
|
||||
// main without seeing it, for whatever reason)
|
||||
if ( ! VG_(clo_show_below_main)) {
|
||||
VG_(get_fnname_nodemangle)( ip, mybuf, MYBUF_LEN );
|
||||
mybuf[MYBUF_LEN-1] = 0; // paranoia
|
||||
if ( VG_STREQ("main", mybuf)
|
||||
# if defined(VGO_linux)
|
||||
|| VG_STREQ("__libc_start_main", mybuf) // glibc glibness
|
||||
|| VG_STREQ("generic_start_main", mybuf) // Yellow Dog doggedness
|
||||
# endif
|
||||
)
|
||||
if ( ! VG_(clo_show_below_main) ) {
|
||||
Vg_FnNameKind kind = VG_(get_fnname_kind_from_IP)(ip);
|
||||
if (Vg_FnNameMain == kind || Vg_FnNameBelowMain == kind) {
|
||||
main_done = True;
|
||||
}
|
||||
}
|
||||
|
||||
// Act on the ip
|
||||
|
||||
@ -36,7 +36,12 @@
|
||||
// Z-encoded names.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/* This is the main, standard demangler entry point. */
|
||||
/* This is the main, standard demangler entry point. It does three things:
|
||||
* (1) undoes Z-encoding;
|
||||
* (2) undoes C++ demangling, if 'do_cxx_demangle' is True
|
||||
* (3) converts "below main" names (eg. '__libc_start_main') to "(below
|
||||
* main)", if --show-below-main=no.
|
||||
*/
|
||||
|
||||
extern
|
||||
void VG_(demangle) ( Bool do_cxx_demangle,
|
||||
|
||||
@ -147,8 +147,6 @@ extern Bool VG_(clo_track_fds);
|
||||
is ignored. Ie if a tool says no, I don't want this to run, that
|
||||
cannot be overridden from the command line. */
|
||||
extern Bool VG_(clo_run_libc_freeres);
|
||||
/* Continue stack traces below main()? Default: NO */
|
||||
extern Bool VG_(clo_show_below_main);
|
||||
|
||||
/* Should we show VEX emulation warnings? Default: NO */
|
||||
extern Bool VG_(clo_show_emwarns);
|
||||
|
||||
@ -913,12 +913,18 @@ that can report errors, e.g. Memcheck, but not Cachegrind.</para>
|
||||
<listitem>
|
||||
<para>By default, stack traces for errors do not show any
|
||||
functions that appear beneath <function>main()</function>
|
||||
(or similar functions such as glibc's
|
||||
<function>__libc_start_main()</function>, if
|
||||
<function>main()</function> is not present in the stack trace);
|
||||
most of the time it's uninteresting C library stuff. If this
|
||||
option is enabled, those entries below <function>main()</function>
|
||||
will be shown.</para>
|
||||
most of the time it's uninteresting C library stuff and/or
|
||||
gobbledygook. Alternatively, if <function>main()</function> is not
|
||||
present in the stack trace, stack traces will not show any functions
|
||||
below <function>main()</function>-like functions such as glibc's
|
||||
<function>__libc_start_main()</function>). Furthermore, if
|
||||
<function>main()</function>-like functions are present in the trace,
|
||||
they are normalised as "(below main)", in order to make the output
|
||||
more deterministic.</para>
|
||||
|
||||
<para>If this option is enabled, all stack trace entries will be
|
||||
shown and <function>main()</function>-like functions will not be
|
||||
normalised.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@ -74,6 +74,19 @@ extern Bool VG_(get_filename_linenum)
|
||||
entry points within it. */
|
||||
extern Bool VG_(get_fnname_if_entry) ( Addr a, Char* fnname, Int n_fnname );
|
||||
|
||||
typedef
|
||||
enum {
|
||||
Vg_FnNameNormal, // A normal function.
|
||||
Vg_FnNameMain, // "main"
|
||||
Vg_FnNameBelowMain // Something below "main", eg. __libc_start_main.
|
||||
} Vg_FnNameKind; // Such names are often filtered.
|
||||
|
||||
/* Indicates what kind of fnname it is. */
|
||||
extern Vg_FnNameKind VG_(get_fnname_kind) ( Char* name );
|
||||
|
||||
/* Like VG_(get_fnname_kind), but takes a code address. */
|
||||
extern Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip );
|
||||
|
||||
/* Looks up data_addr in the collection of data symbols, and if found
|
||||
puts its name (or as much as will fit) into dname[0 .. n_dname-1],
|
||||
which is guaranteed to be zero terminated. Also data_addr's offset
|
||||
|
||||
@ -119,6 +119,10 @@ extern VexControl VG_(clo_vex_control);
|
||||
/* Number of parents of a backtrace. Default: 8. */
|
||||
extern Int VG_(clo_backtrace_size);
|
||||
|
||||
/* Continue stack traces below main()? Default: NO */
|
||||
extern Bool VG_(clo_show_below_main);
|
||||
|
||||
|
||||
/* Call this if a recognised option was bad for some reason. Note:
|
||||
don't use it just because an option was unrecognised -- return
|
||||
'False' from VG_(tdict).tool_process_cmd_line_option) to indicate
|
||||
|
||||
@ -1931,18 +1931,13 @@ static void pp_snapshot_SXPt(Int fd, SXPt* sxpt, Int depth, Char* depth_str,
|
||||
} else {
|
||||
// If it's main-or-below-main, we (if appropriate) ignore everything
|
||||
// below it by pretending it has no children.
|
||||
// XXX: get this properly. Also, don't hard-code "(below main)"
|
||||
// here -- look at the "(below main)"/"__libc_start_main" mess
|
||||
// (m_stacktrace.c and m_demangle.c).
|
||||
// [Nb: Josef wants --show-below-main to work for his fn entry/exit
|
||||
// tracing]
|
||||
Bool should_hide_below_main = /*!VG_(clo_show_below_main)*/True;
|
||||
if (should_hide_below_main &&
|
||||
VG_(get_fnname)(sxpt->Sig.ip, ip_desc, BUF_LEN) &&
|
||||
(VG_STREQ(ip_desc, "main") || VG_STREQ(ip_desc, "(below main)")))
|
||||
{
|
||||
sxpt->Sig.n_children = 0;
|
||||
if ( ! VG_(clo_show_below_main) ) {
|
||||
Vg_FnNameKind kind = VG_(get_fnname_kind_from_IP)(sxpt->Sig.ip);
|
||||
if (Vg_FnNameMain == kind || Vg_FnNameBelowMain == kind) {
|
||||
sxpt->Sig.n_children = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// We need the -1 to get the line number right, But I'm not sure why.
|
||||
ip_desc = VG_(describe_IP)(sxpt->Sig.ip-1, ip_desc, BUF_LEN);
|
||||
}
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
|
||||
Jump to the invalid address stated on the next line
|
||||
at 0x........: ???
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
Process terminating with default action of signal 11 (SIGSEGV)
|
||||
Access not within mapped region at address 0x........
|
||||
at 0x........: ???
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
|
||||
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: ... bytes in ... blocks.
|
||||
malloc/free: ... allocs, ... frees, ... bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -267,10 +267,8 @@ int main(void)
|
||||
GO(__NR_fcntl, "(DUPFD) 1s 0m");
|
||||
SY(__NR_fcntl, x0-1, x0+F_DUPFD, x0); FAILx(EBADF);
|
||||
|
||||
// For F_GETLK the 3rd arg is 'lock'
|
||||
// on x86, this fails with EBADF. But on amd64 in 32-bit mode
|
||||
// it fails with EFAULT.
|
||||
GO(__NR_fcntl, "(GETLK) 1s 0m");
|
||||
// For F_GETLK the 3rd arg is 'lock'. On x86, this fails w/EBADF. But on
|
||||
GO(__NR_fcntl, "(GETLK) 1s 0m"); // amd64 in 32-bit mode it fails w/EFAULT.
|
||||
SY(__NR_fcntl, x0-1, x0+F_GETLK, x0); FAIL; //FAILx(EBADF);
|
||||
|
||||
// __NR_mpx 56
|
||||
@ -976,10 +974,8 @@ int main(void)
|
||||
GO(__NR_fcntl64, "(DUPFD) 1s 0m");
|
||||
SY(__NR_fcntl64, x0-1, x0+F_DUPFD, x0); FAILx(EBADF);
|
||||
|
||||
// For F_GETLK the 3rd arg is 'lock'
|
||||
// on x86, this fails with EBADF. But on amd64 in 32-bit mode
|
||||
// it fails with EFAULT.
|
||||
GO(__NR_fcntl64, "(GETLK) 1s 0m");
|
||||
// For F_GETLK the 3rd arg is 'lock'. // On x86, this fails w/EBADF. But on
|
||||
GO(__NR_fcntl64, "(GETLK) 1s 0m"); // amd64 in 32-bit mode it fails w/EFAULT.
|
||||
SY(__NR_fcntl64, x0-1, x0+F_GETLK, x0); FAIL; //FAILx(EBADF);
|
||||
|
||||
// 222
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -281,9 +281,6 @@ Syscall param mount(target) contains uninitialised byte(s)
|
||||
at 0x........: syscall (in /...libc...)
|
||||
by 0x........: main (scalar.c:124)
|
||||
|
||||
More than 50 errors detected. Subsequent errors
|
||||
will still be recorded, but in less detail than before.
|
||||
|
||||
Syscall param mount(type) contains uninitialised byte(s)
|
||||
at 0x........: syscall (in /...libc...)
|
||||
by 0x........: main (scalar.c:124)
|
||||
@ -629,6 +626,9 @@ Syscall param fcntl(arg) contains uninitialised byte(s)
|
||||
55: __NR_fcntl (GETLK) 1s 0m
|
||||
-----------------------------------------------------
|
||||
|
||||
More than 100 errors detected. Subsequent errors
|
||||
will still be recorded, but in less detail than before.
|
||||
|
||||
Syscall param fcntl(fd) contains uninitialised byte(s)
|
||||
at 0x........: syscall (in /...libc...)
|
||||
by 0x........: main (scalar.c:272)
|
||||
@ -3983,6 +3983,8 @@ Syscall param mq_getsetattr(omqstat) points to unaddressable byte(s)
|
||||
WARNING: unhandled syscall: 9999
|
||||
You may be able to write your own handler.
|
||||
Read the file README_MISSING_SYSCALL_OR_IOCTL.
|
||||
Nevertheless we consider this a bug. Please report
|
||||
it at http://valgrind.org/support/bug_reports.html.
|
||||
-----------------------------------------------------
|
||||
1: __NR_exit 1s 0m
|
||||
-----------------------------------------------------
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
Syscall param (syscallno) contains uninitialised byte(s)
|
||||
at 0x........: syscall (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Syscall param write(fd) contains uninitialised byte(s)
|
||||
at 0x........: syscall (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Syscall param write(count) contains uninitialised byte(s)
|
||||
at 0x........: syscall (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
@ -351,7 +351,7 @@
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>__libc_start_main</fn>
|
||||
<fn>(below main)</fn>
|
||||
</frame>
|
||||
</stack>
|
||||
</error>
|
||||
|
||||
@ -351,7 +351,7 @@
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>__libc_start_main</fn>
|
||||
<fn>(below main)</fn>
|
||||
</frame>
|
||||
</stack>
|
||||
</error>
|
||||
|
||||
@ -356,7 +356,7 @@
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>__libc_start_main</fn>
|
||||
<fn>(below main)</fn>
|
||||
</frame>
|
||||
</stack>
|
||||
</error>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
FILE DESCRIPTORS: 5 open at exit.
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: dup (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: open (in /...libc...)
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
FILE DESCRIPTORS: 6 open at exit.
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: dup2 (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: dup2 (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: open (in /...libc...)
|
||||
|
||||
@ -8,7 +8,7 @@ Open file descriptor .: /dev/null
|
||||
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: open (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Open file descriptor .: .
|
||||
<inherited from parent>
|
||||
|
||||
@ -8,7 +8,7 @@ Open file descriptor .: /dev/null
|
||||
|
||||
Open file descriptor .: /dev/null
|
||||
at 0x........: open (in /...libc...)
|
||||
by 0x........: __libc_start_main (in /...libc...)
|
||||
by 0x........: (below main) (in /...libc...)
|
||||
|
||||
Open file descriptor .: .
|
||||
<inherited from parent>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user