mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Avoid to record execontext used for origin tracking when --trac-origins=no
All calls to VG_(unknown_SP_update) were recording an execontext of one IP, useful only for track origin. This patch implements splits VG_(unknown_SP_update) in two different functions VG_(unknown_SP_update_w_ECU) (doing origin tracking) and VG_(unknown_SP_update) (not doing origin tracking). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13225
This commit is contained in:
parent
ee6b67bd79
commit
8817a79c9d
@ -285,7 +285,10 @@ void VG_(acquire_BigLock)(ThreadId tid, const HChar* who)
|
||||
VG_(running_tid) = tid;
|
||||
|
||||
{ Addr gsp = VG_(get_SP)(tid);
|
||||
VG_(unknown_SP_update)(gsp, gsp, 0/*unknown origin*/);
|
||||
if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
|
||||
VG_(unknown_SP_update_w_ECU)(gsp, gsp, 0/*unknown origin*/);
|
||||
else
|
||||
VG_(unknown_SP_update)(gsp, gsp);
|
||||
}
|
||||
|
||||
if (VG_(clo_trace_sched)) {
|
||||
|
||||
@ -268,59 +268,97 @@ void VG_(stack_limits)(Addr SP, Addr *start, Addr *end )
|
||||
}
|
||||
}
|
||||
|
||||
/* This function gets called if new_mem_stack and/or die_mem_stack are
|
||||
|
||||
/* complaints_stack_switch reports that SP has changed by more than some
|
||||
threshold amount (by default, 2MB). We take this to mean that the
|
||||
application is switching to a new stack, for whatever reason.
|
||||
|
||||
JRS 20021001: following discussions with John Regehr, if a stack
|
||||
switch happens, it seems best not to mess at all with memory
|
||||
permissions. Seems to work well with Netscape 4.X. Really the
|
||||
only remaining difficulty is knowing exactly when a stack switch is
|
||||
happening. */
|
||||
__attribute__((noinline))
|
||||
static void complaints_stack_switch (Addr old_SP, Addr new_SP)
|
||||
{
|
||||
static Int complaints = 3;
|
||||
if (VG_(clo_verbosity) > 0 && complaints > 0 && !VG_(clo_xml)) {
|
||||
Word delta = (Word)new_SP - (Word)old_SP;
|
||||
complaints--;
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"Warning: client switching stacks? "
|
||||
"SP change: 0x%lx --> 0x%lx\n", old_SP, new_SP);
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" to suppress, use: --max-stackframe=%ld "
|
||||
"or greater\n",
|
||||
(delta < 0 ? -delta : delta));
|
||||
if (complaints == 0)
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" further instances of this message "
|
||||
"will not be shown.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* The functions VG_(unknown_SP_update) and VG_(unknown_SP_update_w_ECU)
|
||||
get called if new_mem_stack and/or die_mem_stack are
|
||||
tracked by the tool, and one of the specialised cases
|
||||
(eg. new_mem_stack_4) isn't used in preference.
|
||||
*/
|
||||
|
||||
These functions are performance critical, so are built with macros. */
|
||||
|
||||
// preamble + check if stack has switched.
|
||||
#define IF_STACK_SWITCH_SET_current_task_AND_RETURN \
|
||||
Word delta = (Word)new_SP - (Word)old_SP; \
|
||||
\
|
||||
/* Check if the stack pointer is still in the same stack as before. */ \
|
||||
if (UNLIKELY(current_stack == NULL || \
|
||||
new_SP < current_stack->start || new_SP > current_stack->end)) { \
|
||||
Stack* new_stack = find_stack_by_addr(new_SP); \
|
||||
if (new_stack \
|
||||
&& (current_stack == NULL || new_stack->id != current_stack->id)) { \
|
||||
/* The stack pointer is now in another stack. Update the current */ \
|
||||
/* stack information and return without doing anything else. */ \
|
||||
current_stack = new_stack; \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define IF_BIG_DELTA_complaints_AND_RETURN \
|
||||
if (UNLIKELY(delta < -VG_(clo_max_stackframe) \
|
||||
|| VG_(clo_max_stackframe) < delta)) { \
|
||||
complaints_stack_switch(old_SP, new_SP); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define IF_SMALLER_STACK_die_mem_stack_AND_RETURN \
|
||||
if (delta > 0) { \
|
||||
VG_TRACK( die_mem_stack, old_SP, delta ); \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
VG_REGPARM(3)
|
||||
void VG_(unknown_SP_update)( Addr old_SP, Addr new_SP, UInt ecu )
|
||||
{
|
||||
static Int moans = 3;
|
||||
Word delta = (Word)new_SP - (Word)old_SP;
|
||||
|
||||
/* Check if the stack pointer is still in the same stack as before. */
|
||||
if (current_stack == NULL ||
|
||||
new_SP < current_stack->start || new_SP > current_stack->end) {
|
||||
Stack* new_stack = find_stack_by_addr(new_SP);
|
||||
if (new_stack
|
||||
&& (current_stack == NULL || new_stack->id != current_stack->id)) {
|
||||
/* The stack pointer is now in another stack. Update the current
|
||||
stack information and return without doing anything else. */
|
||||
current_stack = new_stack;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (delta < -VG_(clo_max_stackframe) || VG_(clo_max_stackframe) < delta) {
|
||||
/* SP has changed by more than some threshold amount (by
|
||||
default, 2MB). We take this to mean that the application is
|
||||
switching to a new stack, for whatever reason.
|
||||
|
||||
JRS 20021001: following discussions with John Regehr, if a stack
|
||||
switch happens, it seems best not to mess at all with memory
|
||||
permissions. Seems to work well with Netscape 4.X. Really the
|
||||
only remaining difficulty is knowing exactly when a stack switch is
|
||||
happening. */
|
||||
if (VG_(clo_verbosity) > 0 && moans > 0 && !VG_(clo_xml)) {
|
||||
moans--;
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"Warning: client switching stacks? "
|
||||
"SP change: 0x%lx --> 0x%lx\n", old_SP, new_SP);
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" to suppress, use: --max-stackframe=%ld or greater\n",
|
||||
(delta < 0 ? -delta : delta));
|
||||
if (moans == 0)
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" further instances of this message "
|
||||
"will not be shown.\n");
|
||||
}
|
||||
} else if (delta < 0) {
|
||||
void VG_(unknown_SP_update_w_ECU)( Addr old_SP, Addr new_SP, UInt ecu ) {
|
||||
IF_STACK_SWITCH_SET_current_task_AND_RETURN;
|
||||
IF_BIG_DELTA_complaints_AND_RETURN;
|
||||
IF_SMALLER_STACK_die_mem_stack_AND_RETURN;
|
||||
if (delta < 0) { // IF_BIGGER_STACK
|
||||
VG_TRACK( new_mem_stack_w_ECU, new_SP, -delta, ecu );
|
||||
VG_TRACK( new_mem_stack, new_SP, -delta );
|
||||
|
||||
} else if (delta > 0) {
|
||||
VG_TRACK( die_mem_stack, old_SP, delta );
|
||||
return;
|
||||
}
|
||||
// SAME_STACK. nothing to do.
|
||||
}
|
||||
|
||||
VG_REGPARM(2)
|
||||
void VG_(unknown_SP_update)( Addr old_SP, Addr new_SP ) {
|
||||
IF_STACK_SWITCH_SET_current_task_AND_RETURN;
|
||||
IF_BIG_DELTA_complaints_AND_RETURN;
|
||||
IF_SMALLER_STACK_die_mem_stack_AND_RETURN;
|
||||
if (delta < 0) { // IF_BIGGER_STACK
|
||||
VG_TRACK( new_mem_stack, new_SP, -delta );
|
||||
return;
|
||||
}
|
||||
// SAME_STACK. nothing to do.
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
#include "pub_core_redir.h" // VG_(redir_do_lookup)
|
||||
|
||||
#include "pub_core_signals.h" // VG_(synth_fault_{perms,mapping}
|
||||
#include "pub_core_stacks.h" // VG_(unknown_SP_update)()
|
||||
#include "pub_core_stacks.h" // VG_(unknown_SP_update*)()
|
||||
#include "pub_core_tooliface.h" // VG_(tdict)
|
||||
|
||||
#include "pub_core_translate.h"
|
||||
@ -524,16 +524,25 @@ IRSB* vg_SP_update_pass ( void* closureV,
|
||||
/* Now we know what the old value of SP is. But knowing the new
|
||||
value is a bit tricky if there is a partial write. */
|
||||
if (first_Put == first_SP && last_Put == last_SP) {
|
||||
/* The common case, an exact write to SP. So st->Ist.Put.data
|
||||
does hold the new value; simple. */
|
||||
/* The common case, an exact write to SP. So st->Ist.Put.data
|
||||
does hold the new value; simple. */
|
||||
vg_assert(curr_IP_known);
|
||||
dcall = unsafeIRDirty_0_N(
|
||||
3/*regparms*/,
|
||||
"VG_(unknown_SP_update)",
|
||||
VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
|
||||
mkIRExprVec_3( IRExpr_RdTmp(old_SP), st->Ist.Put.data,
|
||||
mk_ecu_Expr(curr_IP) )
|
||||
);
|
||||
if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
|
||||
dcall = unsafeIRDirty_0_N(
|
||||
3/*regparms*/,
|
||||
"VG_(unknown_SP_update_w_ECU)",
|
||||
VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update_w_ECU) ),
|
||||
mkIRExprVec_3( IRExpr_RdTmp(old_SP), st->Ist.Put.data,
|
||||
mk_ecu_Expr(curr_IP) )
|
||||
);
|
||||
else
|
||||
dcall = unsafeIRDirty_0_N(
|
||||
2/*regparms*/,
|
||||
"VG_(unknown_SP_update)",
|
||||
VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
|
||||
mkIRExprVec_2( IRExpr_RdTmp(old_SP), st->Ist.Put.data )
|
||||
);
|
||||
|
||||
addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
|
||||
/* don't forget the original assignment */
|
||||
addStmtToIRSB( bb, st );
|
||||
@ -562,14 +571,23 @@ IRSB* vg_SP_update_pass ( void* closureV,
|
||||
addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP) ));
|
||||
/* 4 */
|
||||
vg_assert(curr_IP_known);
|
||||
dcall = unsafeIRDirty_0_N(
|
||||
3/*regparms*/,
|
||||
"VG_(unknown_SP_update)",
|
||||
VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
|
||||
mkIRExprVec_3( IRExpr_RdTmp(old_SP),
|
||||
IRExpr_RdTmp(new_SP),
|
||||
mk_ecu_Expr(curr_IP) )
|
||||
);
|
||||
if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
|
||||
dcall = unsafeIRDirty_0_N(
|
||||
3/*regparms*/,
|
||||
"VG_(unknown_SP_update_w_ECU)",
|
||||
VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update_w_ECU) ),
|
||||
mkIRExprVec_3( IRExpr_RdTmp(old_SP),
|
||||
IRExpr_RdTmp(new_SP),
|
||||
mk_ecu_Expr(curr_IP) )
|
||||
);
|
||||
else
|
||||
dcall = unsafeIRDirty_0_N(
|
||||
2/*regparms*/,
|
||||
"VG_(unknown_SP_update)",
|
||||
VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
|
||||
mkIRExprVec_2( IRExpr_RdTmp(old_SP),
|
||||
IRExpr_RdTmp(new_SP) )
|
||||
);
|
||||
addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
|
||||
/* 5 */
|
||||
addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP) ));
|
||||
|
||||
@ -42,7 +42,10 @@ extern void VG_(change_stack) ( UWord id, Addr start, Addr end );
|
||||
extern void VG_(stack_limits) ( Addr SP, Addr *start, Addr *end );
|
||||
|
||||
extern VG_REGPARM(3)
|
||||
void VG_(unknown_SP_update) ( Addr old_SP, Addr new_SP, UInt otag );
|
||||
void VG_(unknown_SP_update_w_ECU)
|
||||
( Addr old_SP, Addr new_SP, UInt ecu );
|
||||
extern VG_REGPARM(2)
|
||||
void VG_(unknown_SP_update) ( Addr old_SP, Addr new_SP );
|
||||
|
||||
#endif // __PUB_CORE_STACKS_H
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user