|
From: Jeremy F. <je...@go...> - 2005-01-15 02:05:20
|
CVS commit by fitzhardinge:
Misc changes needed so that Valgrind can run itself.
M +4 -0 coregrind/core.h 1.57
M +2 -2 coregrind/stage1.c 1.31
M +3 -11 coregrind/vg_main.c 1.231
M +4 -2 coregrind/vg_messages.c 1.17
M +4 -3 coregrind/vg_procselfmaps.c 1.16
M +8 -2 coregrind/vg_scheduler.c 1.205
M +54 -24 coregrind/vg_signals.c 1.107
M +12 -2 coregrind/vg_symtab2.c 1.97
M +17 -9 coregrind/vg_syscalls.c 1.229
M +23 -20 coregrind/vg_transtab.c 1.37
M +14 -2 coregrind/linux/core_os.c 1.2
M +4 -4 include/x86-linux/vki_arch.h 1.10
--- valgrind/coregrind/vg_syscalls.c #1.228:1.229
@@ -118,5 +118,5 @@ Bool VG_(valid_client_addr)(Addr start,
return True;
- if (cl_base < 0x10000)
+ if (0 && cl_base < 0x10000)
cl_base = 0x10000;
@@ -893,5 +893,7 @@ static Addr do_brk(Addr newbrk)
VG_(brk_base), VG_(brk_limit), newbrk);
- if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
+ if (newbrk < VG_(brk_base) || /* too low */
+ newbrk >= VG_(client_end) || /* too high */
+ (newbrk - VG_(brk_base)) > VG_(client_rlimit_data).rlim_cur) /* out of limits */
return VG_(brk_limit);
@@ -916,5 +918,4 @@ static Addr do_brk(Addr newbrk)
/* new brk in a new page - fix the mappings */
if (newbrk > VG_(brk_limit)) {
-
if (debug)
VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
@@ -4334,4 +4335,12 @@ PRE(sys_open, MayBlock)
}
PRE_MEM_RASCIIZ( "open(filename)", arg1 );
+
+ if (VG_(strcmp)((Char *)arg1, "/proc/self/exe") == 0) {
+ Char name[20];
+ VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
+
+ set_result(VG_(open)(name, arg2, arg3));
+ *flags |= Done;
+ }
}
@@ -4473,5 +4482,5 @@ PRE(sys_readlink, Special)
set_result( VG_(do_syscall)(saved, arg1, arg2, arg3));
if ((Int)SYSRES == -2) {
- char name[25];
+ Char name[25];
VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
@@ -5337,5 +5346,5 @@ PRE(sys_rt_sigtimedwait, MayBlock)
PRE_MEM_WRITE( "rt_sigtimedwait(info)", arg2, sizeof(vki_siginfo_t) );
PRE_MEM_READ( "rt_sigtimedwait(timeout)",
- arg4, sizeof(struct vki_timespec) );
+ arg3, sizeof(struct vki_timespec) );
}
@@ -5861,7 +5870,6 @@ void VG_(client_syscall) ( ThreadId tid
(sys->before)(tst->tid, tst, &flags);
- if ((Word)SYSRES <= 0) {
- /* "before" decided the syscall wasn't viable, so don't do
- anything - just pretend the syscall happened. */
+ if ((Word)SYSRES <= 0 || (flags & Done)) {
+ /* "before" did the syscall, so don't do anything else. */
PRINT(" ==> %lld (0x%llx)\n", (Long)(Word)SYSRES, (ULong)SYSRES);
} else if (mayBlock) {
--- valgrind/coregrind/core.h #1.56:1.57
@@ -838,4 +838,7 @@ extern void VG_(resume_scheduler) ( Thre
extern vki_sigset_t VG_(blocked_mask);
+/* Highest signal the kernel will let us use */
+extern Int VG_(max_signal);
+
extern void VG_(sigstartup_actions) ( void );
@@ -1265,4 +1268,5 @@ void VG_(record_fd_open)(Int tid, Int fd
#define MayBlock (1 << 1)
#define PostOnFail (1 << 2)
+#define Done (1 << 3) /* used if a PRE() did the syscall */
// For each generic ("gen") wrapper, we declare the pre-wrapper, the
--- valgrind/coregrind/stage1.c #1.30:1.31
@@ -116,6 +116,6 @@ static void *fix_auxv(void *v_init_esp,
for(; auxv->a_type != AT_NULL; auxv++) {
if (0)
- printf("doing auxv %p %4lld: %lld %p\n",
- auxv, (ULong)auxv->a_type, (ULong)auxv->u.a_val, auxv->u.a_ptr);
+ printf("doing auxv %p %5d: %d %p\n",
+ auxv, auxv->a_type, auxv->u.a_val, auxv->u.a_ptr);
switch(auxv->a_type) {
--- valgrind/coregrind/vg_main.c #1.230:1.231
@@ -859,5 +859,4 @@ static char **fix_environment(char **ori
extern char **environ; /* our environment */
-//#include <error.h>
/* Add a string onto the string table, and return its address */
@@ -1063,7 +1062,4 @@ static Addr setup_client_stack(void* ini
case AT_BASE:
- if (info->interp_base == 0)
- auxv->a_type = AT_IGNORE;
- else
auxv->u.a_val = info->interp_base;
break;
@@ -2320,8 +2316,4 @@ static void build_valgrind_map_callback
UInt prot = 0;
UInt flags = SF_MMAP|SF_NOSYMS;
- Bool is_stack_segment;
-
- is_stack_segment =
- (start == VG_(clstk_base) && (start+size) == VG_(clstk_end));
/* Only record valgrind mappings for now, without loading any
@@ -2507,5 +2499,5 @@ static int prmap(char *start, char *end,
}
-int main(int argc, char **argv)
+int main(int argc, char **argv, char **envp)
{
char **cl_argv;
@@ -2625,5 +2617,5 @@ int main(int argc, char **argv)
// p: load_tool() [for 'preload']
//--------------------------------------------------------------
- env = fix_environment(environ, preload);
+ env = fix_environment(envp, preload);
//--------------------------------------------------------------
--- valgrind/coregrind/vg_procselfmaps.c #1.15:1.16
@@ -239,4 +239,5 @@ void VG_(parse_procselfmaps) (
}
+ if (start < VG_(valgrind_last))
(*record_mapping) ( start, endPlusOne-start,
rr, ww, xx, maj * 256 + min, ino,
--- valgrind/coregrind/vg_messages.c #1.16:1.17
@@ -103,4 +103,5 @@ int VG_(start_msg) ( VgMsgKind kind )
Char ts[32];
Char c;
+ static const Char pfx[] = ">>>>>>>>>>>>>>>>";
vg_n_mbuf = 0;
vg_mbuf[vg_n_mbuf] = 0;
@@ -116,5 +117,6 @@ int VG_(start_msg) ( VgMsgKind kind )
default: c = '?'; break;
}
- return VG_(add_to_msg)( "%c%c%s%d%c%c ",
+ return VG_(add_to_msg)( "%s%c%c%s%d%c%c ",
+ &pfx[sizeof(pfx)-1-RUNNING_ON_VALGRIND],
c,c, ts, VG_(getpid)(), c,c );
}
--- valgrind/coregrind/vg_signals.c #1.106:1.107
@@ -100,4 +100,7 @@ static const Char *signame(Int sigNo);
vki_sigset_t VG_(blocked_mask);
+/* Maximum usable signal. */
+Int VG_(max_signal) = _VKI_NSIG;
+
/* ---------------------------------------------------------------------
HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
@@ -244,17 +247,15 @@ void calculate_SKSS_from_SCSS ( SKSS* ds
break;
- case VKI_SIGVGKILL:
+ default:
+ if (sig == VKI_SIGVGKILL)
skss_handler = sigvgkill_handler;
- break;
-
- case VKI_SIGVGCHLD:
+ else if (sig == VKI_SIGVGCHLD)
skss_handler = sigvgchld_handler;
- break;
-
- default:
+ else {
if (scss_handler == VKI_SIG_IGN)
skss_handler = VKI_SIG_IGN;
else
skss_handler = vg_async_signalhandler;
+ }
break;
}
@@ -320,5 +321,5 @@ static void handle_SCSS_change ( Bool fo
/* Compare the new SKSS entries vs the old ones, and update kernel
where they differ. */
- for (sig = 1; sig <= _VKI_NSIG; sig++) {
+ for (sig = 1; sig <= VG_(max_signal); sig++) {
/* Trying to do anything with SIGKILL is pointless; just ignore
@@ -469,5 +470,5 @@ Int VG_(do_sys_sigaction) ( ThreadId tid
/* Reject out-of-range signal numbers. */
- if (signo < 1 || signo > _VKI_NSIG) goto bad_signo;
+ if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
/* don't let them use our signals */
@@ -686,5 +687,5 @@ void vg_push_signal_frame ( ThreadId tid
Int sigNo = siginfo->si_signo;
- vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
+ vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
vg_assert(VG_(is_valid_tid)(tid));
tst = & VG_(threads)[tid];
@@ -791,5 +792,5 @@ static const Char *signame(Int sigNo)
case VKI_SIGRTMIN ... VKI_SIGRTMAX:
- VG_(sprintf)(buf, "SIGRT%d", sigNo);
+ VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
return buf;
@@ -1495,8 +1496,8 @@ void vg_sync_signalhandler ( Int sigNo,
if (VG_(clo_trace_signals)) {
- VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d",
- sigNo, info->si_code );
+ VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, EIP=%p",
+ sigNo, info->si_code, ARCH_INSTR_PTR(VG_(threads)[tid].arch) );
}
- vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
+ vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
/* Special fault-handling case. We can now get signals which can
@@ -1646,8 +1647,12 @@ static void sigvgkill_handler(int signo,
ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
- //VG_(printf)("sigvgkill for lwp %d tid %d\n", VG_(gettid)(), tid);
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg, "sigvgkill for lwp %d tid %d", VG_(gettid)(), tid);
vg_assert(signo == VKI_SIGVGKILL);
vg_assert(si->si_signo == signo);
+ vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
+
+ VG_(set_running)(tid);
/* Check that the signal comes from within, and ignore it if not. */
@@ -1674,5 +1679,5 @@ void pp_vg_ksigaction ( struct vki_sigac
sa->ksa_handler, (UInt)sa->sa_flags, sa->sa_restorer);
VG_(printf)("vg_ksigaction: { ");
- for (i = 1; i <= _VKI_NSIG; i++)
+ for (i = 1; i <= VG_(max_signal); i++)
if (VG_(sigismember(&(sa->sa_mask),i)))
VG_(printf)("%d ", i);
@@ -1701,5 +1706,5 @@ void VG_(poll_signals)(ThreadId tid)
if (VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d\n", si.si_signo, tid);
+ VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d", si.si_signo, tid);
VG_(deliver_signal)(tid, &si);
}
@@ -1735,5 +1739,28 @@ void VG_(sigstartup_actions) ( void )
/* Get the old host action */
ret = VG_(sigaction)(i, NULL, &sa);
+
+ if (ret != 0)
+ break;
+
+ /* Try setting it back to see if this signal is really
+ available */
+ if (i >= VKI_SIGRTMIN) {
+ struct vki_sigaction tsa;
+
+ tsa.ksa_handler = (void *)vg_sync_signalhandler;
+ tsa.sa_flags = VKI_SA_SIGINFO;
+ VG_(sigfillset)(&tsa.sa_mask);
+
+ /* try setting it to some arbitrary handler */
+ if (VG_(sigaction)(i, &tsa, NULL) != 0) {
+ /* failed - not really usable */
+ break;
+ }
+
+ ret = VG_(sigaction)(i, &sa, NULL);
vg_assert(ret == 0);
+ }
+
+ VG_(max_signal) = i;
if (VG_(clo_trace_signals))
@@ -1747,4 +1774,7 @@ void VG_(sigstartup_actions) ( void )
}
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg, "Max kernel-supported signal is %d", VG_(max_signal));
+
/* Our private internal signals are treated as ignored */
vg_scss.scss_per_sig[VKI_SIGVGCHLD].scss_handler = VKI_SIG_IGN;
--- valgrind/coregrind/vg_symtab2.c #1.96:1.97
@@ -493,9 +493,10 @@ void canonicaliseSymtab ( SegInfo* si )
VG_INTERCEPT_PREFIX_LEN) == 0) {
int len = VG_(strlen)(si->symtab[i].name);
- char *buf = VG_(malloc)(len), *colon;
+ char *buf = VG_(arena_malloc)(VG_AR_SYMTAB, len), *colon;
intercept_demangle(si->symtab[i].name, buf, len);
colon = buf + VG_(strlen)(buf) - 1;
while(*colon != ':') colon--;
VG_(strncpy_safely)(si->symtab[i].name, colon+1, len);
+ VG_(arena_free)(VG_AR_SYMTAB, buf);
}
}
@@ -2384,5 +2385,14 @@ static Bool resolve_redir(CodeRedirect *
}
+ {
+ CodeRedirect *r = VG_(SkipList_Find)(&sk_resolved_redir, &redir->from_addr);
+
+ if (r == NULL || r->from_addr != redir->from_addr)
VG_(SkipList_Insert)(&sk_resolved_redir, redir);
+ else if (verbose_redir)
+ VG_(message)(Vg_DebugMsg, " redir %s:%s:%p->%s:%s:%p duplicated\n",
+ redir->from_lib, redir->from_sym, redir->from_addr,
+ redir->to_lib, redir->to_sym, redir->to_addr);
+ }
}
--- valgrind/coregrind/vg_transtab.c #1.36:1.37
@@ -31,4 +31,5 @@
#include "core.h"
+#include "memcheck/memcheck.h"
/* #define DEBUG_TRANSTAB */
@@ -361,4 +362,5 @@ void discard_oldest_sector ( void )
s, vg_tc_used[s]);
+ VALGRIND_DISCARD_TRANSLATIONS(vg_tc[s], vg_tc_used[s]);
for(i = 0; i < VG_TC_N_SECTORS; i++) {
if (i != s && vg_tc[i] != NULL)
@@ -401,8 +402,8 @@ Int maybe_commission_sector ( void )
for (s = 0; s < VG_TC_N_SECTORS; s++) {
if (vg_tc[s] == NULL) {
-#if 1
+ if (1)
vg_tc[s] = VG_(get_memory_from_mmap)
( vg_tc_sector_szB, "trans-cache(sector)" );
-#else
+ else {
// Alternative: put translations in an mmap'd file. The main
// reason is to help OProfile -- OProfile can assign time spent in
@@ -421,5 +422,7 @@ Int maybe_commission_sector ( void )
vg_tc[s] = VG_(mmap)(0, PGROUNDUP(vg_tc_sector_szB), VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, VKI_MAP_SHARED, 0, fd, 0);
VG_(close)(fd);
-#endif
+ }
+
+ VALGRIND_MAKE_WRITABLE(vg_tc[s], vg_tc_sector_szB);
vg_tc_used[s] = 0;
VG_(sprintf)(msg, "after allocation of sector %d (size %d)",
--- valgrind/coregrind/vg_scheduler.c #1.204:1.205
@@ -447,4 +447,6 @@ void VG_(vg_yield)(void)
VG_(nanosleep)(&ts);
VG_(set_running)(tid);
+
+ VG_(poll_signals)(tid); /* something might have happened */
}
@@ -659,4 +661,8 @@ static void handle_syscall(ThreadId tid)
SCHEDSETJMP(tid, sigcode, VG_(client_syscall)(tid));
+ if (!VG_(is_running_thread)(tid))
+ VG_(printf)("tid %d not running; running_tid=%d, tid %d status %d\n",
+ tid, running_tid, tid, tst->status);
+
vg_assert(VG_(is_running_thread)(tid));
@@ -970,5 +976,5 @@ void do_client_request ( ThreadId tid )
case VG_USERREQ__RUNNING_ON_VALGRIND:
- SET_CLREQ_RETVAL(tid, 1);
+ SET_CLREQ_RETVAL(tid, RUNNING_ON_VALGRIND+1);
break;
@@ -1112,5 +1118,5 @@ void do_client_request ( ThreadId tid )
static Bool whined = False;
- if (!whined) {
+ if (!whined && VG_(clo_verbosity) > 2) {
// Allow for requests in core, but defined by tools, which
// have 0 and 0 in their two high bytes.
--- valgrind/include/x86-linux/vki_arch.h #1.9:1.10
@@ -136,8 +136,7 @@ typedef struct {
/* Use high signals because native pthreads wants to use low */
-#define VKI_SIGVGKILL (VKI_SIGRTMAX-0) // [[internal: kill]]
-#define VKI_SIGVGCHLD (VKI_SIGRTMAX-1) // [[internal: thread death]]
-#define VKI_SIGVGRTUSERMAX (VKI_SIGRTMAX-2) // [[internal: last
- // user-usable RT signal]]
+#define VKI_SIGVGKILL (VG_(max_signal)-0) // [[internal: kill]]
+#define VKI_SIGVGCHLD (VG_(max_signal)-1) // [[internal: thread death]]
+#define VKI_SIGVGRTUSERMAX (VG_(max_signal)-2) // [[internal: last user-usable RT signal]]
#define VKI_SA_NOCLDSTOP 0x00000001u
@@ -270,4 +269,5 @@ struct vki_sigcontext {
#define VKI_O_RDONLY 00
#define VKI_O_WRONLY 01
+#define VKI_O_RDWR 02
#define VKI_O_CREAT 0100 /* not fcntl */
#define VKI_O_EXCL 0200 /* not fcntl */
--- valgrind/coregrind/linux/core_os.c #1.1:1.2
@@ -30,4 +30,14 @@ void VGA_(thread_wrapper)(ThreadId tid)
tid, &tid);
+ if (tid == 1) {
+ /* Thread 1 has its stack on the main process stack, and so
+ is expandable. Do this so that backtraces are printed
+ properly.
+ XXX Perhaps it should have a private stack too?
+ */
+ tst->os_state.stack = (UInt *)VG_(valgrind_last) - VG_STACK_SIZE_W;
+ tst->os_state.stacksize = VG_STACK_SIZE_W;
+ }
+
tst->os_state.lwpid = VG_(gettid)();
tst->os_state.threadgroup = VG_(getpid)();
@@ -112,4 +122,5 @@ void VGA_(reap_threads)(ThreadId self)
vg_assert(si.si_signo == VKI_SIGVGCHLD);
}
+ vg_assert(VG_(count_living_threads)() == 1);
}
@@ -123,5 +134,6 @@ void VGA_(intercept_libc_freeres_wrapper
}
-/* Clean up the client by calling __libc_freeres() (if requested) */
+/* Final clean-up before terminating the process.
+ Clean up the client by calling __libc_freeres() (if requested) */
void VGA_(final_tidyup)(ThreadId tid)
{
|