#include "pub_core_stacks.h"
#include "pub_core_stacktrace.h"
#include "pub_core_syscall.h"
+#include "pub_core_syswrap.h"
#include "pub_core_tooliface.h" // For VG_(details).{name,bug_reports_to}
#include "pub_core_options.h" // For VG_(clo_xml)
static void print_thread_state (Bool stack_usage,
const HChar* prefix, ThreadId i)
{
- VgStack *stack
+ VgStack *stack
= (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
-
- VG_(printf)("\n%sThread %d: status = %s (lwpid %d)\n", prefix, i,
+ HChar syscallno[50];
+ // must be large enough for VG_SYSNUM_STRING result + 10.
+
+ if (VG_(is_in_syscall) (i))
+ VG_(sprintf)(syscallno, " syscall %s",
+ VG_SYSNUM_STRING(VG_(is_in_syscall_no)(i)));
+ else
+ syscallno[0] = 0;
+ VG_(printf)("\n%sThread %d: status = %s%s (lwpid %d)\n", prefix, i,
VG_(name_of_ThreadStatus)(VG_(threads)[i].status),
+ syscallno,
VG_(threads)[i].os_state.lwpid);
if (VG_(threads)[i].status != VgTs_Empty)
VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH );
if (stack_usage && VG_(threads)[i].client_stack_highest_byte != 0 ) {
Addr start, end;
-
+
start = end = 0;
VG_(stack_limits)(VG_(get_SP)(i), &start, &end);
if (start != end)
}
if (stack_usage && stack != 0)
VG_(printf)
- ("%svalgrind stack top usage: %lu of %lu\n",
+ ("%svalgrind stack range: [%p %p] top usage: %lu of %lu\n",
prefix,
+ (void*)stack, (void*)((Addr)stack + VG_(clo_valgrind_stacksize) - 1),
VG_(clo_valgrind_stacksize)
- VG_(am_get_VgStack_unused_szB) (stack,
VG_(clo_valgrind_stacksize)),
/* The scheduler needs to be able to zero out these records after a
fork, hence this is exported from m_syswrap. */
-void VG_(clear_syscallInfo) ( Int tid )
+void VG_(clear_syscallInfo) ( ThreadId tid )
{
vg_assert(syscallInfo);
vg_assert(tid >= 0 && tid < VG_N_THREADS);
syscallInfo[tid].status.what = SsIdle;
}
-Bool VG_(is_in_syscall) ( Int tid )
+Bool VG_(is_in_syscall) ( ThreadId tid )
{
vg_assert(tid >= 0 && tid < VG_N_THREADS);
return (syscallInfo[tid].status.what != SsIdle);
}
+Word VG_(is_in_syscall_no) (ThreadId tid )
+{
+ vg_assert(tid >= 0 && tid < VG_N_THREADS);
+ return syscallInfo[tid].orig_args.sysno;
+}
+
static void ensure_initialised ( void )
{
Int i;
extern void VG_(post_syscall) ( ThreadId tid );
/* Clear this module's private state for thread 'tid' */
-extern void VG_(clear_syscallInfo) ( Int tid );
+extern void VG_(clear_syscallInfo) ( ThreadId tid );
// Returns True if the given thread is currently in a system call
-extern Bool VG_(is_in_syscall) ( Int tid );
+extern Bool VG_(is_in_syscall) ( ThreadId tid );
+
+// If VG_(is_in_syscall) (tid), returns the sysno the given thread is in
+extern Word VG_(is_in_syscall_no) (ThreadId tid );
// Fix up a thread's state when syscall is interrupted by a signal.
extern void VG_(fixup_guest_state_after_syscall_interrupted)(