You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
1
(22) |
2
(19) |
3
(8) |
4
(34) |
5
(14) |
6
(14) |
|
7
(12) |
8
(15) |
9
(15) |
10
(10) |
11
(10) |
12
(28) |
13
(11) |
|
14
(22) |
15
(29) |
16
(20) |
17
(15) |
18
(39) |
19
(11) |
20
(12) |
|
21
(8) |
22
(9) |
23
(8) |
24
(10) |
25
(9) |
26
(7) |
27
(7) |
|
28
(6) |
29
(6) |
30
(11) |
|
|
|
|
|
From: Tom H. <th...@cy...> - 2004-11-08 23:47:28
|
In message <Pin...@he...>
Nicholas Nethercote <nj...@ca...> wrote:
> But the __NR_foo name means different things on different architectures.
>
> Take __NR_lchown as an example. On x86, when you call
> syscall(__NR_lchown, ...), it ends up calling sys_lchown16() in the
> kernel. On x86-64, it instead ends up calling sys_lchown() in the kernel.
> There are lots of examples like this.
>
> The syscall wrappers (the PRE() and POST()) functions should be matched
> with the correct sys_foo()/old_foo() functions. We don't know just by
> looking at the __NR_foo constant which sys_foo() function will be called,
> so we need to specify the __NR_foo-->sys_foo() mapping ourselves.
Ah right. I didn't realise that there were differences like that
between platforms. I understand the logic now.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 19:30:15
|
CVS commit by nethercote:
Improved memcheck/tests/scalar so that it shows an example whereby the syscall
number itself is undefined.
M +2 -0 .cvsignore 1.23
M +7 -3 scalar.c 1.2
M +9 -4 scalar.stderr.exp 1.2
M +1 -1 scalar.supp 1.2
M +7 -2 scalar_supp.stderr.exp 1.2
--- valgrind/memcheck/tests/.cvsignore #1.22:1.23
@@ -49,6 +49,8 @@
realloc2
realloc3
+scalar
sigaltstack
signal2
+str_tester
supp1
supp2
--- valgrind/memcheck/tests/scalar.c #1.1:1.2
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <unistd.h>
+#include <sys/syscall.h>
int main(void)
@@ -10,7 +11,10 @@ int main(void)
char** pc = malloc(sizeof(char*));
- // Four errors: each of the scalar args are undefined, plus the 2nd arg
- // points to unaddressable memory.
- write(pi[0], pc[0], pi[0]+1);
+ // Five errors:
+ // - the syscall number itself is undefined (but we know it's
+ // 0 + __NR_write :)
+ // - each of the scalar args are undefined
+ // - the 2nd arg points to unaddressable memory.
+ syscall(pi[0]+__NR_write, pi[0], pc[0], pi[0]+1);
return 0;
--- valgrind/memcheck/tests/scalar.stderr.exp #1.1:1.2
@@ -1,19 +1,24 @@
+Syscall param (syscallno) contains uninitialised byte(s)
+ at 0x........: syscall (in /...libc...)
+ by 0x........: __libc_start_main (...libc...)
+ by 0x........: ...
+
Syscall param write(fd) contains uninitialised byte(s)
- at 0x........: write (in /...libc...)
+ at 0x........: syscall (in /...libc...)
by 0x........: __libc_start_main (...libc...)
by 0x........: ...
Syscall param write(buf) contains uninitialised byte(s)
- at 0x........: write (in /...libc...)
+ at 0x........: syscall (in /...libc...)
by 0x........: __libc_start_main (...libc...)
by 0x........: ...
Syscall param write(count) contains uninitialised byte(s)
- at 0x........: write (in /...libc...)
+ at 0x........: syscall (in /...libc...)
by 0x........: __libc_start_main (...libc...)
by 0x........: ...
Syscall param write(buf) points to unaddressable byte(s)
- at 0x........: write (in /...libc...)
+ at 0x........: syscall (in /...libc...)
by 0x........: __libc_start_main (...libc...)
by 0x........: ...
--- valgrind/memcheck/tests/scalar.supp #1.1:1.2
@@ -4,5 +4,5 @@
Memcheck:Param
write(buf)
- fun:__write_nocancel
+ fun:syscall
fun:__libc_start_main
}
--- valgrind/memcheck/tests/scalar_supp.stderr.exp #1.1:1.2
@@ -1,9 +1,14 @@
+Syscall param (syscallno) contains uninitialised byte(s)
+ at 0x........: syscall (in /...libc...)
+ by 0x........: __libc_start_main (...libc...)
+ by 0x........: ...
+
Syscall param write(fd) contains uninitialised byte(s)
- at 0x........: write (in /...libc...)
+ at 0x........: syscall (in /...libc...)
by 0x........: __libc_start_main (...libc...)
by 0x........: ...
Syscall param write(count) contains uninitialised byte(s)
- at 0x........: write (in /...libc...)
+ at 0x........: syscall (in /...libc...)
by 0x........: __libc_start_main (...libc...)
by 0x........: ...
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 19:25:02
|
CVS commit by nethercote:
Improved Memcheck's error checking messages in two significant ways:
- All memory-related errors are now clear whether they are caused by
unaddressable or uninitialised memory. (Previously, writes were
clearly addressability errors, but reads could be either.) Mostly
done by replacing the 'isWrite' field in MAC_Error with 'isUnaddr'.
Also, mc_check_readable() now indicates not just if an error occurred,
but what kind of error (ie. addressability or definedness).
- Put machinery into place in the core to inform tools when registers
are being read by the core -- ie. a 'pre_reg_read' event. Most
notably, this facilitates syscall scalar arg definedness checking for
Memcheck. Currently this is only working for read(), write(), exit()
and exit_group(), but it will be extended as the syscalls are
overhauled as part of the arch-abstraction work.
A consequence of this is that the ParamErr messages have changed. This:
Syscall param write(buf) contains uninitialised byte(s)
now means that the pointer 'buf' is partially undefined. If the memory
pointed to by 'buf' is partially undefined or unaddressable, it says one of:
Syscall param write(buf) points to uninitialised byte(s)
Syscall param write(buf) points to unaddressable byte(s)
The docs have been updated accordingly.
I also added a couple of regression tests.
These two change sare notable for being the first improvements to
Memcheck's checking/errors in a long time.
I also folded mc_clientreqs.c into mc_main.c, which saves exporting a
whole bunch of things that are not used anywhere else.
A memcheck/tests/scalar.c 1.1 [no copyright]
A memcheck/tests/scalar.stderr.exp 1.1
A memcheck/tests/scalar.supp 1.1
A memcheck/tests/scalar.vgtest 1.1
A memcheck/tests/scalar_supp.stderr.exp 1.1
A memcheck/tests/scalar_supp.vgtest 1.1
M +5 -4 addrcheck/ac_main.c 1.70
M +2 -0 coregrind/toolfuncs.def 1.9
M +14 -1 coregrind/vg_scheduler.c 1.198
M +27 -5 coregrind/vg_syscalls.c 1.168
M +5 -0 coregrind/x86-linux/core_platform.h 1.11
M +0 -1 memcheck/Makefile.am 1.54
M +15 -11 memcheck/mac_needs.c 1.33
M +10 -9 memcheck/mac_shared.h 1.28
M +28 -35 memcheck/mc_errcontext.c 1.23
M +3 -27 memcheck/mc_include.h 1.23
M +345 -51 memcheck/mc_main.c 1.55
M +34 -25 memcheck/docs/mc_main.html 1.13
M +4 -1 memcheck/tests/Makefile.am 1.55
M +2 -2 memcheck/tests/badpoll.stderr.exp 1.2
M +2 -2 memcheck/tests/buflen_check.stderr.exp 1.10
M +3 -3 memcheck/tests/execve.stderr.exp 1.3
M +1 -1 memcheck/tests/execve2.stderr.exp 1.2
M +1 -1 memcheck/tests/fwrite.stderr.exp 1.10
M +4 -1 memcheck/tests/weirdioctl.c 1.3
M +1 -1 memcheck/tests/weirdioctl.stderr.exp 1.9
M +37 -37 memcheck/tests/weirdioctl.stdout.exp 1.4
M +2 -2 memcheck/tests/weirdioctl.vgtest 1.4
M +3 -3 memcheck/tests/writev.stderr.exp 1.8
M +3 -3 memcheck/tests/writev.stderr.exp2 1.4
R memcheck/mc_clientreqs.c 1.24
--- valgrind/addrcheck/ac_main.c #1.69:1.70
@@ -546,5 +546,6 @@ void ac_check_is_accessible ( CorePart p
switch (part) {
case Vg_CoreSysCall:
- MAC_(record_param_error) ( tid, bad_addr, isWrite, s );
+ MAC_(record_param_error) ( tid, bad_addr, /*isReg*/False,
+ /*isUnaddr*/True, s );
break;
@@ -553,5 +554,5 @@ void ac_check_is_accessible ( CorePart p
/* fall through */
case Vg_CorePThread:
- MAC_(record_core_mem_error)( tid, isWrite, s );
+ MAC_(record_core_mem_error)( tid, /*isUnaddr*/True, s );
break;
@@ -591,5 +592,4 @@ void ac_check_is_readable_asciiz ( CoreP
Bool ok = True;
Addr bad_addr;
- /* VG_(message)(Vg_DebugMsg,"check is readable asciiz: 0x%x",str); */
VGP_PUSHCC(VgpCheckMem);
@@ -598,5 +598,6 @@ void ac_check_is_readable_asciiz ( CoreP
ok = ac_check_readable_asciiz ( (Addr)str, &bad_addr );
if (!ok) {
- MAC_(record_param_error) ( tid, bad_addr, /*is_writable =*/False, s );
+ MAC_(record_param_error) ( tid, bad_addr, /*IsReg*/False,
+ /*IsUnaddr*/True, s );
}
--- valgrind/coregrind/toolfuncs.def #1.8:1.9
@@ -231,4 +231,6 @@
## changed register.
+void, pre_reg_read, CorePart part, ThreadId tid, Char* s, UInt reg, SizeT size
+
## Use VG_(set_shadow_archreg)() to set the eight general purpose regs,
## and use VG_(set_shadow_eflags)() to set eflags.
--- valgrind/coregrind/vg_scheduler.c #1.197:1.198
@@ -965,7 +965,20 @@ VgSchedReturnCode do_scheduler ( Int* ex
) {
- /* If __NR_exit, remember the supplied argument. */
+ /* Remember the supplied argument. */
*exitcode = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
+ // Inform tool about regs read by syscall
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, "(syscallno)",
+ R_SYSCALL_NUM, sizeof(UWord) );
+
+ if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit)
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid,
+ "exit(error_code)", R_SYSCALL_ARG1, sizeof(int) );
+
+ if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group)
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid,
+ "exit_group(error_code)", R_SYSCALL_ARG1,
+ sizeof(int) );
+
/* Only run __libc_freeres if the tool says it's ok and
it hasn't been overridden with --run-libc-freeres=no
--- valgrind/coregrind/vg_syscalls.c #1.167:1.168
@@ -43,5 +43,21 @@
*/
-#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) /*nothing, so far*/
+#define X(syscallname, argname) syscallname"("#argname")"
+
+#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
+ do { \
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, "(syscallno)", R_SYSCALL_NUM, sizeof(t1)); \
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, X(s,a1), R_SYSCALL_ARG1, sizeof(t1)); \
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, X(s,a2), R_SYSCALL_ARG2, sizeof(t2)); \
+ VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, X(s,a3), R_SYSCALL_ARG3, sizeof(t3)); \
+ } while (0);
+
+#if 0
+ do { \
+ if (VG_(defined_)()) { \
+ SK_(pre_reg_read)(args); \
+ } \
+ } while(0)
+#endif
#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
@@ -1003,4 +1019,10 @@ static Bool fd_allowed(Int fd, const Cha
__NR_foo constants and their relationship to the sys_foo() functions.
+ Note that for the PRE_REG_READ tests, we pass a somewhat generic name
+ for the syscall (eg. "write")... this should be good enough for the
+ average user to understand what is happening, without confusing them
+ with names like "sys_write". However, for the --trace-syscalls=yes
+ output, we use the sys_foo() name to avoid ambiguity.
+
XXX: some of these are arch-specific, and should be factored out.
*/
@@ -4098,6 +4120,6 @@ POST(open)
PRE(sys_read)
{
- PRINT("read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
- PRE_REG_READ3(ssize_t, sys_read,
+ PRINT("sys_read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
+ PRE_REG_READ3(ssize_t, "read",
unsigned int, fd, char __user *, buf, size_t, count);
@@ -4115,6 +4137,6 @@ POST(sys_read)
PRE(sys_write)
{
- PRINT("write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
- PRE_REG_READ3(ssize_t, sys_write,
+ PRINT("sys_write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
+ PRE_REG_READ3(ssize_t, "write",
unsigned int, fd, const char __user *, buf, size_t, count);
if (!fd_allowed(arg1, "write", tid, False))
--- valgrind/coregrind/x86-linux/core_platform.h #1.10:1.11
@@ -55,4 +55,9 @@
#define R_SYSCALL_NUM R_EAX
#define R_SYSCALL_ARG1 R_EBX
+#define R_SYSCALL_ARG2 R_ECX
+#define R_SYSCALL_ARG3 R_EDX
+#define R_SYSCALL_ARG4 R_ESI
+#define R_SYSCALL_ARG5 R_EDI
+#define R_SYSCALL_ARG6 R_EBP
#define R_SYSCALL_RET R_EAX
--- valgrind/memcheck/Makefile.am #1.53:1.54
@@ -19,5 +19,4 @@
mac_needs.c \
mc_main.c \
- mc_clientreqs.c \
mc_errcontext.c \
mc_from_ucode.c \
--- valgrind/memcheck/mac_needs.c #1.32:1.33
@@ -115,5 +115,5 @@ void MAC_(clear_MAC_Error) ( MAC_Error*
err_extra->size = 0;
clear_AddrInfo ( &err_extra->addrinfo );
- err_extra->isWrite = False;
+ err_extra->isUnaddr = True;
}
@@ -149,5 +149,5 @@ Bool SK_(eq_SkinError) ( VgRes res, Erro
case CoreMemErr: {
Char *e1s, *e2s;
- if (e1_extra->isWrite != e2_extra->isWrite) return False;
+ if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
e1s = VG_(get_error_string)(e1);
e2s = VG_(get_error_string)(e2);
@@ -159,5 +159,5 @@ Bool SK_(eq_SkinError) ( VgRes res, Erro
case UserErr:
case ParamErr:
- if (e1_extra->isWrite != e2_extra->isWrite) return False;
+ if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
if (VG_(get_error_kind)(e1) == ParamErr
&& 0 != VG_(strcmp)(VG_(get_error_string)(e1),
@@ -256,4 +256,8 @@ void MAC_(pp_AddrInfo) ( Addr a, AddrInf
break;
}
+ case Register:
+ // print nothing
+ sk_assert(0 == a);
+ break;
default:
VG_(skin_panic)("MAC_(pp_AddrInfo)");
@@ -294,5 +298,5 @@ void MAC_(pp_shared_SkinError) ( Error*
break;
default:
- VG_(skin_panic)("SK_(pp_SkinError)(axskind)");
+ VG_(skin_panic)("SK_(pp_shared_SkinError)(axskind)");
}
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
@@ -446,15 +450,15 @@ void MAC_(record_address_error) ( Thread
/* This is for memory errors in pthread functions, as opposed to pthread API
errors which are found by the core. */
-void MAC_(record_core_mem_error) ( ThreadId tid, Bool isWrite, Char* msg )
+void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
{
MAC_Error err_extra;
MAC_(clear_MAC_Error)( &err_extra );
- err_extra.isWrite = isWrite;
+ err_extra.isUnaddr = isUnaddr;
VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
}
-void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isWrite,
- Char* msg )
+void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
+ Bool isUnaddr, Char* msg )
{
MAC_Error err_extra;
@@ -462,6 +466,6 @@ void MAC_(record_param_error) ( ThreadId
sk_assert(VG_INVALID_THREADID != tid);
MAC_(clear_MAC_Error)( &err_extra );
- err_extra.addrinfo.akind = Undescribed;
- err_extra.isWrite = isWrite;
+ err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
+ err_extra.isUnaddr = isUnaddr;
VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
}
@@ -530,5 +534,5 @@ UInt SK_(update_extra)( Error* err )
case IllegalMempoolErr:
case FreeMismatchErr: {
- MAC_Error* extra = (MAC_Error*)VG_(get_error_extra)(err);
+ MAC_Error* extra = VG_(get_error_extra)(err);
if (extra != NULL && Undescribed == extra->addrinfo.akind) {
describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
--- valgrind/memcheck/mac_shared.h #1.27:1.28
@@ -48,10 +48,11 @@
typedef
enum {
- Undescribed, /* as-yet unclassified */
+ Undescribed, // as-yet unclassified
Stack,
- Unknown, /* classification yielded nothing useful */
+ Unknown, // classification yielded nothing useful
Freed, Mallocd,
- UserG, /* in a user-defined block; Addrcheck & Memcheck only */
- Mempool, /* in a mempool; Addrcheck & Memcheck only */
+ UserG, // in a user-defined block
+ Mempool, // in a mempool
+ Register, // in a register; for Param errors only
}
AddrKind;
@@ -62,5 +63,5 @@ typedef
AddrKind akind; // ALL
SizeT blksize; // Freed, Mallocd
- SSizeT rwoffset; // Freed, Mallocd
+ OffT rwoffset; // Freed, Mallocd
ExeContext* lastchange; // Freed, Mallocd
ThreadId stack_tid; // Stack
@@ -111,5 +112,5 @@ typedef
Int size; // AddrErr, ValueErr
AddrInfo addrinfo; // {Addr,Free,FreeMismatch,Param,User}Err
- Bool isWrite; // ParamErr, UserErr, CoreMemErr
+ Bool isUnaddr; // {CoreMem,Param,User}Err
}
MAC_Error;
@@ -317,8 +318,8 @@ extern void MAC_(mempool_free)(Addr pool
extern void MAC_(record_address_error) ( ThreadId tid, Addr a,
Int size, Bool isWrite );
-extern void MAC_(record_core_mem_error) ( ThreadId tid, Bool isWrite,
+extern void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr,
Char* s );
-extern void MAC_(record_param_error) ( ThreadId tid, Addr a,
- Bool isWriteLack, Char* msg );
+extern void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
+ Bool isUnaddr, Char* msg );
extern void MAC_(record_jump_error) ( ThreadId tid, Addr a );
extern void MAC_(record_free_error) ( ThreadId tid, Addr a );
--- valgrind/memcheck/mc_errcontext.c #1.22:1.23
@@ -41,20 +41,16 @@ void SK_(pp_SkinError) ( Error* err )
switch (VG_(get_error_kind)(err)) {
- case CoreMemErr:
- if (err_extra->isWrite) {
- VG_(message)(Vg_UserMsg,
- "%s contains unaddressable byte(s)", VG_(get_error_string)(err));
- } else {
- VG_(message)(Vg_UserMsg,
- "%s contains uninitialised or unaddressable byte(s)",
- VG_(get_error_string)(err));
- }
+ case CoreMemErr: {
+ Char* s = ( err_extra->isUnaddr ? "unaddressable" : "uninitialised" );
+ VG_(message)(Vg_UserMsg, "%s contains %s byte(s)",
+ VG_(get_error_string)(err), s);
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
break;
+ }
+
case ValueErr:
if (err_extra->size == 0) {
- VG_(message)(
- Vg_UserMsg,
+ VG_(message)(Vg_UserMsg,
"Conditional jump or move depends on uninitialised value(s)");
} else {
@@ -66,32 +62,27 @@ void SK_(pp_SkinError) ( Error* err )
break;
- case ParamErr:
- if (err_extra->isWrite) {
- VG_(message)(Vg_UserMsg,
- "Syscall param %s contains unaddressable byte(s)",
- VG_(get_error_string)(err));
- } else {
- VG_(message)(Vg_UserMsg,
- "Syscall param %s contains uninitialised or "
- "unaddressable byte(s)",
- VG_(get_error_string)(err));
- }
+ case ParamErr: {
+ Bool isReg = ( Register == err_extra->addrinfo.akind );
+ Char* s1 = ( isReg ? "contains" : "points to" );
+ Char* s2 = ( err_extra->isUnaddr ? "unaddressable" : "uninitialised" );
+ if (isReg) sk_assert(!err_extra->isUnaddr);
+
+ VG_(message)(Vg_UserMsg, "Syscall param %s %s %s byte(s)",
+ VG_(get_error_string)(err), s1, s2);
+
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
break;
+ }
+ case UserErr: {
+ Char* s = ( err_extra->isUnaddr ? "Unaddressable" : "Uninitialised" );
- case UserErr:
- if (err_extra->isWrite) {
VG_(message)(Vg_UserMsg,
- "Unaddressable byte(s) found during client check request");
- } else {
- VG_(message)(Vg_UserMsg,
- "Uninitialised or "
- "unaddressable byte(s) found during client check request");
- }
+ "%s byte(s) found during client check request", s);
+
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
break;
-
+ }
default:
MAC_(pp_shared_SkinError)(err);
@@ -113,4 +104,5 @@ void MC_(record_value_error) ( ThreadId
MAC_(clear_MAC_Error)( &err_extra );
err_extra.size = size;
+ err_extra.isUnaddr = False;
VG_(maybe_record_error)( tid, ValueErr, /*addr*/0, /*s*/NULL, &err_extra );
}
@@ -118,5 +110,6 @@ void MC_(record_value_error) ( ThreadId
/* This called from non-generated code */
-void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isWrite )
+void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isWrite,
+ Bool isUnaddr )
{
MAC_Error err_extra;
@@ -125,5 +118,5 @@ void MC_(record_user_error) ( ThreadId t
MAC_(clear_MAC_Error)( &err_extra );
err_extra.addrinfo.akind = Undescribed;
- err_extra.isWrite = isWrite;
+ err_extra.isUnaddr = isUnaddr;
VG_(maybe_record_error)( tid, UserErr, a, /*s*/NULL, &err_extra );
}
--- valgrind/memcheck/mc_include.h #1.22:1.23
@@ -133,31 +132,8 @@ extern REGPARM(2) void MC_(fpu_write_che
extern REGPARM(2) void MC_(fpu_read_check) ( Addr addr, SizeT size );
-
-/* For client requests */
-extern void MC_(make_noaccess) ( Addr a, SizeT len );
-extern void MC_(make_readable) ( Addr a, SizeT len );
-extern void MC_(make_writable) ( Addr a, SizeT len );
-
-extern Bool MC_(check_writable) ( Addr a, SizeT len, Addr* bad_addr );
-extern Bool MC_(check_readable) ( Addr a, SizeT len, Addr* bad_addr );
-
-extern void MC_(detect_memory_leaks) ( void );
-
-extern Int MC_(get_or_set_vbits_for_client) (
- ThreadId tid,
- Addr dataV,
- Addr vbitsV,
- SizeT size,
- Bool setting /* True <=> set vbits, False <=> get vbits */
- );
-
-/* Functions defined in mc_clientreqs.c */
-extern Bool MC_(client_perm_maybe_describe)( Addr a, AddrInfo* ai );
-extern void MC_(show_client_block_stats) ( void );
-
-
/* Functions defined in mc_errcontext.c */
extern void MC_(record_value_error) ( ThreadId tid, Int size );
-extern void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isWrite );
+extern void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isWrite,
+ Bool isUnaddr );
@@ -165,5 +141,5 @@ extern void MC_(record_user_error) ( T
/*--------------------------------------------------------------------*/
-/*--- end mc_include.h ---*/
+/*--- end ---*/
/*--------------------------------------------------------------------*/
--- valgrind/memcheck/mc_main.c #1.54:1.55
@@ -390,22 +390,22 @@ static void set_address_range_perms ( Ad
/* Set permissions for address ranges ... */
-void MC_(make_noaccess) ( Addr a, SizeT len )
+static void mc_make_noaccess ( Addr a, SizeT len )
{
PROF_EVENT(35);
- DEBUG("MC_(make_noaccess)(%p, %llu)\n", a, (ULong)len);
+ DEBUG("mc_make_noaccess(%p, %llu)\n", a, (ULong)len);
set_address_range_perms ( a, len, VGM_BIT_INVALID, VGM_BIT_INVALID );
}
-void MC_(make_writable) ( Addr a, SizeT len )
+static void mc_make_writable ( Addr a, SizeT len )
{
PROF_EVENT(36);
- DEBUG("MC_(make_writable)(%p, %llu)\n", a, (ULong)len);
+ DEBUG("mc_make_writable(%p, %llu)\n", a, (ULong)len);
set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_INVALID );
}
-void MC_(make_readable) ( Addr a, SizeT len )
+static void mc_make_readable ( Addr a, SizeT len )
{
PROF_EVENT(37);
- DEBUG("MC_(make_readable)(%p, %llu)\n", a, (ULong)len);
+ DEBUG("mc_make_readable(%p, %llu)\n", a, (ULong)len);
set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_VALID );
}
@@ -487,6 +487,6 @@ ESP_UPDATE_HANDLERS ( make_aligned_word_
make_aligned_doubleword_writable,
make_aligned_doubleword_noaccess,
- MC_(make_writable),
- MC_(make_noaccess)
+ mc_make_writable,
+ mc_make_noaccess
);
@@ -508,4 +508,7 @@ static void mc_copy_address_range_state
}
+/*------------------------------------------------------------*/
+/*--- Checking memory ---*/
+/*------------------------------------------------------------*/
/* Check permissions for address range. If inadequate permissions
@@ -517,5 +520,5 @@ static void mc_copy_address_range_state
indicate the lowest failing address. Functions below are
similar. */
-Bool MC_(check_noaccess) ( Addr a, SizeT len, Addr* bad_addr )
+static Bool mc_check_noaccess ( Addr a, SizeT len, Addr* bad_addr )
{
SizeT i;
@@ -534,5 +537,5 @@ Bool MC_(check_noaccess) ( Addr a, SizeT
}
-Bool MC_(check_writable) ( Addr a, SizeT len, Addr* bad_addr )
+static Bool mc_check_writable ( Addr a, SizeT len, Addr* bad_addr )
{
SizeT i;
@@ -551,5 +554,9 @@ Bool MC_(check_writable) ( Addr a, SizeT
}
-Bool MC_(check_readable) ( Addr a, SizeT len, Addr* bad_addr )
+typedef enum {
+ MC_Ok = 5, MC_AddrErr = 6, MC_ValueErr = 7
+} MC_ReadResult;
+
+static MC_ReadResult mc_check_readable ( Addr a, SizeT len, Addr* bad_addr )
{
SizeT i;
@@ -558,16 +565,22 @@ Bool MC_(check_readable) ( Addr a, SizeT
PROF_EVENT(44);
- DEBUG("MC_(check_readable)\n");
+ DEBUG("mc_check_readable\n");
for (i = 0; i < len; i++) {
abit = get_abit(a);
vbyte = get_vbyte(a);
PROF_EVENT(45);
- if (abit != VGM_BIT_VALID || vbyte != VGM_BYTE_VALID) {
+ // Report addressability errors in preference to definedness errors
+ // by checking the A bits first.
+ if (abit != VGM_BIT_VALID) {
if (bad_addr != NULL) *bad_addr = a;
- return False;
+ return MC_AddrErr;
+ }
+ if (vbyte != VGM_BYTE_VALID) {
+ if (bad_addr != NULL) *bad_addr = a;
+ return MC_ValueErr;
}
a++;
}
- return True;
+ return MC_Ok;
}
@@ -587,10 +600,15 @@ static Bool mc_check_readable_asciiz ( A
abit = get_abit(a);
vbyte = get_vbyte(a);
- if (abit != VGM_BIT_VALID || vbyte != VGM_BYTE_VALID) {
+ // As in mc_check_readable(), check A bits first
+ if (abit != VGM_BIT_VALID) {
if (bad_addr != NULL) *bad_addr = a;
- return False;
+ return MC_AddrErr;
+ }
+ if (vbyte != VGM_BYTE_VALID) {
+ if (bad_addr != NULL) *bad_addr = a;
+ return MC_ValueErr;
}
/* Ok, a is safe to read. */
- if (* ((UChar*)a) == 0) return True;
+ if (* ((UChar*)a) == 0) return MC_Ok;
a++;
}
@@ -613,14 +631,15 @@ void mc_check_is_writable ( CorePart par
/* VG_(message)(Vg_DebugMsg,"check is writable: %x .. %x",
base,base+size-1); */
- ok = MC_(check_writable) ( base, size, &bad_addr );
+ ok = mc_check_writable ( base, size, &bad_addr );
if (!ok) {
switch (part) {
case Vg_CoreSysCall:
- MAC_(record_param_error) ( tid, bad_addr, /*isWrite =*/True, s );
+ MAC_(record_param_error) ( tid, bad_addr, /*isReg*/False,
+ /*isUnaddr*/True, s );
break;
case Vg_CorePThread:
case Vg_CoreSignal:
- MAC_(record_core_mem_error)( tid, /*isWrite=*/True, s );
+ MAC_(record_core_mem_error)( tid, /*isUnaddr*/True, s );
break;
@@ -637,6 +656,6 @@ void mc_check_is_readable ( CorePart par
Addr base, SizeT size )
{
- Bool ok;
Addr bad_addr;
+ MC_ReadResult res;
VGP_PUSHCC(VgpCheckMem);
@@ -644,13 +663,16 @@ void mc_check_is_readable ( CorePart par
/* VG_(message)(Vg_DebugMsg,"check is readable: %x .. %x",
base,base+size-1); */
- ok = MC_(check_readable) ( base, size, &bad_addr );
- if (!ok) {
+ res = mc_check_readable ( base, size, &bad_addr );
+ if (MC_Ok != res) {
+ Bool isUnaddr = ( MC_AddrErr == res ? True : False );
+
switch (part) {
case Vg_CoreSysCall:
- MAC_(record_param_error) ( tid, bad_addr, /*isWrite =*/False, s );
+ MAC_(record_param_error) ( tid, bad_addr, /*isReg*/False,
+ isUnaddr, s );
break;
case Vg_CorePThread:
- MAC_(record_core_mem_error)( tid, /*isWrite=*/False, s );
+ MAC_(record_core_mem_error)( tid, isUnaddr, s );
break;
@@ -672,5 +694,5 @@ void mc_check_is_readable_asciiz ( CoreP
Char* s, Addr str )
{
- Bool ok = True;
+ MC_ReadResult res;
Addr bad_addr;
/* VG_(message)(Vg_DebugMsg,"check is readable asciiz: 0x%x",str); */
@@ -679,7 +701,8 @@ void mc_check_is_readable_asciiz ( CoreP
sk_assert(part == Vg_CoreSysCall);
- ok = mc_check_readable_asciiz ( (Addr)str, &bad_addr );
- if (!ok) {
- MAC_(record_param_error) ( tid, bad_addr, /*is_writable =*/False, s );
+ res = mc_check_readable_asciiz ( (Addr)str, &bad_addr );
+ if (MC_Ok != res) {
+ Bool isUnaddr = ( MC_AddrErr == res ? True : False );
+ MAC_(record_param_error) ( tid, bad_addr, /*isReg*/False, isUnaddr, s );
}
@@ -694,5 +717,5 @@ void mc_new_mem_startup( Addr a, SizeT l
DEBUG("mc_new_mem_startup(%p, %llu, rr=%u, ww=%u, xx=%u)\n",
a,(ULong)len,rr,ww,xx);
- MC_(make_readable)(a, len);
+ mc_make_readable(a, len);
}
@@ -701,7 +724,7 @@ void mc_new_mem_heap ( Addr a, SizeT len
{
if (is_inited) {
- MC_(make_readable)(a, len);
+ mc_make_readable(a, len);
} else {
- MC_(make_writable)(a, len);
+ mc_make_writable(a, len);
}
}
@@ -712,7 +735,7 @@ void mc_set_perms (Addr a, SizeT len, Bo
DEBUG("mc_set_perms(%p, %llu, rr=%u ww=%u, xx=%u)\n",
a, (ULong)len, rr, ww, xx);
- if (rr) MC_(make_readable)(a, len);
- else if (ww) MC_(make_writable)(a, len);
- else MC_(make_noaccess)(a, len);
+ if (rr) mc_make_readable(a, len);
+ else if (ww) mc_make_writable(a, len);
+ else mc_make_noaccess(a, len);
}
@@ -740,4 +763,22 @@ static void mc_post_reg_write_clientcall
}
+static void mc_pre_reg_read(CorePart part, ThreadId tid, Char* s, UInt reg,
+ SizeT size)
+{
+ UWord mask;
+
+ // XXX: the only one at the moment
+ sk_assert(Vg_CoreSysCall == part);
+
+ switch (size) {
+ case 4: mask = 0xffffffff; break;
+ case 2: mask = 0xffff; break;
+ case 1: mask = 0xff; break;
+ default: VG_(skin_panic)("Unhandled size in mc_pre_reg_read");
+ }
+
+ if (VGM_WORD_VALID != (mask & VG_(get_thread_shadow_archreg)( tid, reg )) )
+ MAC_(record_param_error) ( tid, 0, /*isReg*/True, /*isUnaddr*/False, s );
+}
/*------------------------------------------------------------*/
@@ -1349,5 +1390,5 @@ void mc_fpu_write_check_SLOWLY ( Addr ad
/* Copy Vbits for src into vbits. Returns: 1 == OK, 2 == alignment
error, 3 == addressing error. */
-Int MC_(get_or_set_vbits_for_client) (
+static Int mc_get_or_set_vbits_for_client (
ThreadId tid,
Addr dataV,
@@ -1458,5 +1499,5 @@ Bool mc_is_valid_address ( Addr a )
run the generic leak detector with suitable parameters for this
tool. */
-void MC_(detect_memory_leaks) ( void )
+static void mc_detect_memory_leaks ( void )
{
MAC_(do_detect_memory_leaks) ( mc_is_valid_64k_chunk, mc_is_valid_address );
@@ -1623,4 +1664,255 @@ void SK_(print_debug_usage)(void)
}
+/*------------------------------------------------------------*/
+/*--- Client requests ---*/
+/*------------------------------------------------------------*/
+
+/* Client block management:
+
+ This is managed as an expanding array of client block descriptors.
+ Indices of live descriptors are issued to the client, so it can ask
+ to free them later. Therefore we cannot slide live entries down
+ over dead ones. Instead we must use free/inuse flags and scan for
+ an empty slot at allocation time. This in turn means allocation is
+ relatively expensive, so we hope this does not happen too often.
+*/
+
+typedef
+ enum { CG_NotInUse, CG_NoAccess, CG_Writable, CG_Readable }
+ CGenBlockKind;
+
+typedef
+ struct {
+ Addr start;
+ SizeT size;
+ ExeContext* where;
+ CGenBlockKind kind;
+ }
+ CGenBlock;
+
+/* This subsystem is self-initialising. */
+static UInt vg_cgb_size = 0;
+static UInt vg_cgb_used = 0;
+static CGenBlock* vg_cgbs = NULL;
+
+/* Stats for this subsystem. */
+static UInt vg_cgb_used_MAX = 0; /* Max in use. */
+static UInt vg_cgb_allocs = 0; /* Number of allocs. */
+static UInt vg_cgb_discards = 0; /* Number of discards. */
+static UInt vg_cgb_search = 0; /* Number of searches. */
+
+
+static
+Int vg_alloc_client_block ( void )
+{
+ UInt i, sz_new;
+ CGenBlock* cgbs_new;
+
+ vg_cgb_allocs++;
+
+ for (i = 0; i < vg_cgb_used; i++) {
+ vg_cgb_search++;
+ if (vg_cgbs[i].kind == CG_NotInUse)
+ return i;
+ }
+
+ /* Not found. Try to allocate one at the end. */
+ if (vg_cgb_used < vg_cgb_size) {
+ vg_cgb_used++;
+ return vg_cgb_used-1;
+ }
+
+ /* Ok, we have to allocate a new one. */
+ sk_assert(vg_cgb_used == vg_cgb_size);
+ sz_new = (vg_cgbs == NULL) ? 10 : (2 * vg_cgb_size);
+
+ cgbs_new = VG_(malloc)( sz_new * sizeof(CGenBlock) );
+ for (i = 0; i < vg_cgb_used; i++)
+ cgbs_new[i] = vg_cgbs[i];
+
+ if (vg_cgbs != NULL)
+ VG_(free)( vg_cgbs );
+ vg_cgbs = cgbs_new;
+
+ vg_cgb_size = sz_new;
+ vg_cgb_used++;
+ if (vg_cgb_used > vg_cgb_used_MAX)
+ vg_cgb_used_MAX = vg_cgb_used;
+ return vg_cgb_used-1;
+}
+
+
+static void show_client_block_stats ( void )
+{
+ VG_(message)(Vg_DebugMsg,
+ "general CBs: %d allocs, %d discards, %d maxinuse, %d search",
+ vg_cgb_allocs, vg_cgb_discards, vg_cgb_used_MAX, vg_cgb_search
+ );
+}
+
+static Bool find_addr(VgHashNode* sh_ch, void* ap)
+{
+ MAC_Chunk *m = (MAC_Chunk*)sh_ch;
+ Addr a = *(Addr*)ap;
+
+ return VG_(addr_is_in_block)(a, m->data, m->size);
+}
+
+static Bool client_perm_maybe_describe( Addr a, AddrInfo* ai )
+{
+ UInt i;
+ /* VG_(printf)("try to identify %d\n", a); */
+
+ /* Perhaps it's a general block ? */
+ for (i = 0; i < vg_cgb_used; i++) {
+ if (vg_cgbs[i].kind == CG_NotInUse)
+ continue;
+ if (VG_(addr_is_in_block)(a, vg_cgbs[i].start, vg_cgbs[i].size)) {
+ MAC_Mempool **d, *mp;
+
+ /* OK - maybe it's a mempool, too? */
+ mp = (MAC_Mempool*)VG_(HT_get_node)(MAC_(mempool_list),
+ (UWord)vg_cgbs[i].start,
+ (void*)&d);
+ if(mp != NULL) {
+ if(mp->chunks != NULL) {
+ MAC_Chunk *mc;
+
+ mc = (MAC_Chunk*)VG_(HT_first_match)(mp->chunks, find_addr, &a);
+ if(mc != NULL) {
+ ai->akind = UserG;
+ ai->blksize = mc->size;
+ ai->rwoffset = (Int)(a) - (Int)mc->data;
+ ai->lastchange = mc->where;
+ return True;
+ }
+ }
+ ai->akind = Mempool;
+ ai->blksize = vg_cgbs[i].size;
+ ai->rwoffset = (Int)(a) - (Int)(vg_cgbs[i].start);
+ ai->lastchange = vg_cgbs[i].where;
+ return True;
+ }
+ ai->akind = UserG;
+ ai->blksize = vg_cgbs[i].size;
+ ai->rwoffset = (Int)(a) - (Int)(vg_cgbs[i].start);
+ ai->lastchange = vg_cgbs[i].where;
+ return True;
+ }
+ }
+ return False;
+}
+
+Bool SK_(handle_client_request) ( ThreadId tid, UWord* arg, UWord* ret )
+{
+ Int i;
+ Bool ok;
+ Addr bad_addr;
+
+ if (!VG_IS_SKIN_USERREQ('M','C',arg[0])
+ && VG_USERREQ__MALLOCLIKE_BLOCK != arg[0]
+ && VG_USERREQ__FREELIKE_BLOCK != arg[0]
+ && VG_USERREQ__CREATE_MEMPOOL != arg[0]
+ && VG_USERREQ__DESTROY_MEMPOOL != arg[0]
+ && VG_USERREQ__MEMPOOL_ALLOC != arg[0]
+ && VG_USERREQ__MEMPOOL_FREE != arg[0])
+ return False;
+
+ switch (arg[0]) {
+ case VG_USERREQ__CHECK_WRITABLE: /* check writable */
+ ok = mc_check_writable ( arg[1], arg[2], &bad_addr );
+ if (!ok)
+ MC_(record_user_error) ( tid, bad_addr, /*isWrite*/True,
+ /*isUnaddr*/True );
+ *ret = ok ? (UWord)NULL : bad_addr;
+ break;
+
+ case VG_USERREQ__CHECK_READABLE: { /* check readable */
+ MC_ReadResult res;
+ res = mc_check_readable ( arg[1], arg[2], &bad_addr );
+ if (MC_AddrErr == res)
+ MC_(record_user_error) ( tid, bad_addr, /*isWrite*/False,
+ /*isUnaddr*/True );
+ else if (MC_ValueErr == res)
+ MC_(record_user_error) ( tid, bad_addr, /*isWrite*/False,
+ /*isUnaddr*/False );
+ *ret = ( res==MC_Ok ? (UWord)NULL : bad_addr );
+ break;
+ }
+
+ case VG_USERREQ__DO_LEAK_CHECK:
+ mc_detect_memory_leaks();
+ *ret = 0; /* return value is meaningless */
+ break;
+
+ case VG_USERREQ__MAKE_NOACCESS: /* make no access */
+ i = vg_alloc_client_block();
+ /* VG_(printf)("allocated %d %p\n", i, vg_cgbs); */
+ vg_cgbs[i].kind = CG_NoAccess;
+ vg_cgbs[i].start = arg[1];
+ vg_cgbs[i].size = arg[2];
+ vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
+ mc_make_noaccess ( arg[1], arg[2] );
+ *ret = i;
+ break;
+
+ case VG_USERREQ__MAKE_WRITABLE: /* make writable */
+ i = vg_alloc_client_block();
+ vg_cgbs[i].kind = CG_Writable;
+ vg_cgbs[i].start = arg[1];
+ vg_cgbs[i].size = arg[2];
+ vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
+ mc_make_writable ( arg[1], arg[2] );
+ *ret = i;
+ break;
+
+ case VG_USERREQ__MAKE_READABLE: /* make readable */
+ i = vg_alloc_client_block();
+ vg_cgbs[i].kind = CG_Readable;
+ vg_cgbs[i].start = arg[1];
+ vg_cgbs[i].size = arg[2];
+ vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
+ mc_make_readable ( arg[1], arg[2] );
+ *ret = i;
+ break;
+
+ case VG_USERREQ__DISCARD: /* discard */
+ if (vg_cgbs == NULL
+ || arg[2] >= vg_cgb_used || vg_cgbs[arg[2]].kind == CG_NotInUse)
+ return 1;
+ sk_assert(arg[2] >= 0 && arg[2] < vg_cgb_used);
+ vg_cgbs[arg[2]].kind = CG_NotInUse;
+ vg_cgb_discards++;
+ *ret = 0;
+ break;
+
+ case VG_USERREQ__GET_VBITS:
+ /* Returns: 1 == OK, 2 == alignment error, 3 == addressing
+ error. */
+ /* VG_(printf)("get_vbits %p %p %d\n", arg[1], arg[2], arg[3] ); */
+ *ret = mc_get_or_set_vbits_for_client
+ ( tid, arg[1], arg[2], arg[3], False /* get them */ );
+ break;
+
+ case VG_USERREQ__SET_VBITS:
+ /* Returns: 1 == OK, 2 == alignment error, 3 == addressing
+ error. */
+ /* VG_(printf)("set_vbits %p %p %d\n", arg[1], arg[2], arg[3] ); */
+ *ret = mc_get_or_set_vbits_for_client
+ ( tid, arg[1], arg[2], arg[3], True /* set them */ );
+ break;
+
+ default:
+ if (MAC_(handle_common_client_requests)(tid, arg, ret )) {
+ return True;
+ } else {
+ VG_(message)(Vg_UserMsg,
+ "Warning: unknown memcheck client request code %llx",
+ (ULong)arg[0]);
+ return False;
+ }
+ }
+ return True;
+}
/*------------------------------------------------------------*/
@@ -1650,12 +1942,12 @@ void SK_(pre_clo_init)(void)
MAC_( new_mem_heap) = & mc_new_mem_heap;
- MAC_( ban_mem_heap) = & MC_(make_noaccess);
+ MAC_( ban_mem_heap) = & mc_make_noaccess;
MAC_(copy_mem_heap) = & mc_copy_address_range_state;
- MAC_( die_mem_heap) = & MC_(make_noaccess);
- MAC_(check_noaccess) = & MC_(check_noaccess);
+ MAC_( die_mem_heap) = & mc_make_noaccess;
+ MAC_(check_noaccess) = & mc_check_noaccess;
VG_(init_new_mem_startup) ( & mc_new_mem_startup );
- VG_(init_new_mem_stack_signal) ( & MC_(make_writable) );
- VG_(init_new_mem_brk) ( & MC_(make_writable) );
+ VG_(init_new_mem_stack_signal) ( & mc_make_writable );
+ VG_(init_new_mem_brk) ( & mc_make_writable );
VG_(init_new_mem_mmap) ( & mc_set_perms );
@@ -1663,7 +1955,7 @@ void SK_(pre_clo_init)(void)
VG_(init_change_mem_mprotect) ( & mc_set_perms );
- VG_(init_die_mem_stack_signal) ( & MC_(make_noaccess) );
- VG_(init_die_mem_brk) ( & MC_(make_noaccess) );
- VG_(init_die_mem_munmap) ( & MC_(make_noaccess) );
+ VG_(init_die_mem_stack_signal) ( & mc_make_noaccess );
+ VG_(init_die_mem_brk) ( & mc_make_noaccess );
+ VG_(init_die_mem_munmap) ( & mc_make_noaccess );
VG_(init_new_mem_stack_4) ( & MAC_(new_mem_stack_4) );
@@ -1681,10 +1973,12 @@ void SK_(pre_clo_init)(void)
VG_(init_die_mem_stack) ( & MAC_(die_mem_stack) );
- VG_(init_ban_mem_stack) ( & MC_(make_noaccess) );
+ VG_(init_ban_mem_stack) ( & mc_make_noaccess );
VG_(init_pre_mem_read) ( & mc_check_is_readable );
VG_(init_pre_mem_read_asciiz) ( & mc_check_is_readable_asciiz );
VG_(init_pre_mem_write) ( & mc_check_is_writable );
- VG_(init_post_mem_write) ( & MC_(make_readable) );
+ VG_(init_post_mem_write) ( & mc_make_readable );
+
+ VG_(init_pre_reg_read) ( & mc_pre_reg_read );
VG_(init_post_regs_write_init) ( & mc_post_regs_write_init );
@@ -1716,5 +2010,5 @@ void SK_(pre_clo_init)(void)
/* Additional block description for VG_(describe_addr)() */
- MAC_(describe_addr_supp) = MC_(client_perm_maybe_describe);
+ MAC_(describe_addr_supp) = client_perm_maybe_describe;
init_shadow_memory();
@@ -1728,10 +2022,10 @@ void SK_(post_clo_init) ( void )
void SK_(fini) ( Int exitcode )
{
- MAC_(common_fini)( MC_(detect_memory_leaks) );
+ MAC_(common_fini)( mc_detect_memory_leaks );
if (0) {
VG_(message)(Vg_DebugMsg,
"------ Valgrind's client block stats follow ---------------" );
- MC_(show_client_block_stats)();
+ show_client_block_stats();
}
}
--- valgrind/memcheck/docs/mc_main.html #1.12:1.13
@@ -313,14 +313,18 @@
read/write permissions</h4>
-Memcheck checks all parameters to system calls. If a system call
-needs to read from a buffer provided by your program, Memcheck checks
-that the entire buffer is addressible and has valid data, ie, it is
-readable. And if the system call needs to write to a user-supplied
-buffer, Memcheck checks that the buffer is addressible. After the
-system call, Memcheck updates its administrative information to
-precisely reflect any changes in memory permissions caused by the
-system call.
+Memcheck checks all parameters to system calls, i.e:
+<ul>
+<li>It checks all the direct parameters themselves.
+<li>Also, if a system call needs to read from a buffer provided by your
+ program, Memcheck checks that the entire buffer is addressible and has
+ valid data, ie, it is readable.
+<li>Also, if the system call needs to write to a user-supplied buffer, Memcheck
+ checks that the buffer is addressible.
+</ul>
+
+After the system call, Memcheck updates its administrative information to
+precisely reflect any changes in memory permissions caused by the system call.
-<p>Here's an example of a system call with an invalid parameter:
+<p>Here's an example of two system calls with invalid parameters:
<pre>
#include <stdlib.h>
@@ -328,26 +332,31 @@
int main( void )
{
- char* arr = malloc(10);
- (void) write( 1 /* stdout */, arr, 10 );
- return 0;
+ char* arr = malloc(10);
+ int* arr2 = malloc(sizeof(int));
+ write( 1 /* stdout */, arr, 10 );
+ exit(arr2[0]);
}
</pre>
-<p>You get this complaint ...
+<p>You get these complaints ...
<pre>
- Syscall param write(buf) contains uninitialised or unaddressable byte(s)
- at 0x4035E072: __libc_write
- by 0x402A6E5E: __libc_start_main (libc-start.c:129)
- by 0x80483B1: (within tests/badwrite)
- by <bogus frame pointer> ???
- Address 0x3807E6D0 is 0 bytes inside a block of size 10 alloc'd
- at 0x4004FEE6: malloc (ut_clientmalloc.c:539)
- by 0x80484A0: main (tests/badwrite.c:6)
- by 0x402A6E5E: __libc_start_main (libc-start.c:129)
- by 0x80483B1: (within tests/badwrite)
+ Syscall param write(buf) points to uninitialised byte(s)
+ at 0x25A48723: __write_nocancel (in /lib/tls/libc-2.3.3.so)
+ by 0x259AFAD3: __libc_start_main (in /lib/tls/libc-2.3.3.so)
+ by 0x8048348: (within /auto/homes/njn25/grind/head4/a.out)
+ Address 0x25AB8028 is 0 bytes inside a block of size 10 alloc'd
+ at 0x259852B0: malloc (vg_replace_malloc.c:130)
+ by 0x80483F1: main (a.c:5)
+
+ Syscall param exit(error_code) contains uninitialised byte(s)
+ at 0x25A21B44: __GI__exit (in /lib/tls/libc-2.3.3.so)
+ by 0x8048426: main (a.c:8)
</pre>
-<p>... because the program has tried to write uninitialised junk from
-the malloc'd block to the standard output.
+<p>... because the program has (a) tried to write uninitialised junk from
+the malloc'd block to the standard output, and (b) passed an uninitialised
+value to <code>exit</code>. Note that the first error refers to the memory
+pointed to by <code>buf</code> (not <code>buf</code> itself), but the second
+error refers to the argument <code>error_code</code> itself.
<h4>3.3.6 Overlapping source and destination blocks</h4>
--- valgrind/memcheck/tests/Makefile.am #1.54:1.55
@@ -52,4 +52,6 @@
realloc2.stderr.exp realloc2.vgtest \
realloc3.stderr.exp realloc3.vgtest \
+ scalar.stderr.exp scalar.vgtest \
+ scalar_supp.stderr.exp scalar_supp.vgtest scalar.supp \
sigaltstack.stderr.exp sigaltstack.vgtest \
signal2.stderr.exp \
@@ -80,5 +82,5 @@
nanoleak new_nothrow \
null_socket overlap \
- realloc1 realloc2 realloc3 sigaltstack signal2 \
+ realloc1 realloc2 realloc3 scalar sigaltstack signal2 \
str_tester supp1 supp2 suppfree \
trivialleak weirdioctl \
@@ -132,4 +134,5 @@
realloc2_SOURCES = realloc2.c
realloc3_SOURCES = realloc3.c
+scalar_SOURCES = scalar.c
signal2_SOURCES = signal2.c
supp1_SOURCES = supp.c
--- valgrind/memcheck/tests/badpoll.stderr.exp #1.1:1.2
@@ -1,3 +1,3 @@
-Syscall param poll(ufds) contains uninitialised or unaddressable byte(s)
+Syscall param poll(ufds) points to uninitialised byte(s)
at 0x........: poll (in /...libc...)
by 0x........: main (badpoll.c:22)
@@ -6,5 +6,5 @@
by 0x........: main (badpoll.c:12)
-Syscall param poll(ufds) contains unaddressable byte(s)
+Syscall param poll(ufds) points to unaddressable byte(s)
at 0x........: poll (in /...libc...)
by 0x........: main (badpoll.c:22)
--- valgrind/memcheck/tests/buflen_check.stderr.exp #1.9:1.10
@@ -1,3 +1,3 @@
-Syscall param socketcall.getsockname(name) contains unaddressable byte(s)
+Syscall param socketcall.getsockname(name) points to unaddressable byte(s)
at 0x........: getsockname (in /...libc...)
by 0x........: __libc_start_main (...libc...)
@@ -5,5 +5,5 @@
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-Syscall param socketcall.getsockname(namelen_in) contains uninitialised or unaddressable byte(s)
+Syscall param socketcall.getsockname(namelen_in) points to unaddressable byte(s)
at 0x........: getsockname (in /...libc...)
by 0x........: __libc_start_main (...libc...)
--- valgrind/memcheck/tests/execve.stderr.exp #1.2:1.3
@@ -1,13 +1,13 @@
-Syscall param execve(filename) contains uninitialised or unaddressable byte(s)
+Syscall param execve(filename) points to unaddressable byte(s)
at 0x........: execve (in /...libc...)
by 0x........: main (execve.c:8)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-Syscall param execve(argv[i]) contains uninitialised or unaddressable byte(s)
+Syscall param execve(argv[i]) points to unaddressable byte(s)
at 0x........: execve (in /...libc...)
by 0x........: main (execve.c:8)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-Syscall param execve(envp[i]) contains uninitialised or unaddressable byte(s)
+Syscall param execve(envp[i]) points to unaddressable byte(s)
at 0x........: execve (in /...libc...)
by 0x........: main (execve.c:8)
--- valgrind/memcheck/tests/execve2.stderr.exp #1.1:1.2
@@ -1,3 +1,3 @@
-Syscall param execve(filename) contains uninitialised or unaddressable byte(s)
+Syscall param execve(filename) points to unaddressable byte(s)
at 0x........: execve (in /...libc...)
by 0x........: main (execve2.c:6)
--- valgrind/memcheck/tests/fwrite.stderr.exp #1.9:1.10
@@ -1,3 +1,3 @@
-Syscall param write(buf) contains uninitialised or unaddressable byte(s)
+Syscall param write(buf) points to uninitialised byte(s)
at 0x........: write (in /...libc...)
by 0x........: __libc_start_main (...libc...)
--- valgrind/memcheck/tests/weirdioctl.c #1.2:1.3
@@ -2,5 +2,8 @@
/* A program which sets a readable fd to have a timeout, and therefore
needs --weird-hacks=ioctl-VTIME in order to run without
- blocking. */
+ blocking.
+
+ [Nb: no longer true, since the ioctl-VTIME weird hack no longer exists]
+*/
#include <stdio.h>
--- valgrind/memcheck/tests/weirdioctl.stderr.exp #1.8:1.9
@@ -1,3 +1,3 @@
-Syscall param ioctl(TCSET{A,AW,AF}) contains uninitialised or unaddressable byte(s)
+Syscall param ioctl(TCSET{A,AW,AF}) points to uninitialised byte(s)
at 0x........: ioctl (in /...libc...)
by 0x........: __libc_start_main (...libc...)
--- valgrind/memcheck/tests/weirdioctl.stdout.exp #1.3:1.4
@@ -1,52 +1,52 @@
first ioctl returned -1
-got 118
-got 103
-got 111
+got 10
+got 47
+got 42
+got 32
+got 65
+got 32
got 112
-got 116
-got 115
-got 58
+got 114
+got 111
+got 103
+got 114
+got 97
+got 109
got 32
-got 45
-got 45
got 119
-got 101
-got 105
-got 114
-got 100
-got 45
got 104
-got 97
-got 99
-got 107
-got 115
-got 61
got 105
-got 111
got 99
+got 104
+got 32
+got 115
+got 101
got 116
-got 108
-got 45
-got 86
-got 84
-got 73
-got 77
-got 69
+got 115
+got 32
+got 97
got 32
-got 45
-got 113
-got 10
-got 112
got 114
-got 111
-got 103
-got 58
+got 101
+got 97
+got 100
+got 97
+got 98
+got 108
+got 101
got 32
+got 102
+got 100
got 32
+got 116
+got 111
got 32
-got 119
+got 104
+got 97
+got 118
got 101
-got 105
-got 114
-got 100
+got 32
+got 97
+got 32
+got 116
second ioctl returned -1
--- valgrind/memcheck/tests/weirdioctl.vgtest #1.3:1.4
@@ -1,3 +1,3 @@
-vgopts: --weird-hacks=ioctl-VTIME -q
prog: weirdioctl
-args: < weirdioctl.vgtest
+vgopts: -q
+args: < weirdioctl.c
--- valgrind/memcheck/tests/writev.stderr.exp #1.7:1.8
@@ -1,4 +1,4 @@
Test file created.
-Syscall param writev(vector[...]) contains uninitialised or unaddressable byte(s)
+Syscall param writev(vector[...]) points to unaddressable byte(s)
at 0x........: writev (in /...libc...)
by 0x........: main (writev.c:56)
@@ -6,5 +6,5 @@
Received EFAULT as expected
-Syscall param writev(vector) contains uninitialised or unaddressable byte(s)
+Syscall param writev(vector) points to unaddressable byte(s)
at 0x........: writev (in /...libc...)
by 0x........: main (writev.c:68)
@@ -12,5 +12,5 @@
Received EINVAL as expected
-Syscall param readv(vector) contains uninitialised or unaddressable byte(s)
+Syscall param readv(vector) points to unaddressable byte(s)
at 0x........: readv (in /...libc...)
by 0x........: main (writev.c:76)
--- valgrind/memcheck/tests/writev.stderr.exp2 #1.3:1.4
@@ -1,4 +1,4 @@
Test file created.
-Syscall param writev(vector[...]) contains uninitialised or unaddressable byte(s)
+Syscall param writev(vector[...]) points to unaddressable byte(s)
at 0x........: (within /...libc...)
by 0x........: main (writev.c:56)
@@ -6,5 +6,5 @@
Received EFAULT as expected
-Syscall param writev(vector) contains uninitialised or unaddressable byte(s)
+Syscall param writev(vector) points to unaddressable byte(s)
at 0x........: (within /...libc...)
by 0x........: main (writev.c:68)
@@ -12,5 +12,5 @@
Received EINVAL as expected
-Syscall param readv(vector) contains uninitialised or unaddressable byte(s)
+Syscall param readv(vector) points to unaddressable byte(s)
at 0x........: readv (in /...libc...)
by 0x........: main (writev.c:76)
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 18:46:16
|
On Mon, 8 Nov 2004, Tom Hughes wrote: >> - Started overhauling the syscalls to account for different architectures; >> in particular, accounts for the fact that the __NR_foo syscall number >> often doesn't directly match with the sys_foo() function that implements the >> function in the Linux kernel. So started introducing this indirection as >> needed. Currently, only read() and write() have been done; the transition >> will be staged, since doing all syscalls in one hit is a total pain. > > Why do we care what the name of the kernel function used to handle the > system call is? Surely it's better to base our stuff on the externally > visible name of the system call - ie it's __NR_xxx name. But the __NR_foo name means different things on different architectures. Take __NR_lchown as an example. On x86, when you call syscall(__NR_lchown, ...), it ends up calling sys_lchown16() in the kernel. On x86-64, it instead ends up calling sys_lchown() in the kernel. There are lots of examples like this. The syscall wrappers (the PRE() and POST()) functions should be matched with the correct sys_foo()/old_foo() functions. We don't know just by looking at the __NR_foo constant which sys_foo() function will be called, so we need to specify the __NR_foo-->sys_foo() mapping ourselves. Is that clear? N |
|
From: Tom H. <th...@cy...> - 2004-11-08 18:16:42
|
In message <200...@of...>
Nicholas Nethercote <nj...@ca...> wrote:
> - Started overhauling the syscalls to account for different architectures;
> in particular, accounts for the fact that the __NR_foo syscall number
> often doesn't directly match with the sys_foo() function that implements the
> function in the Linux kernel. So started introducing this indirection as
> needed. Currently, only read() and write() have been done; the transition
> will be staged, since doing all syscalls in one hit is a total pain.
Why do we care what the name of the kernel function used to handle the
system call is? Surely it's better to base our stuff on the externally
visible name of the system call - ie it's __NR_xxx name.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 17:51:43
|
CVS commit by nethercote:
Arch-abstraction:
- Started overhauling the syscalls to account for different architectures;
in particular, accounts for the fact that the __NR_foo syscall number
often doesn't directly match with the sys_foo() function that implements the
function in the Linux kernel. So started introducing this indirection as
needed. Currently, only read() and write() have been done; the transition
will be staged, since doing all syscalls in one hit is a total pain.
This will also pave the way for scalar syscall arg checking with Memcheck,
now that it is clear what the prototypes of the relevant syscalls are.
- Removed support for 2.2 kernels in the configure test, after discussion with
Julian. If it causes major problems, we can consider reverting.
M +1 -6 configure.in 1.141
M +56 -9 coregrind/vg_syscalls.c 1.167
--- valgrind/configure.in #1.140:1.141
@@ -124,12 +124,7 @@
;;
- 2.2.*)
- AC_MSG_RESULT([2.2 family (${kernel})])
- AC_DEFINE([KERNEL_2_2], 1, [Define to 1 if you're using Linux 2.2.x])
- ;;
-
*)
AC_MSG_RESULT([unsupported (${kernel})])
- AC_MSG_ERROR([Valgrind works on kernels 2.2, 2.4, 2.6])
+ AC_MSG_ERROR([Valgrind works on kernels 2.4, 2.6])
;;
esac
--- valgrind/coregrind/vg_syscalls.c #1.166:1.167
@@ -33,5 +33,5 @@
/* All system calls are channelled through here, doing two things:
- * notify the tool of the memory events (reads, writes) happening
+ * notify the tool of the events (mem/reg reads, writes) happening
* perform the syscall, usually by passing it along to the kernel
@@ -43,4 +43,6 @@
*/
+#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) /*nothing, so far*/
+
#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
@@ -992,7 +994,16 @@ static Bool fd_allowed(Int fd, const Cha
/* ---------------------------------------------------------------------
- The Main Entertainment ...
+ The Main Entertainment ... syscall wrappers
------------------------------------------------------------------ */
+/* Note: the PRE() and POST() wrappers are for the actual functions
+ implementing the system calls in the Linux kernel. These mostly have
+ names like sys_write(); a few have names like old_mmap(). See the
+ comment for sys_info[] and related arrays for important info about the
+ __NR_foo constants and their relationship to the sys_foo() functions.
+
+ XXX: some of these are arch-specific, and should be factored out.
+*/
+
#define MayBlock (1 << 0)
#define PostOnFail (1 << 1)
@@ -4085,8 +4096,9 @@ POST(open)
}
-PRE(read)
+PRE(sys_read)
{
- /* size_t read(int fd, void *buf, size_t count); */
PRINT("read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
+ PRE_REG_READ3(ssize_t, sys_read,
+ unsigned int, fd, char __user *, buf, size_t, count);
if (!fd_allowed(arg1, "read", tid, False))
@@ -4096,13 +4108,14 @@ PRE(read)
}
-POST(read)
+POST(sys_read)
{
POST_MEM_WRITE( arg2, res );
}
-PRE(write)
+PRE(sys_write)
{
- /* size_t write(int fd, const void *buf, size_t count); */
PRINT("write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
+ PRE_REG_READ3(ssize_t, sys_write,
+ unsigned int, fd, const char __user *, buf, size_t, count);
if (!fd_allowed(arg1, "write", tid, False))
set_result( -VKI_EBADF );
@@ -5626,4 +5639,28 @@ POST(clock_getres)
}
+
+/* ---------------------------------------------------------------------
+ Summary info about syscalls
+ ------------------------------------------------------------------ */
+
+/* Important point: for each arch/Linux platform, the name of the constant
+ for a syscall (eg. __NR_write) usually matches the name of the function
+ in the Linux kernel that implements it (eg. sys_write()). However, this
+ is not always the case. For example:
+
+ __NR_lchown --> sys_lchown16()
+ __NR_lchown32 --> sys_lchown()
+ __NR_select --> old_select()
+ __NR__newselect --> sys_select()
+
+ Therefore part of the role of the arrays below is to provide a mapping
+ from the __NR_foo constants to the sys_foo() PRE/POST wrappers above.
+
+ XXX: doing this in stages, so we're in transition between the old
+ SYSB_/SYSBA macros to the new SYSX_/SYS_XY macros.
+
+ XXX: some of these are arch-specific, and should be factored out.
+*/
+
struct sys_info {
UInt flags;
@@ -5634,4 +5671,7 @@ struct sys_info {
#define SYSBA(name, flags) [__NR_##name] = { flags, before_##name, after_##name }
+#define SYSX_(const, name, flags) [const] = { flags, before_##name, NULL }
+#define SYSXY(const, name, flags) [const] = { flags, before_##name, after_##name }
+
static void bad_before(ThreadId tid, ThreadState *tst)
{
@@ -5819,6 +5859,8 @@ static const struct sys_info sys_info[]
SYSB_(_newselect, MayBlock),
SYSBA(open, MayBlock),
- SYSBA(read, MayBlock),
- SYSB_(write, MayBlock),
+// SYSBA(read, MayBlock),
+// SYSB_(write, MayBlock),
+ SYSXY(__NR_read, sys_read, MayBlock),
+ SYSX_(__NR_write, sys_write, MayBlock),
SYSBA(creat, MayBlock),
SYSBA(pipe, 0),
@@ -5924,4 +5966,9 @@ static const struct sys_info sys_info[]
#undef SYSBA
+
+/* ---------------------------------------------------------------------
+ Executing the syscalls
+ ------------------------------------------------------------------ */
+
Bool VG_(pre_syscall) ( ThreadId tid )
{
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 13:31:43
|
CVS commit by nethercote:
Don't silently ignore any suppression contexts beyond the 4th -- instead abort
with a warning. Addresses part of bug #77922.
MERGED FROM HEAD
M +16 -5 vg_errcontext.c 1.58.2.2
--- valgrind/coregrind/vg_errcontext.c #1.58.2.1:1.58.2.2
@@ -787,5 +787,5 @@ static void load_one_suppressions_file (
# define N_BUF 200
Int fd, i;
- Bool eof;
+ Bool eof, too_many_contexts = False;
Char buf[N_BUF+1];
Char* tool_names;
@@ -883,7 +883,11 @@ static void load_one_suppressions_file (
VG_N_SUPP_CALLERS */
if (!VG_STREQ(buf, "}")) {
- do {
- eof = VG_(get_line) ( fd, buf, N_BUF );
- } while (!eof && !VG_STREQ(buf, "}"));
+ // Don't just ignore extra lines -- abort. (Someone complained
+ // about silent ignoring of lines in bug #77922.)
+ //do {
+ // eof = VG_(get_line) ( fd, buf, N_BUF );
+ //} while (!eof && !VG_STREQ(buf, "}"));
+ too_many_contexts = True;
+ goto syntax_error;
}
@@ -899,4 +903,11 @@ static void load_one_suppressions_file (
"FATAL: in suppressions file `%s': unexpected EOF",
filename );
+ } else if (too_many_contexts) {
+ VG_(message)(Vg_UserMsg,
+ "FATAL: in suppressions file: `%s': at %s:",
+ filename, buf );
+ VG_(message)(Vg_UserMsg,
+ "too many lines (limit of %d contexts in suppressions)",
+ VG_N_SUPP_CALLERS);
} else {
VG_(message)(Vg_UserMsg,
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 13:24:35
|
CVS commit by nethercote:
Don't silently ignore any suppression contexts beyond the 4th -- instead abort
with a warning. Addresses part of bug #77922.
MERGE TO STABLE
M +16 -5 vg_errcontext.c 1.64
--- valgrind/coregrind/vg_errcontext.c #1.63:1.64
@@ -788,5 +788,5 @@ static void load_one_suppressions_file (
# define N_BUF 200
Int fd, i;
- Bool eof;
+ Bool eof, too_many_contexts = False;
Char buf[N_BUF+1];
Char* tool_names;
@@ -884,7 +884,11 @@ static void load_one_suppressions_file (
VG_N_SUPP_CALLERS */
if (!VG_STREQ(buf, "}")) {
- do {
- eof = VG_(get_line) ( fd, buf, N_BUF );
- } while (!eof && !VG_STREQ(buf, "}"));
+ // Don't just ignore extra lines -- abort. (Someone complained
+ // about silent ignoring of lines in bug #77922.)
+ //do {
+ // eof = VG_(get_line) ( fd, buf, N_BUF );
+ //} while (!eof && !VG_STREQ(buf, "}"));
+ too_many_contexts = True;
+ goto syntax_error;
}
@@ -900,4 +904,11 @@ static void load_one_suppressions_file (
"FATAL: in suppressions file `%s': unexpected EOF",
filename );
+ } else if (too_many_contexts) {
+ VG_(message)(Vg_UserMsg,
+ "FATAL: in suppressions file: `%s': at %s:",
+ filename, buf );
+ VG_(message)(Vg_UserMsg,
+ "too many lines (limit of %d contexts in suppressions)",
+ VG_N_SUPP_CALLERS);
} else {
VG_(message)(Vg_UserMsg,
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-08 13:03:05
|
CVS commit by nethercote:
--trace-syscalls=yes wibble
M +2 -2 vg_syscalls.c 1.166
--- valgrind/coregrind/vg_syscalls.c #1.165:1.166
@@ -1916,5 +1916,5 @@ PRE(dup)
{
/* int dup(int oldfd); */
- PRINT("dup ( %d ) --> ", arg1);
+ PRINT("dup ( %d )", arg1);
}
@@ -4114,5 +4114,5 @@ PRE(creat)
{
/* int creat(const char *pathname, mode_t mode); */
- PRINT("creat ( %p(%s), %d ) --> ",arg1,arg1,arg2);
+ PRINT("creat ( %p(%s), %d )",arg1,arg1,arg2);
PRE_MEM_RASCIIZ( "creat(pathname)", arg1 );
}
|
|
From: <js...@ac...> - 2004-11-08 03:56:32
|
Nightly build on phoenix ( SuSE 9.1 ) started at 2004-11-08 03:50:00 GMT Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow insn_basic: valgrind ./insn_basic insn_cmov: valgrind ./insn_cmov insn_fpu: valgrind ./insn_fpu insn_mmx: valgrind ./insn_mmx insn_mmxext: (cpu_test failed, skipping) insn_sse: valgrind ./insn_sse insn_sse2: (cpu_test failed, skipping) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 179 tests, 2 stderr failures, 0 stdout failures ================= corecheck/tests/fdleak_fcntl (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <to...@co...> - 2004-11-08 03:26:40
|
Nightly build on dunsmere ( Fedora Core 2 ) started at 2004-11-08 03:20:02 GMT Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 184 tests, 9 stderr failures, 0 stdout failures ================= corecheck/tests/fdleak_cmsg (stderr) corecheck/tests/fdleak_fcntl (stderr) corecheck/tests/fdleak_ipv4 (stderr) corecheck/tests/fdleak_socketpair (stderr) memcheck/tests/badpoll (stderr) memcheck/tests/buflen_check (stderr) memcheck/tests/execve (stderr) memcheck/tests/execve2 (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-11-08 03:20:33
|
Nightly build on audi ( Red Hat 9 ) started at 2004-11-08 03:15:02 GMT Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 184 tests, 9 stderr failures, 0 stdout failures ================= corecheck/tests/fdleak_cmsg (stderr) corecheck/tests/fdleak_fcntl (stderr) corecheck/tests/fdleak_ipv4 (stderr) corecheck/tests/fdleak_socketpair (stderr) memcheck/tests/badpoll (stderr) memcheck/tests/buflen_check (stderr) memcheck/tests/execve (stderr) memcheck/tests/execve2 (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-11-08 03:13:47
|
Nightly build on ginetta ( Red Hat 8.0 ) started at 2004-11-08 03:10:02 GMT Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow cpuid: valgrind ./cpuid dastest: valgrind ./dastest fpu_lazy_eflags: valgrind ./fpu_lazy_eflags insn_basic: valgrind ./insn_basic insn_cmov: valgrind ./insn_cmov insn_fpu: valgrind ./insn_fpu insn_mmx: valgrind ./insn_mmx insn_mmxext: valgrind ./insn_mmxext insn_sse: valgrind ./insn_sse insn_sse2: (cpu_test failed, skipping) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 184 tests, 0 stderr failures, 0 stdout failures ================= |
|
From: Tom H. <th...@cy...> - 2004-11-08 03:08:37
|
Nightly build on alvis ( Red Hat 7.3 ) started at 2004-11-08 03:05:02 GMT Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow fpu_lazy_eflags: valgrind ./fpu_lazy_eflags insn_basic: valgrind ./insn_basic insn_cmov: valgrind ./insn_cmov insn_fpu: valgrind ./insn_fpu insn_mmx: valgrind ./insn_mmx insn_mmxext: valgrind ./insn_mmxext insn_sse: valgrind ./insn_sse insn_sse2: (cpu_test failed, skipping) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 184 tests, 1 stderr failure, 0 stdout failures ================= memcheck/tests/vgtest_ume (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-11-08 03:04:00
|
Nightly build on standard ( Red Hat 7.2 ) started at 2004-11-08 03:00:02 GMT Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow fpu_lazy_eflags: valgrind ./fpu_lazy_eflags insn_basic: valgrind ./insn_basic insn_cmov: valgrind ./insn_cmov insn_fpu: valgrind ./insn_fpu insn_mmx: valgrind ./insn_mmx insn_mmxext: valgrind ./insn_mmxext insn_sse: valgrind ./insn_sse insn_sse2: (cpu_test failed, skipping) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 184 tests, 1 stderr failure, 0 stdout failures ================= memcheck/tests/vgtest_ume (stderr) make: *** [regtest] Error 1 |