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
|
|
From: Paul F. <pa...@so...> - 2022-12-30 12:48:02
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=ccbb75cf1d6fa24562f7fa5c5a70a4a56dcc7fa0 commit ccbb75cf1d6fa24562f7fa5c5a70a4a56dcc7fa0 Author: Paul Floyd <pj...@wa...> Date: Fri Dec 30 13:46:09 2022 +0100 FreeeBSD: Add Helgrind suppression for void __thread_specific_ptr<_Tp>::set_pointer(pointer __p) Diff: --- freebsd-helgrind.supp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/freebsd-helgrind.supp b/freebsd-helgrind.supp index 6c51bfbd01..71bfcb6abc 100644 --- a/freebsd-helgrind.supp +++ b/freebsd-helgrind.supp @@ -157,3 +157,8 @@ Helgrind:Race fun:_ZL11* } +{ + HELGRIND-CXX-TLS + Helgrind:Race + fun:_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE11set_pointerEPS1_ +} |
|
From: Paul F. <pa...@so...> - 2022-12-29 21:23:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=5cfb0173eda1843904650bef755b3e19a5b3fb1b commit 5cfb0173eda1843904650bef755b3e19a5b3fb1b Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 22:21:03 2022 +0100 Add DRD shared_timed_mutex to Helgrind This uses pthread_rwlock_timedrdlock / pthread_rwlock_timedwrlock (see commit 6ffb70e650ee7cf4ada829557dd30ababb09e078) Diff: --- helgrind/tests/Makefile.am | 1 + helgrind/tests/shared_timed_mutex.stderr.exp | 3 +++ helgrind/tests/shared_timed_mutex.vgtest | 3 +++ 3 files changed, 7 insertions(+) diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 32f926b74f..ac6b15af77 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -66,6 +66,7 @@ EXTRA_DIST = \ pth_spinlock.vgtest pth_spinlock.stdout.exp pth_spinlock.stderr.exp \ rwlock_race.vgtest rwlock_race.stdout.exp rwlock_race.stderr.exp \ rwlock_test.vgtest rwlock_test.stdout.exp rwlock_test.stderr.exp \ + shared_timed_mutex.vgtest shared_timed_mutex.stderr.exp \ shmem_abits.vgtest shmem_abits.stdout.exp shmem_abits.stderr.exp \ stackteardown.vgtest stackteardown.stdout.exp stackteardown.stderr.exp \ t2t_laog.vgtest t2t_laog.stdout.exp t2t_laog.stderr.exp \ diff --git a/helgrind/tests/shared_timed_mutex.stderr.exp b/helgrind/tests/shared_timed_mutex.stderr.exp new file mode 100644 index 0000000000..d18786f806 --- /dev/null +++ b/helgrind/tests/shared_timed_mutex.stderr.exp @@ -0,0 +1,3 @@ + + +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/shared_timed_mutex.vgtest b/helgrind/tests/shared_timed_mutex.vgtest new file mode 100644 index 0000000000..d3a044379c --- /dev/null +++ b/helgrind/tests/shared_timed_mutex.vgtest @@ -0,0 +1,3 @@ +prereq: test -e ../../drd/tests/shared_timed_mutex +vgopts: --read-var-info=yes +prog: ../../drd/tests/shared_timed_mutex |
|
From: Paul F. <pa...@so...> - 2022-12-29 21:10:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=d7c93d1f71f36e0b67770125b48a2583662af152 commit d7c93d1f71f36e0b67770125b48a2583662af152 Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 22:08:14 2022 +0100 Add a variation of the Helgrind tls_threads test This version uses GLIBC_TUNABLES in the environment so it checks that glibc.pthread.stack_cache_size can be detected and modified. Diff: --- helgrind/tests/Makefile.am | 1 + helgrind/tests/tls_threads2.stderr.exp | 2 ++ helgrind/tests/tls_threads2.vgtest | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 2157f7cd38..32f926b74f 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -135,6 +135,7 @@ EXTRA_DIST = \ tc24_nonzero_sem.stderr.exp \ tls_threads.vgtest tls_threads.stdout.exp \ tls_threads.stderr.exp \ + tls_threads2.vgtest tls_threads2.stderr.exp \ trylock.vgtest trylock.stderr.exp # Wrapper headers used by some check programs. diff --git a/helgrind/tests/tls_threads2.stderr.exp b/helgrind/tests/tls_threads2.stderr.exp new file mode 100644 index 0000000000..be3b8904e7 --- /dev/null +++ b/helgrind/tests/tls_threads2.stderr.exp @@ -0,0 +1,2 @@ +starting join in main +finished join in main diff --git a/helgrind/tests/tls_threads2.vgtest b/helgrind/tests/tls_threads2.vgtest new file mode 100644 index 0000000000..f8f0ad15be --- /dev/null +++ b/helgrind/tests/tls_threads2.vgtest @@ -0,0 +1,4 @@ +prereq: ../../tests/os_test linux +env: GLIBC_TUNABLES=glibc.pthread.mutex_spin_count=4:glibc.pthread.stack_cache_size=41943040:glibc.pthread.rseq=1 +prog: tls_threads +vgopts: -q --sim-hints=no-nptl-pthread-stackcache |
|
From: Paul F. <pa...@so...> - 2022-12-29 21:03:03
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=6ffb70e650ee7cf4ada829557dd30ababb09e078 commit 6ffb70e650ee7cf4ada829557dd30ababb09e078 Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 22:00:53 2022 +0100 Bug 400793 - pthread_rwlock_timedwrlock false positive Add Helgrind intercepts for pthread_rwlock_timedwrlock (and pthread_rwlock_timedrdlock) Reuse the DRD trylock test Diff: --- NEWS | 1 + helgrind/hg_intercepts.c | 18 ++++++++++++------ helgrind/tests/Makefile.am | 3 ++- helgrind/tests/trylock.stderr.exp | 13 +++++++++++++ helgrind/tests/trylock.vgtest | 1 + 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 071f654b50..16ae313dfc 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 170510 Don't warn about ioctl of size 0 without direction hint 351857 confusing error message about valid command line option 392331 Spurious lock not held error from inside pthread_cond_timedwait +400793 pthread_rwlock_timedwrlock false positive 444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition. 444488 Use glibc.pthread.stack_cache_size tunable 444568 drd/tests/pth_barrier_thr_cr fails on Fedora 38 diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index 0d29cb3bfa..5a83996e36 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -2222,9 +2222,6 @@ static int pthread_spin_trylock_WRK(pthread_spinlock_t *lock) pthread_rwlock_unlock pthread_rwlock_tryrdlock pthread_rwlock_trywrlock - - Unhandled: pthread_rwlock_timedrdlock - pthread_rwlock_timedwrlock */ //----------------------------------------------------------- @@ -2676,7 +2673,7 @@ static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock) //----------------------------------------------------------- -// glibc: Unhandled +// glibc: pthread_rwlock_timedrdlock // darwin: Unhandled // Solaris: pthread_rwlock_timedrdlock // Solaris: pthread_rwlock_reltimedrdlock_np @@ -2712,6 +2709,11 @@ static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock, return ret; } #if defined(VGO_linux) +PTH_FUNC(int, pthreadZurwlockZutimedrdlock, // pthread_rwlock_timedrdlock + pthread_rwlock_t *rwlock, + const struct timespec *timeout) { + return pthread_rwlock_timedrdlock_WRK(rwlock, timeout); +} #elif defined(VGO_darwin) #elif defined(VGO_freebsd) PTH_FUNC(int, pthreadZurwlockZutimedrdlock, // pthread_rwlock_timedrdlock @@ -2779,8 +2781,7 @@ PTH_FUNC(int, pthreadZurwlockZuclockrdlock, // pthread_rwlock_clockrdlock //----------------------------------------------------------- -// glibc: Unhandled -// darwin: Unhandled +// glibc: pthread_rwlock_timedwrlock // Solaris: pthread_rwlock_timedwrlock // Solaris: pthread_rwlock_reltimedwrlock_np // FreeBSD: pthread_rwlock_timedwrlock @@ -2815,6 +2816,11 @@ static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock, return ret; } #if defined(VGO_linux) +PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock + pthread_rwlock_t *rwlock, + const struct timespec *timeout) { + return pthread_rwlock_timedwrlock_WRK(rwlock, timeout); +} #elif defined(VGO_darwin) #elif defined(VGO_freebsd) PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 28f4c61912..2157f7cd38 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -134,7 +134,8 @@ EXTRA_DIST = \ tc24_nonzero_sem.vgtest tc24_nonzero_sem.stdout.exp \ tc24_nonzero_sem.stderr.exp \ tls_threads.vgtest tls_threads.stdout.exp \ - tls_threads.stderr.exp + tls_threads.stderr.exp \ + trylock.vgtest trylock.stderr.exp # Wrapper headers used by some check programs. noinst_HEADERS = safe-pthread.h safe-semaphore.h diff --git a/helgrind/tests/trylock.stderr.exp b/helgrind/tests/trylock.stderr.exp new file mode 100644 index 0000000000..e3aea4bd4e --- /dev/null +++ b/helgrind/tests/trylock.stderr.exp @@ -0,0 +1,13 @@ + +Locking rwlock via pthread_rwlock_wrlock(). +Locking rwlock via pthread_rwlock_trywrlock(). +Locking rwlock via pthread_rwlock_timedwrlock(). +Locking rwlock via pthread_rwlock_rdlock(). +Locking rwlock via pthread_rwlock_tryrdlock(). +Locking rwlock via pthread_rwlock_timedrdlock(). +Attempt to lock for writing recursively (not allowed). +Locking mutex via pthread_mutex_trylock(). +Locking mutex via pthread_mutex_lock(). +Locking mutex via pthread_mutex_timedlock(). + +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/trylock.vgtest b/helgrind/tests/trylock.vgtest new file mode 100644 index 0000000000..1d4f16d3b8 --- /dev/null +++ b/helgrind/tests/trylock.vgtest @@ -0,0 +1 @@ +prog: ../../drd/tests/trylock |
|
From: Paul F. <pa...@so...> - 2022-12-29 20:00:36
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=ab1eb2cb7473013e1458630372ee1fde2e4f66e9 commit ab1eb2cb7473013e1458630372ee1fde2e4f66e9 Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 20:59:25 2022 +0100 Update modified hg04 reference for DRD. Diff: --- drd/tests/hg04_race.stderr.exp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drd/tests/hg04_race.stderr.exp b/drd/tests/hg04_race.stderr.exp index 5b5969c995..4cc01a213f 100644 --- a/drd/tests/hg04_race.stderr.exp +++ b/drd/tests/hg04_race.stderr.exp @@ -1,8 +1,8 @@ Thread 3: Conflicting load by thread 3 at 0x........ size 4 - at 0x........: th (hg04_race.c:10) - by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 Other segment start (thread 2) @@ -11,8 +11,8 @@ Other segment end (thread 2) (thread finished, call stack no longer available) Conflicting store by thread 3 at 0x........ size 4 - at 0x........: th (hg04_race.c:10) - by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 Other segment start (thread 2) |
|
From: Philippe W. <phi...@so...> - 2022-12-29 15:37:58
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=a5b88a02d5750c464736ab1d4c66cedd4182c79e commit a5b88a02d5750c464736ab1d4c66cedd4182c79e Author: Philippe Waroquiers <phi...@sk...> Date: Thu Dec 29 15:56:36 2022 +0100 Add a test for helgrind --history-backtrace-size Extend hg04_race to have more entries in the conflicting stacktrace, and make another test hg04_race_h9 to test with one more entry than the default of 8. Diff: --- helgrind/tests/Makefile.am | 1 + helgrind/tests/hg04_race.c | 67 ++++++++++++++++++++++++++-- helgrind/tests/hg04_race.stderr.exp | 52 ++++++++++++++++------ helgrind/tests/hg04_race_h9.stderr.exp | 79 ++++++++++++++++++++++++++++++++++ helgrind/tests/hg04_race_h9.stdout.exp | 0 helgrind/tests/hg04_race_h9.vgtest | 3 ++ 6 files changed, 187 insertions(+), 15 deletions(-) diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 2286e220f1..28f4c61912 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -34,6 +34,7 @@ EXTRA_DIST = \ hg02_deadlock.vgtest hg02_deadlock.stdout.exp hg02_deadlock.stderr.exp \ hg03_inherit.vgtest hg03_inherit.stdout.exp hg03_inherit.stderr.exp \ hg04_race.vgtest hg04_race.stdout.exp hg04_race.stderr.exp \ + hg04_race_h9.vgtest hg04_race_h9.stdout.exp hg04_race_h9.stderr.exp \ hg05_race2.vgtest hg05_race2.stdout.exp hg05_race2.stderr.exp \ hg06_readshared.vgtest hg06_readshared.stdout.exp \ hg06_readshared.stderr.exp \ diff --git a/helgrind/tests/hg04_race.c b/helgrind/tests/hg04_race.c index 111195bf90..760caf8860 100644 --- a/helgrind/tests/hg04_race.c +++ b/helgrind/tests/hg04_race.c @@ -5,18 +5,79 @@ static int shared; +__attribute__((noinline)) +static void th10(void) +{ + shared++; +} + +__attribute__((noinline)) +static void th9(void) +{ + th10(); +} + +__attribute__((noinline)) +static void th8(void) +{ + th9(); +} + +__attribute__((noinline)) +static void th7(void) +{ + th8(); +} + +__attribute__((noinline)) +static void th6(void) +{ + th7(); +} + +__attribute__((noinline)) +static void th5(void) +{ + th6(); +} + +__attribute__((noinline)) +static void th4(void) +{ + th5(); +} + +__attribute__((noinline)) +static void th3(void) +{ + th4(); +} + +__attribute__((noinline)) +static void th2(void) +{ + th3(); +} + + +__attribute__((noinline)) +static void th1(void) +{ + th2(); +} + static void *th(void *v) { - shared++; + th1(); - return 0; + return 0; } int main() { pthread_t a, b; - pthread_create(&a, NULL, th, NULL); + pthread_create(&a, NULL, th, NULL); sleep(1); /* force ordering */ pthread_create(&b, NULL, th, NULL); diff --git a/helgrind/tests/hg04_race.stderr.exp b/helgrind/tests/hg04_race.stderr.exp index 67f6573963..f66394bd13 100644 --- a/helgrind/tests/hg04_race.stderr.exp +++ b/helgrind/tests/hg04_race.stderr.exp @@ -4,28 +4,42 @@ Thread #x was created ... by 0x........: pthread_create@* (hg_intercepts.c:...) - by 0x........: main (hg04_race.c:21) + by 0x........: main (hg04_race.c:82) ---Thread-Announcement------------------------------------------ Thread #x was created ... by 0x........: pthread_create@* (hg_intercepts.c:...) - by 0x........: main (hg04_race.c:19) + by 0x........: main (hg04_race.c:80) ---------------------------------------------------------------- Possible data race during read of size 4 at 0x........ by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... This conflicts with a previous write of size 4 by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) - by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 @@ -33,15 +47,29 @@ Locks held: none Possible data race during write of size 4 at 0x........ by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... This conflicts with a previous write of size 4 by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) - by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 diff --git a/helgrind/tests/hg04_race_h9.stderr.exp b/helgrind/tests/hg04_race_h9.stderr.exp new file mode 100644 index 0000000000..6e692e749a --- /dev/null +++ b/helgrind/tests/hg04_race_h9.stderr.exp @@ -0,0 +1,79 @@ + +---Thread-Announcement------------------------------------------ + +Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) + by 0x........: main (hg04_race.c:82) + +---Thread-Announcement------------------------------------------ + +Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) + by 0x........: main (hg04_race.c:80) + +---------------------------------------------------------------- + +Possible data race during read of size 4 at 0x........ by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + +This conflicts with a previous write of size 4 by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + Location 0x........ is 0 bytes inside global var "shared" + declared at hg04_race.c:6 + +---------------------------------------------------------------- + +Possible data race during write of size 4 at 0x........ by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + +This conflicts with a previous write of size 4 by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + Location 0x........ is 0 bytes inside global var "shared" + declared at hg04_race.c:6 + + +ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/hg04_race_h9.stdout.exp b/helgrind/tests/hg04_race_h9.stdout.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helgrind/tests/hg04_race_h9.vgtest b/helgrind/tests/hg04_race_h9.vgtest new file mode 100644 index 0000000000..528d7a19ac --- /dev/null +++ b/helgrind/tests/hg04_race_h9.vgtest @@ -0,0 +1,3 @@ +prog: hg04_race +vgopts: --read-var-info=yes --history-backtrace-size=9 +stderr_filter_args: hg04_race.c |
|
From: Philippe W. <phi...@so...> - 2022-12-29 12:19:00
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3c916e4cbf82eace7b9721a95f0217211aeb05fb commit 3c916e4cbf82eace7b9721a95f0217211aeb05fb Author: Philippe Waroquiers <phi...@sk...> Date: Thu Dec 29 13:18:27 2022 +0100 Fix typo in NEWS. Diff: --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 664c08a970..071f654b50 100644 --- a/NEWS +++ b/NEWS @@ -18,7 +18,7 @@ AMD64/macOS 10.13 and nanoMIPS/Linux. * Helgrind: - The option ---history-backtrace-size=<number> allows to configure the number of entries to record in the stack traces of "old" - accesses. Previous, this number was hardcoded to 8. + accesses. Previously, this number was hardcoded to 8. * ==================== FIXED BUGS ==================== |
|
From: Philippe W. <phi...@so...> - 2022-12-29 10:37:08
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=29252c77bbbcbc69eb94058677611a0e312eedf8 commit 29252c77bbbcbc69eb94058677611a0e312eedf8 Author: Philippe Waroquiers <phi...@sk...> Date: Thu Dec 29 11:11:01 2022 +0100 Add clo option the nr of entries in helgrind --history-level=full stack traces The number of such entries was hardcoded to 8. A new command line option -history-backtrace-size=number allows to set the (max) number of entries to record. Note that according perl perf/vg_perf --tools=helgrind --vg=. --vg=../trunk_untouched perf this change (unexpectedly) improves some tests: - Running tests in perf ---------------------------------------------- -- bigcode1 -- bigcode1 . :0.08s he: 2.0s (25.5x, -----) bigcode1 trunk_untouched:0.08s he: 2.1s (25.9x, -1.5%) -- bigcode2 -- bigcode2 . :0.08s he: 4.2s (52.2x, -----) bigcode2 trunk_untouched:0.08s he: 4.2s (52.0x, 0.5%) -- bz2 -- bz2 . :0.40s he: 6.5s (16.3x, -----) bz2 trunk_untouched:0.40s he: 7.4s (18.5x,-14.0%) -- fbench -- fbench . :0.15s he: 2.0s (13.2x, -----) fbench trunk_untouched:0.15s he: 2.3s (15.5x,-17.7%) -- ffbench -- ffbench . :0.16s he: 3.7s (23.2x, -----) ffbench trunk_untouched:0.16s he: 3.7s (23.4x, -0.8%) -- heap -- heap . :0.05s he: 5.1s (102.8x, -----) heap trunk_untouched:0.05s he: 5.2s (104.6x, -1.8%) -- heap_pdb4 -- heap_pdb4 . :0.07s he: 5.8s (82.9x, -----) heap_pdb4 trunk_untouched:0.07s he: 5.8s (83.3x, -0.5%) -- many-loss-records -- many-loss-records . :0.01s he: 1.0s (96.0x, -----) many-loss-records trunk_untouched:0.01s he: 0.9s (95.0x, 1.0%) -- many-xpts -- many-xpts . :0.04s he: 1.6s (38.8x, -----) many-xpts trunk_untouched:0.04s he: 1.5s (38.5x, 0.6%) -- memrw -- memrw . :0.06s he: 2.5s (41.2x, -----) memrw trunk_untouched:0.06s he: 2.5s (41.2x, 0.0%) -- sarp -- sarp . :0.02s he: 4.0s (198.0x, -----) sarp trunk_untouched:0.02s he: 3.9s (196.5x, 0.8%) -- tinycc -- tinycc . :0.10s he: 7.1s (70.7x, -----) tinycc trunk_untouched:0.10s he: 7.6s (75.8x, -7.2%) -- Finished tests in perf ---------------------------------------------- == 12 programs, 24 timings ================= Diff: --- NEWS | 7 +++ helgrind/docs/hg-manual.xml | 33 +++++++---- helgrind/hg_basics.h | 3 + helgrind/hg_main.c | 13 +++- helgrind/libhb_core.c | 140 +++++++++++++++++++++++++------------------- 5 files changed, 123 insertions(+), 73 deletions(-) diff --git a/NEWS b/NEWS index b538ad5241..664c08a970 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,13 @@ AMD64/macOS 10.13 and nanoMIPS/Linux. * Make the address space limit on FreeBSD amd64 128Gbytes (the same as Linux and Solaris, it was 32Gbytes) +* ==================== TOOL CHANGES =================== + +* Helgrind: + - The option ---history-backtrace-size=<number> allows to configure + the number of entries to record in the stack traces of "old" + accesses. Previous, this number was hardcoded to 8. + * ==================== FIXED BUGS ==================== The following bugs have been fixed or resolved. Note that "n-i-bz" diff --git a/helgrind/docs/hg-manual.xml b/helgrind/docs/hg-manual.xml index c00be7bd0c..7082e91f7a 100644 --- a/helgrind/docs/hg-manual.xml +++ b/helgrind/docs/hg-manual.xml @@ -666,9 +666,9 @@ the point it was detected.</para> "<computeroutput>This conflicts with a previous write</computeroutput>". This shows a previous access which also accessed the stated address, and which is believed to be racing -against the access in the first call stack. Note that this second -call stack is limited to a maximum of 8 entries to limit the -memory usage.</para> +against the access in the first call stack. Note that this second call +stack is limited to a maximum of <varname>--history-backtrace-size</varname> +entries with a default value of 8 to limit the memory usage.</para> <para>Finally, Helgrind may attempt to give a description of the raced-on address in source level terms. In this example, it @@ -1117,13 +1117,13 @@ unlock(mx) unlock(mx) [default: full] ]]></option> </term> <listitem> - <para><option>--history-level=full</option> (the default) causes - Helgrind collects enough information about "old" accesses that - it can produce two stack traces in a race report -- both the - stack trace for the current access, and the trace for the - older, conflicting access. To limit memory usage, "old" accesses - stack traces are limited to a maximum of 8 entries, even if - <option>--num-callers</option> value is bigger.</para> + <para><option>--history-level=full</option> (the default) causes Helgrind + collects enough information about "old" accesses that it can produce two + stack traces in a race report -- both the stack trace for the current + access, and the trace for the older, conflicting access. To limit memory + usage, "old" accesses stack traces are limited to a maximum + of <varname>--history-backtrace-size</varname> entries (default 8) or + to <option>--num-callers</option> value if this value is smaller.</para> <para>Collecting such information is expensive in both speed and memory, particularly for programs that do many inter-thread synchronisation events (locks, unlocks, etc). Without such @@ -1150,6 +1150,19 @@ unlock(mx) unlock(mx) </listitem> </varlistentry> + <varlistentry id="opt.history-backtrace-size" + xreflabel="--history-backtrace-size"> + <term> + <option><![CDATA[--history-backtrace-size=<number> + [default: 8] ]]></option> + </term> + <listitem> + <para>When <varname>--history-level=full</varname> is selected, + <varname>--history-backtrace-size=number</varname> indicates how many + entries to record in "old" accesses stack traces.</para> + </listitem> + </varlistentry> + <varlistentry id="opt.delta-stacktrace" xreflabel="--delta-stacktrace"> <term> diff --git a/helgrind/hg_basics.h b/helgrind/hg_basics.h index 89c1bc0f81..1698fca151 100644 --- a/helgrind/hg_basics.h +++ b/helgrind/hg_basics.h @@ -91,6 +91,9 @@ extern Bool HG_(clo_cmp_race_err_addrs); very useful). */ extern UWord HG_(clo_history_level); +/* Controls how many IPs an history stack records. */ +extern UInt HG_(clo_history_backtrace_size); + /* For full history level, determines how the stack trace is computed. no : a stacktrace is always computed from scratch, typically using the unwind information. diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 813c983a4c..26a37ead5e 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -5756,6 +5756,11 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) else if VG_XACT_CLO(arg, "--history-level=full", HG_(clo_history_level), 2); + else if VG_BINT_CLO(arg, "--history-backtrace-size", + HG_(clo_history_backtrace_size), 2, 500) {} + // 500 just in case someone with a lot of CPU and memory would like to use + // the same value for --num-callers and this. + else if VG_BOOL_CLO(arg, "--delta-stacktrace", HG_(clo_delta_stacktrace)) {} @@ -5765,9 +5770,9 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) /* "stuvwx" --> stuvwx (binary) */ else if VG_STR_CLO(arg, "--hg-sanity-flags", tmp_str) { Int j; - + if (6 != VG_(strlen)(tmp_str)) { - VG_(message)(Vg_UserMsg, + VG_(message)(Vg_UserMsg, "--hg-sanity-flags argument must have 6 digits\n"); return False; } @@ -5798,7 +5803,7 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) else if VG_BOOL_CLO(arg, "--ignore-thread-creation", HG_(clo_ignore_thread_creation)) {} - else + else return VG_(replacement_malloc_process_cmd_line_option)(arg); return True; @@ -5813,6 +5818,8 @@ static void hg_print_usage ( void ) " full: show both stack traces for a data race (can be very slow)\n" " approx: full trace for one thread, approx for the other (faster)\n" " none: only show trace for one thread in a race (fastest)\n" +" --history-backtrace-size=<number> record <number> callers for full\n" +" history level [8]\n" " --delta-stacktrace=no|yes [yes on linux amd64/x86]\n" " no : always compute a full history stacktrace from unwind info\n" " yes : derive a stacktrace from the previous stacktrace\n" diff --git a/helgrind/libhb_core.c b/helgrind/libhb_core.c index 683c685f24..7c0ea84503 100644 --- a/helgrind/libhb_core.c +++ b/helgrind/libhb_core.c @@ -284,7 +284,8 @@ typedef #define N_KWs_N_STACKs_PER_THREAD 62500 -#define N_FRAMES 8 +UInt HG_(clo_history_backtrace_size) = 8; + // (UInt) `echo "Reference Counted Execution Context" | md5sum` #define RCEC_MAGIC 0xab88abb2UL @@ -297,7 +298,9 @@ typedef UWord rc; UWord rcX; /* used for crosschecking */ UWord frames_hash; /* hash of all the frames */ - UWord frames[N_FRAMES]; + UWord frames[0]; + /* Variable-length array. + The size depends on HG_(clo_history_backtrace_size). */ } RCEC; @@ -305,7 +308,7 @@ struct _Thr { /* Current VTSs for this thread. They change as we go along. viR is the VTS to be used for reads, viW for writes. Usually they are the same, but can differ when we deal with reader-writer - locks. It is always the case that + locks. It is always the case that VtsID__cmpLEQ(viW,viR) == True that is, viW must be the same, or lagging behind, viR. */ VtsID viR; @@ -337,19 +340,24 @@ struct _Thr { Thread should be merged into a single structure. */ Thread* hgthread; + /* The ULongs (scalar Kws) in this accumulate in strictly + increasing order, without duplicates. This is important because + we need to be able to find a given scalar Kw in this array + later, by binary search. */ + XArray* /* ULong_n_EC */ local_Kws_n_stacks; + /* cached_rcec maintains the last RCEC that was retrieved for this thread. */ - RCEC cached_rcec; // cached_rcec value, not ref-counted. + RCEC cached_rcec; + // cached_rcec value, not ref-counted. + // As the last member of an RCEC is a variable length array, this must be + // the last element of the _Thr struct. + /* The shadow register vex_shadow1 SP register (SP_s1) is used to maintain the validity of the cached rcec. If SP_s1 is 0, then the cached rcec is invalid (cannot be used). If SP_S1 is != 0, then the cached rcec is valid. The valid cached rcec can be used to generate a new RCEC by changing just the last frame. */ - /* The ULongs (scalar Kws) in this accumulate in strictly - increasing order, without duplicates. This is important because - we need to be able to find a given scalar Kw in this array - later, by binary search. */ - XArray* /* ULong_n_EC */ local_Kws_n_stacks; }; @@ -4061,7 +4069,12 @@ static inline void set_cached_rcec_validity(Thr *thr, Bool valid) static Thr* Thr__new ( void ) { - Thr* thr = HG_(zalloc)( "libhb.Thr__new.1", sizeof(Thr) ); + Thr* thr = HG_(zalloc) + ( "libhb.Thr__new.1", + sizeof(Thr) + HG_(clo_history_backtrace_size) * sizeof(UWord)); + // We need to add the size of the frames in the cached_rcec (last member of + // _Thr). + thr->viR = VtsID_INVALID; thr->viW = VtsID_INVALID; thr->llexit_done = False; @@ -4308,7 +4321,7 @@ static Bool RCEC__differs_by_frames ( RCEC* ec1, RCEC* ec2 ) { tl_assert(ec2 && ec2->magic == RCEC_MAGIC); } if (ec1->frames_hash != ec2->frames_hash) return True; - for (i = 0; i < N_FRAMES; i++) { + for (i = 0; i < HG_(clo_history_backtrace_size); i++) { if (ec1->frames[i] != ec2->frames[i]) return True; } return False; @@ -4424,6 +4437,8 @@ static RCEC* ctxt__find_or_add ( RCEC* example ) copy = alloc_RCEC(); tl_assert(copy != example); *copy = *example; + for (Word i = 0; i < HG_(clo_history_backtrace_size); i++) + copy->frames[i] = example->frames[i]; copy->next = contextTab[hent]; contextTab[hent] = copy; stats__ctxt_tab_curr++; @@ -4457,16 +4472,17 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) { Bool ok = True; UInt i; - UWord frames[N_FRAMES]; - UWord sps[N_FRAMES]; - UWord fps[N_FRAMES]; + UWord frames[HG_(clo_history_backtrace_size)]; + UWord sps[HG_(clo_history_backtrace_size)]; + UWord fps[HG_(clo_history_backtrace_size)]; const DiEpoch cur_ep = VG_(current_DiEpoch)(); - for (i = 0; i < N_FRAMES; i++) + for (i = 0; i < HG_(clo_history_backtrace_size); i++) frames[i] = sps[i] = fps[i] = 0; - VG_(get_StackTrace)( thr->hgthread->coretid, &frames[0], N_FRAMES, + VG_(get_StackTrace)( thr->hgthread->coretid, &frames[0], + HG_(clo_history_backtrace_size), &sps[0], &fps[0], 0); - for (i = 0; i < N_FRAMES; i++) { + for (i = 0; i < HG_(clo_history_backtrace_size); i++) { if ( thr->cached_rcec.frames[i] != frames[i] ) { /* There are a bunch of "normal" reasons for which a stack derived from the cached rcec differs from frames. */ @@ -4506,16 +4522,20 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) unless asked to show below main. */ if (reason == NULL) { UInt fr_main; - Vg_FnNameKind fr_kind; - for (fr_main = 0; fr_main < N_FRAMES; fr_main++) { + Vg_FnNameKind fr_kind = Vg_FnNameNormal; + for (fr_main = 0; + fr_main < HG_(clo_history_backtrace_size); + fr_main++) { fr_kind = VG_(get_fnname_kind_from_IP) (cur_ep, frames[fr_main]); if (fr_kind == Vg_FnNameMain || fr_kind == Vg_FnNameBelowMain) break; } UInt kh_main; - Vg_FnNameKind kh_kind; - for (kh_main = 0; kh_main < N_FRAMES; kh_main++) { + Vg_FnNameKind kh_kind = Vg_FnNameNormal; + for (kh_main = 0; + kh_main < HG_(clo_history_backtrace_size); + kh_main++) { kh_kind = VG_(get_fnname_kind_from_IP) (cur_ep, thr->cached_rcec.frames[kh_main]); if (kh_kind == Vg_FnNameMain || kh_kind == Vg_FnNameBelowMain) @@ -4558,7 +4578,7 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) if (reason == NULL) { if ((i > 0 && sps[i] == sps[i-1] && fps[i] == fps[i-1]) - || (i < N_FRAMES-1 + || (i < HG_(clo_history_backtrace_size)-1 && sps[i] == sps[i+1] && fps[i] == fps[i+1])) { reason = "previous||next frame: identical sp and fp"; } @@ -4566,7 +4586,7 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) if (reason == NULL) { if ((i > 0 && fps[i] == fps[i-1]) - || (i < N_FRAMES-1 + || (i < HG_(clo_history_backtrace_size)-1 && fps[i] == fps[i+1])) { reason = "previous||next frame: identical fp"; } @@ -4585,7 +4605,7 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) So, if we find __run_exit_handlers, ignore the difference. */ if (reason == NULL) { const HChar *fnname; - for (UInt f = 0; f < N_FRAMES; f++) { + for (UInt f = 0; f < HG_(clo_history_backtrace_size); f++) { if (VG_(get_fnname)( cur_ep, frames[f], &fnname) && VG_(strcmp) ("__run_exit_handlers", fnname) == 0) { reason = "exit handlers"; @@ -4633,9 +4653,10 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) (void*)previous_frame0); VG_(pp_StackTrace)(cur_ep, &previous_frame0, 1); VG_(printf)("resulting cached stack trace:\n"); - VG_(pp_StackTrace)(cur_ep, thr->cached_rcec.frames, N_FRAMES); + VG_(pp_StackTrace)(cur_ep, thr->cached_rcec.frames, + HG_(clo_history_backtrace_size)); VG_(printf)("check stack trace:\n"); - VG_(pp_StackTrace)(cur_ep, frames, N_FRAMES); + VG_(pp_StackTrace)(cur_ep, frames, HG_(clo_history_backtrace_size)); VG_(show_sched_status) (False, // host_stacktrace False, // stack_usage @@ -4697,20 +4718,22 @@ static RCEC* get_RCEC ( Thr* thr ) stats__cached_rcec_updated++; } else { /* Compute a fresh stacktrace. */ - main_get_stacktrace( thr, &thr->cached_rcec.frames[0], N_FRAMES ); + main_get_stacktrace( thr, &thr->cached_rcec.frames[0], + HG_(clo_history_backtrace_size) ); if (DEBUG_CACHED_RCEC) { Bool save_show_below_main = VG_(clo_show_below_main); VG_(clo_show_below_main) = True; VG_(printf)("caching stack trace:\n"); VG_(pp_StackTrace)(VG_(current_DiEpoch)(), - &thr->cached_rcec.frames[0], N_FRAMES); + &thr->cached_rcec.frames[0], + HG_(clo_history_backtrace_size)); VG_(clo_show_below_main) = save_show_below_main; } stats__cached_rcec_fresh++; } hash = 0; - for (i = 0; i < N_FRAMES; i++) { + for (i = 0; i < HG_(clo_history_backtrace_size); i++) { hash ^= thr->cached_rcec.frames[i]; hash = ROLW(hash, 19); } @@ -5044,11 +5067,12 @@ Bool libhb_event_map_lookup ( /*OUT*/ExeContext** resEC, tl_assert(ref_rcec->magic == RCEC_MAGIC); tl_assert(ref_szB >= 1); /* Count how many non-zero frames we have. */ - maxNFrames = min_UInt(N_FRAMES, VG_(clo_backtrace_size)); + maxNFrames = min_UInt(HG_(clo_history_backtrace_size), + VG_(clo_backtrace_size)); for (n = 0; n < maxNFrames; n++) { if (0 == ref_rcec->frames[n]) break; } - *resEC = VG_(make_ExeContext_from_StackTrace)(ref_rcec->frames, + *resEC = VG_(make_ExeContext_from_StackTrace)(&ref_rcec->frames[0], n); *resThr = Thr__from_ThrID(ref->acc.tsw.thrid); *resSzB = ref_szB; @@ -5072,17 +5096,17 @@ void libhb_event_map_access_history ( Addr a, SizeT szB, Access_t fn ) OldRef *ref = lru.next; SizeT ref_szB; Int n; - + while (ref != &mru) { ref_szB = ref->acc.tsw.szB; if (cmp_nonempty_intervals(a, szB, ref->ga, ref_szB) == 0) { RCEC* ref_rcec = ref->acc.rcec; - for (n = 0; n < N_FRAMES; n++) { + for (n = 0; n < HG_(clo_history_backtrace_size); n++) { if (0 == ref_rcec->frames[n]) { break; } } - (*fn)(ref_rcec->frames, n, + (*fn)(&ref_rcec->frames[0], n, Thr__from_ThrID(ref->acc.tsw.thrid), ref->ga, ref_szB, @@ -5101,13 +5125,14 @@ static void event_map_init ( void ) Word i; /* Context (RCEC) pool allocator */ - rcec_pool_allocator = VG_(newPA) ( - sizeof(RCEC), - 1000 /* RCECs per pool */, - HG_(zalloc), - "libhb.event_map_init.1 (RCEC pools)", - HG_(free) - ); + rcec_pool_allocator + = VG_(newPA) ( + sizeof(RCEC) + 2 * HG_(clo_history_backtrace_size) * sizeof(UWord), + 1000 /* RCECs per pool */, + HG_(zalloc), + "libhb.event_map_init.1 (RCEC pools)", + HG_(free) + ); /* Context table */ tl_assert(!contextTab); @@ -6839,25 +6864,20 @@ void libhb_shutdown ( Bool show_stats ) stats__ctxt_tab_qs, stats__ctxt_tab_cmps ); #if 0 - VG_(printf)("sizeof(AvlNode) = %lu\n", sizeof(AvlNode)); - VG_(printf)("sizeof(WordBag) = %lu\n", sizeof(WordBag)); - VG_(printf)("sizeof(MaybeWord) = %lu\n", sizeof(MaybeWord)); - VG_(printf)("sizeof(CacheLine) = %lu\n", sizeof(CacheLine)); - VG_(printf)("sizeof(LineZ) = %lu\n", sizeof(LineZ)); - VG_(printf)("sizeof(LineF) = %lu\n", sizeof(LineF)); - VG_(printf)("sizeof(SecMap) = %lu\n", sizeof(SecMap)); - VG_(printf)("sizeof(Cache) = %lu\n", sizeof(Cache)); - VG_(printf)("sizeof(SMCacheEnt) = %lu\n", sizeof(SMCacheEnt)); - VG_(printf)("sizeof(CountedSVal) = %lu\n", sizeof(CountedSVal)); - VG_(printf)("sizeof(VTS) = %lu\n", sizeof(VTS)); - VG_(printf)("sizeof(ScalarTS) = %lu\n", sizeof(ScalarTS)); - VG_(printf)("sizeof(VtsTE) = %lu\n", sizeof(VtsTE)); - VG_(printf)("sizeof(MSMInfo) = %lu\n", sizeof(MSMInfo)); - - VG_(printf)("sizeof(struct _XArray) = %lu\n", sizeof(struct _XArray)); - VG_(printf)("sizeof(struct _WordFM) = %lu\n", sizeof(struct _WordFM)); - VG_(printf)("sizeof(struct _Thr) = %lu\n", sizeof(struct _Thr)); - VG_(printf)("sizeof(struct _SO) = %lu\n", sizeof(struct _SO)); + VG_(printf)("sizeof(CacheLine) = %zu\n", sizeof(CacheLine)); + VG_(printf)("sizeof(LineZ) = %zu\n", sizeof(LineZ)); + VG_(printf)("sizeof(LineF) = %zu\n", sizeof(LineF)); + VG_(printf)("sizeof(SecMap) = %zu\n", sizeof(SecMap)); + VG_(printf)("sizeof(Cache) = %zu\n", sizeof(Cache)); + VG_(printf)("sizeof(SMCacheEnt) = %zu\n", sizeof(SMCacheEnt)); + VG_(printf)("sizeof(CountedSVal) = %zu\n", sizeof(CountedSVal)); + VG_(printf)("sizeof(VTS) = %zu\n", sizeof(VTS)); + VG_(printf)("sizeof(ScalarTS) = %zu\n", sizeof(ScalarTS)); + VG_(printf)("sizeof(VtsTE) = %zu\n", sizeof(VtsTE)); + + VG_(printf)("sizeof(struct _Thr) = %zu\n", sizeof(struct _Thr)); + VG_(printf)("sizeof(RCEC) = %zu\n", sizeof(RCEC)); + VG_(printf)("sizeof(struct _SO) = %zu\n", sizeof(struct _SO)); #endif VG_(printf)("%s","<<< END libhb stats >>>\n"); |
|
From: Philippe W. <phi...@sk...> - 2022-12-27 22:27:56
|
This commit implements in python a set of GDB commands corresponding to the
Valgrind gdbserver monitor commands.
Basically, the idea is that one GDB command is defined for each valgrind gdbserver
subcommand and will generate and send a monitor command to valgrind.
The python code is auto-loaded by GDB as soon as GDB observes that the valgrind
preload core shared lib is loaded (e.g. vgpreload_core-amd64-linux.so).
This automatic loading is done thanks to the .debug_gdb_scripts section
added in vg_preloaded.c file.
Sadly, the auto-load only happens once valgrind has started to execute the code of ld
that loads this vg_preload file.
I have tried 2 approaches to have the python code auto-loaded when attaching at startup
to valgrind:
* have valgrind gdbserver reporting first to GDB that the executable file is
the tool executable (with a .debug_gdb_scripts section) and then reporting
the real (guest) executable file.
The drawback of this approach is that it triggers a warning/question in GDB
according to the GDB setting 'set exec-file-mismatch'.
* have valgrind gdbserver pretending to be multiprocess enabled, and report
a fake process using the tool executable with a .debug_gdb_scripts section.
The drawback of this is that this always creates a second inferior in GDB,
which will be confusing.
Possibly, we might complete the below message :
==2984378== (action at startup) vgdb me ...
==2984378==
==2984378== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==2984378== /path/to/gdb /home/philippe/valgrind/littleprogs/some_mem
==2984378== and then give GDB the following command
==2984378== target remote | /home/philippe/valgrind/git/improve/Inst/libexec/valgrind/../../bin/vgdb --pid=2984378
==2984378== --pid is optional if only one valgrind process is running
with:
==2984378== GDB valgrind python specific commands will be auto-loaded when execution begins.
==2984378== Alternatively, you might load it before with the GDB command:
==2984378== source /abs/path/to/valgrind/install/libexec/valgrind/valgrind-monitor.py
We might also have the python code loading producing a message such as:
GDB Valgrind specific command loaded.
Type "help valgrind" for more information.
The following GDB setting traces the monitor commands sent by a GDB valgrind
command to the valgrind gdbserver:
set debug valgrind-execute-monitor on
How to use the new GDB valgrind commands?
-----------------------------------------
The usage of the GDB front end commands is compatible with the
monitor command as accepted today by Valgrind.
For example, the memcheck monitor command "xb' has the following usage:
xb <addr> [<len>]
With some piece of code:
'char some_mem [5];'
xb can be used the following way:
(gdb) print &some_mem
(gdb) $2 = (char (*)[5]) 0x1ffefffe8b
(gdb) monitor xb 0x1ffefffe8b 5
ff ff ff ff ff
0x4A43040: 0x00 0x00 0x00 0x00 0x00
(gdb)
The same action can be done with the new GDB 'memcheck xb' command:
(gdb) memcheck xb 0x1ffefffe8b 5
ff ff ff ff ff
0x1FFEFFFE8B: 0x00 0x00 0x00 0x00 0x00
(gdb)
At this point, you might ask yourself: "what is the interest ?".
Using GDB valgrind commands provides several advantages compared to
the valgrind gdbserver monitor commands.
Evaluation of arguments by GDB:
-------------------------------
For relevant arguments, the GDB command will evaluate its arguments using
the usual GDB evaluation logic, for example, instead of printing/copying
the address and size of 'some_mem', the following will work:
(gdb) memcheck xb &some_mem sizeof(some_mem)
ff ff ff ff ff
0x1FFEFFFE8B: 0x00 0x00 0x00 0x00 0x00
(gdb)
or:
(gdb) p some_mem
$4 = "\000\000\000\000"
(gdb) memcheck xb &$4
ff ff ff ff ff
0x1FFEFFFE8B: 0x00 0x00 0x00 0x00 0x00
(gdb)
This is both easier to use interactively and easier to use in GDB scripts,
as you can directly use variable names in the GDB valgrind commands.
Command completion by GDB:
--------------------------
The usual command completion in GDB will work for the GDB valgrind commands.
For example, typing TAB after the letter 'l' in:
(gdb) valgrind v.info l
will show the 2 "valgrind v.info" subcommands:
last_error location
(gdb) valgrind v.info l
Note that as usual, GDB will recognise a command as soon as it is unambiguous.
Usual help and apropos support by GDB:
--------------------------------------
The Valgrind gdbserver provides an online help using:
(gdb) monitor help
However, this gives the help for all monitor commands, and is not searchable.
GDB provides a better help and documentation search.
For example, the following commands can be used to get various help
or search the GDB Valgrind command online documentation:
help valgrind
help memcheck
help helgrind
help callgrind
help massif
to get help about the general valgrind commands or the tool specific commands.
Examples of searching the online documentation:
apropos valgrind.*location
apropos -v validity
apropos -v leak
User can define aliases for the valgrind commands:
--------------------------------------------------
The following aliases are predefined:
v and vg for valgrind
mc for memcheck
hg for helgrind
cg for callgrind
ms for massif
So, the following will be equivalent:
(gdb) valgrind v.info location &some_mem
(gdb) v v.i lo &some_mem
(gdb) alias Vl = valgrind v.info location
(gdb) Vl &some_mem
Implementation should be complete.
What is still missing is updating the valgrind user manual and the NEWS file.
---
coregrind/Makefile.am | 2 +
coregrind/m_gdbserver/valgrind-monitor-def.py | 841 ++++++++++++++++++
coregrind/m_gdbserver/valgrind-monitor.py | 32 +
coregrind/m_main.c | 12 +
coregrind/vg_preloaded.c | 13 +
5 files changed, 900 insertions(+)
create mode 100644 coregrind/m_gdbserver/valgrind-monitor-def.py
create mode 100644 coregrind/m_gdbserver/valgrind-monitor.py
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 151f5c2f0..dda0689dd 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -766,6 +766,8 @@ GDBSERVER_XML_FILES = \
# so as to make sure these get copied into the install tree
vglibdir = $(pkglibexecdir)
vglib_DATA = $(GDBSERVER_XML_FILES)
+vglib_DATA += m_gdbserver/valgrind-monitor.py
+vglib_DATA += m_gdbserver/valgrind-monitor-def.py
# so as to make sure these get copied into the tarball
EXTRA_DIST += $(GDBSERVER_XML_FILES)
diff --git a/coregrind/m_gdbserver/valgrind-monitor-def.py b/coregrind/m_gdbserver/valgrind-monitor-def.py
new file mode 100644
index 000000000..9855126d2
--- /dev/null
+++ b/coregrind/m_gdbserver/valgrind-monitor-def.py
@@ -0,0 +1,841 @@
+# This file is part of Valgrind, a dynamic binary instrumentation
+# framework.
+
+# Copyright (C) 2022-2022 Philippe Waroquiers
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# The GNU General Public License is contained in the file COPYING.
+
+"""
+This file defines a series of gdb commands and subcommands to help interfacing
+gdb with the Valgrind gdbserver.
+
+!!! This only works with GDB version >= 9.1, as some command names contains
+a dot character only allowed from this version onwards.
+
+Type "help valgrind" to get help about the top of the command hierarchy.
+"""
+
+from typing import Callable
+from enum import Enum
+import re
+
+class _Debug_Valgrind_Execute_Monitor(gdb.Parameter):
+ """Set valgrind monitor command execution debugging.
+Usage: set debug valgrind-execute-monitor [on|off]"""
+ def __init__(self):
+ super().__init__("debug valgrind-execute-monitor",
+ gdb.COMMAND_MAINTENANCE,
+ gdb.PARAM_BOOLEAN)
+
+Debug_Valgrind_Execute_Monitor = _Debug_Valgrind_Execute_Monitor()
+
+def gdb_execute_monitor(monitor_command : str, from_tty : bool) -> None:
+ """Execute the given monitor command."""
+ cmd = "monitor " + monitor_command
+ if Debug_Valgrind_Execute_Monitor.value:
+ print('[valgrind-execute-monitor] sending "' + cmd + '" to valgrind')
+ try:
+ gdb.execute (cmd, from_tty)
+ except Exception as inst:
+ if monitor_command == "v.kill" and str(inst).find('Remote connection closed') >= 0:
+ print('Remote connection closed')
+ else:
+ print('Error sending "' + monitor_command + '" to valgrind: '+ str(inst))
+
+class Valgrind_Command(gdb.Command):
+ """Parent class for all Valgrind commands."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Generic Valgrind Command invoke method to override if needed."""
+ # print("generic invoke", self.mname)
+ if arg_str:
+ gdb_execute_monitor (self.mname + " " + arg_str, from_tty)
+ else:
+ gdb_execute_monitor (self.mname, from_tty)
+
+def Vinit(toolname : str,
+ mname : str,
+ command_class : Enum,
+ completer_class : Enum,
+ prefix : bool) -> Callable[[Valgrind_Command],
+ Valgrind_Command]:
+ """Class decorator to initialise and register a Valgrind_Command class.
+MNAME is the Valgrind monitor name string for this command.
+The gdb command is the concatenation of TOOLNAME and MNAME.
+TOOLNAME is valgrind for the general valgrind commands."""
+ def instantiate(GDB_Command : Valgrind_Command) -> Valgrind_Command:
+ def adhoc_init (self):
+ # print("initializing", GDB_Command)
+ if completer_class:
+ super(GDB_Command, self).__init__(name = toolname + " " + mname,
+ command_class = command_class,
+ completer_class = completer_class,
+ prefix = prefix)
+ else:
+ super(GDB_Command, self).__init__(name = toolname + " " + mname,
+ command_class = command_class,
+ prefix = prefix)
+ self.toolname=toolname
+ self.mname=mname
+ GDB_Command.__init__ = adhoc_init
+ GDB_Command() # register the command
+ return GDB_Command
+ return instantiate
+
+def build_name(command : Valgrind_Command) -> str:
+ """Returns the GDB full name for the given COMMAND."""
+ if command.mname:
+ return command.toolname + ' ' + command.mname
+ else:
+ return command.toolname
+
+def build_help(command : Valgrind_Command) -> str:
+ """Returns a string to ask help for the given COMMAND."""
+ return "help " + build_name(command)
+
+def build_type_help(command) -> str:
+ """Returns a string giving what to type to get helps about the given command"""
+ return 'Type "' + build_help(command) + '"'
+
+class Valgrind_Prefix_Command(Valgrind_Command):
+ """Parent class for all Valgrind prefix commands."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Generic Valgrind prefix Command invoke method to override if needed."""
+ # print("generic prefix invoke", self.mname)
+ if arg_str:
+ # If it is not a recognised sub-command, raise an error.
+ raise gdb.GdbError(('Undefined ' + build_name (self)
+ + ' command: "' + arg_str + '".\n'
+ + build_type_help(self)))
+ else:
+ gdb.execute (build_help(self), from_tty)
+
+class Valgrind_Prefix_Exec_Command(Valgrind_Prefix_Command):
+ """Parent class for all Valgrind prefix commands that can be executed without subcommands."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Invoke for a prefix command that can be executed."""
+ if arg_str:
+ super().invoke(arg_str, from_tty)
+ else:
+ gdb_execute_monitor (self.mname, from_tty)
+
+def eval_execute(command : Valgrind_Command,
+ arg_str : str,
+ arg_opt : bool, arg_descr : str, format_fn,
+ from_tty : bool) -> None:
+ """Evaluates ARG_STR, format the result with FORMAT_FN and
+executes the monitor command COMMAND.mname + FORMAT_FN(evaluated ARG_STR).
+ARG_OPT True indicates the argument is optional.
+ARG_DESCR is used in error messages."""
+ if arg_str:
+ eval_arg_str = gdb.parse_and_eval (arg_str)
+ gdb_execute_monitor (command.mname + " " + format_fn(eval_arg_str), from_tty)
+ elif arg_opt:
+ gdb_execute_monitor (command.mname, from_tty)
+ else:
+ raise gdb.GdbError(('Argument "' + arg_descr + '" required.\n'
+ + build_type_help(command)))
+
+def eval_execute_2(command : Valgrind_Command,
+ arg_str : str,
+ arg1_opt : bool, arg1_descr : str, format_fn1,
+ arg2_opt : bool, arg2_descr : str, format_fn2,
+ from_tty : bool) -> None:
+ """Like eval_execute but allowing 2 arguments to be extracted from ARG_STR).
+The second argument starts after the first space in ARG_STR."""
+ if arg1_opt and not arg2_opt:
+ raise gdb.GdbError(('Cannot have arg1_opt True and arg2_opt False'
+ + ' in definition of '
+ + build_name(command)))
+ if arg_str:
+ arg_str_v = arg_str.split(' ', 1);
+ eval_arg1_str = gdb.parse_and_eval (arg_str_v[0])
+ if len(arg_str_v) <= 1:
+ if arg2_opt:
+ gdb_execute_monitor (command.mname + " " + format_fn1(eval_arg1_str), from_tty)
+ else:
+ raise gdb.GdbError(('Argument 2 "' + arg2_descr + '" required.\n'
+ + build_type_help(command)))
+ else:
+ eval_arg2_str = gdb.parse_and_eval (arg_str_v[1])
+ gdb_execute_monitor (command.mname
+ + " " + format_fn1(eval_arg1_str)
+ + " " + format_fn1(eval_arg2_str),
+ from_tty)
+ elif arg1_opt and arg2_opt:
+ gdb_execute_monitor (command.mname, from_tty)
+ else:
+ raise gdb.GdbError(('Argument 1 "' + arg1_descr + '" required.\n'
+ + ('' if arg2_opt
+ else 'Argument 2 "' + arg2_descr + '" required.\n')
+ + build_type_help(command)))
+
+def def_alias(alias : str, command_name : str) -> None:
+ """Defines an alias ALIAS = COMMAND_NAME.
+Traps the error if ALIAS is already defined (so as to be able to source
+this file again)."""
+ d = "alias " + alias + ' = ' + command_name
+ try:
+ gdb.execute (d)
+ except Exception as inst:
+ print('"' + d + '" : '+ str(inst))
+
+class Valgrind_ADDR(Valgrind_Command):
+ """Common class for Valgrind commands taking ADDR arg."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "ADDR (address expression)", hex,
+ from_tty)
+
+class Valgrind_ADDR_opt(Valgrind_Command):
+ """Common class for Valgrind commands taking [ADDR] arg."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ True, "ADDR (address expression)", hex,
+ from_tty)
+
+class Valgrind_ADDR_LEN_opt(Valgrind_Command):
+ """Common class for Valgrind commands taking ADDR and [LEN] args.
+For compatibility reason with the Valgrind gdbserver monitor command,
+we detect and accept usages such as 0x1234ABCD[10]."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ if re.fullmatch("^0x[0123456789ABCDEFabcdef]+\[[^\[\]]+\]$", arg_str):
+ arg_str = arg_str.replace("[", " ")
+ arg_str = arg_str.replace("]", " ")
+ eval_execute_2(self, arg_str,
+ False, "ADDR (address expression)", hex,
+ True, "LEN (integer length expression)", str,
+ from_tty)
+
+############# The rest of this file defines first the valgrind general commands
+# then the tool specific commands.
+# The commands are defined in the same order as produced by
+# (gdb) monitor help debug
+
+############# valgrind general commands.
+
+###### Top of the hierarchy of the valgrind general commands.
+@Vinit("valgrind", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Monitor_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind gdbserver monitor commands.
+Usage: valgrind VALGRIND_MONITOR_COMMAND [ARG...]
+VALGRIND_MONITOR_COMMAND is a valgrind subcommand, matching a
+gdbserver Valgrind monitor command.
+ARG... are optional arguments. They depend on the VALGRIND_MONITOR_COMMAND.)
+
+Type "help memcheck" for memcheck specific commands.
+Type "help helgrind" for helgrind specific commands.
+Type "help callgrind" for callgrind specific commands.
+Type "help massif" for massif specific commands.
+"""
+
+def_alias("vg", "valgrind")
+def_alias("v", "valgrind") # To avoid 'v' reported as ambiguous for 'vg' and 'valgrind' !
+
+@Vinit("valgrind", "help", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Help_Command(Valgrind_Prefix_Exec_Command):
+ """Ask Valgrind gdbserver to output the help for its monitor commands.
+Usage: valgrind help
+This shows the help string reported by the Valgrind gdbserver.
+Type "help valgrind" to get help about the GDB front end commands interfacing
+to the Valgrind gdbserver monitor commands.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Invoke for a prefix command that can be executed."""
+ if arg_str:
+ super().invoke(arg_str, from_tty)
+ else:
+ gdb_execute_monitor (self.mname, from_tty)
+
+@Vinit("valgrind", "help debug", gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False)
+class Valgrind_Help_Debug_Command(Valgrind_Command):
+ """Ask Valgrind gdbserver to output the help for its monitor commands (including debugging commands).
+Usage: valgrind help debug
+This shows the help string reported by the Valgrind gdbserver.
+Type "help valgrind" to get help about the GDB front end commands interfacing
+to the Valgrind gdbserver monitor commands.
+"""
+
+@Vinit("valgrind", "v.wait", gdb.COMMAND_OBSCURE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Wait_Command(Valgrind_Command):
+ """Have Valgrind gdbserver sleeping for MS (default 0) milliseconds.
+Usage: valgrind v.wait [MS]
+MS is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty: bool) -> None:
+ eval_execute(self, arg_str,
+ True, "MS (integer expression in milliseconds)", str,
+ from_tty)
+
+@Vinit("valgrind", "v.info", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Info_Command(Valgrind_Prefix_Command):
+ """Get various information about Valgrind gdbserver.
+Usage: valgrind v.info WHAT [ARG...]
+WHAT is the v.info subcommand, specifying the type of information requested.
+ARG are optional arguments, depending on the WHAT subcommand.
+"""
+
+@Vinit("valgrind", "v.info all_errors", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_All_Errors_Command(Valgrind_Command):
+ """Show all errors found so far by Valgrind.
+Usage: valgrind v.info all_errors
+"""
+
+@Vinit("valgrind", "v.info last_error", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Last_Error_Command(Valgrind_Command):
+ """Show last error found by Valgrind.
+Usage: valgrind v.info last_error
+"""
+
+@Vinit("valgrind", "v.info location", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Info_Location_Command(Valgrind_ADDR):
+ """Show information known by Valgrind about location ADDR.
+Usage: valgrind v.info location ADDR
+ADDR is an address expression evaluated by GDB.
+"""
+
+@Vinit("valgrind", "v.info n_errs_found", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_N_Errs_Found_Command(Valgrind_Command):
+ """Show the nr of errors found so far by Valgrind and the given MSG.
+Usage: valgrind v.info n_errs_found [MSG]
+"""
+
+@Vinit("valgrind", "v.info open_fds", gdb.COMMAND_DATA, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Open_Fds_Command(Valgrind_Command):
+ """Show open file descriptors tracked by Valgrind (only if --track-fds=yes).
+Usage: valgrind v.info open_fds
+"""
+
+@Vinit("valgrind", "v.kill", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE, False)
+class Valgrind_Kill_Command(Valgrind_Command):
+ """Instruct valgrind gdbserver to kill the valgrind process.
+Usage: valgrind v.kill
+"""
+
+@Vinit("valgrind", "v.clo", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE, False)
+class Valgrind_Clo_Command(Valgrind_Command):
+ """Change one or more Valgrind dynamic command line options.
+Usage: valgrind v.clo [VALGRIND_OPTION]...
+VALGRIND_OPTION is the command line option to change.
+Example: (gdb) valgrind v.clo --stats=yes --show-below-main=yes
+
+Without VALGRIND_OPTION, shows the dynamically changeable options.
+"""
+
+@Vinit("valgrind", "v.set", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Set_Command(Valgrind_Prefix_Command):
+ """Modify various setting of Valgrind gdbserver.
+Usage: valgrind v.set WHAT [ARG]...
+WHAT is the v.set subcommand, specifying the setting to change.
+ARG are optional arguments, depending on the WHAT subcommand.
+"""
+
+@Vinit("valgrind", "v.set gdb_output", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Gdb_Output_Command(Valgrind_Command):
+ """Set Valgrind output to gdb.
+Usage: valgrind v.set gdb_output
+"""
+
+@Vinit("valgrind", "v.set log_output", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Log_Output_Command(Valgrind_Command):
+ """Set Valgrind output to Valgrind log.
+Usage: valgrind v.set log_output
+"""
+
+@Vinit("valgrind", "v.set mixed_output", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Mixed_Output_Command(Valgrind_Command):
+ """Set Valgrind output to Valgrind log, interactive output to gdb.
+Usage: valgrind v.set mixed_output
+"""
+
+@Vinit("valgrind", "v.set merge-recursive-frames", gdb.COMMAND_STATUS, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Set_Merge_Recursive_Frames_Command(Valgrind_Command):
+ """Set the number of frames for recursive calls merging in Valgrind stacktraces.
+Usage: valgrind v.set merge-recursive-frames NUM
+NUM is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "NUM (number of frames for recursive calls merging)",
+ str,
+ from_tty)
+
+@Vinit("valgrind", "v.set vgdb-error", gdb.COMMAND_RUNNING, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Set_Vgdb_Error_Command(Valgrind_Command):
+ """Set the number of errors at which Valgrind gdbserver gives control to gdb.
+Usage: valgrind v.set vgdb-error NUM
+NUM is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "NUM (number of errors)",
+ str,
+ from_tty)
+
+@Vinit("valgrind", "v.do", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Do_Command(Valgrind_Prefix_Command):
+ """Ask Valgrind gdbserver to do an internal/maintenance action.
+Usage: valgrind v.do WHAT
+WHAT is the valgrind v.do subcommand, specifying the type of action requested.
+"""
+
+@Vinit("valgrind", "v.do expensive_sanity_check_general", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Do_Expensive_Sanity_Check_General_Command(Valgrind_Command):
+ """Do an expensive Valgrind sanity check now.
+Usage: valgrind v.do expensive_sanity_check_general
+"""
+
+@Vinit("valgrind", "v.info gdbserver_status", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Gdbserver_Status_Command(Valgrind_Command):
+ """Show gdbserver status.
+Usage: valgrind v.info gdbserver_status
+"""
+
+@Vinit("valgrind", "v.info memory", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Info_Memory_Status_Command(Valgrind_Prefix_Exec_Command):
+ """Show valgrind heap memory stats.
+Usage: valgrind v.info memory
+"""
+
+@Vinit("valgrind", "v.info memory aspacemgr", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Memory_Aspacemgr_Command(Valgrind_Command):
+ """Show Valgrind heap memory stats and show Valgrind segments on log output.
+Usage: valgrind v.info memory aspacemgr
+"""
+
+@Vinit("valgrind", "v.info exectxt", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Exectxt_Command(Valgrind_Command):
+ """Show stacktraces and stats of all execontexts record by Valgrind.
+Usage: valgrind v.info exectxt
+"""
+
+@Vinit("valgrind", "v.info scheduler", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Scheduler_Command(Valgrind_Command):
+ """Show Valgrind thread state and stacktrace.
+Usage: valgrind v.info scheduler
+"""
+
+@Vinit("valgrind", "v.info stats", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Stats_Command(Valgrind_Command):
+ """Show various Valgrind and tool stats.
+Usage: valgrind v.info stats
+"""
+
+@Vinit("valgrind", "v.info unwind", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Info_Unwind_Command(Valgrind_ADDR_LEN_opt):
+ """Show unwind debug info for ADDR .. ADDR+LEN.
+Usage: valgrind v.info unwind ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+"""
+
+@Vinit("valgrind", "v.set debuglog", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Set_Debuglog_Command(Valgrind_Command):
+ """Set Valgrind debug log level to LEVEL.
+Usage: valgrind v.set LEVEL
+LEVEL is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "LEVEL (valgrind debug log level)",
+ str,
+ from_tty)
+@Vinit("valgrind", "v.set hostvisibility", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Set_Hostvisibility_Command(Valgrind_Prefix_Exec_Command):
+ """Set visibility of the internal Valgrind 'host' state.
+Without arguments, enables the host visibility.
+Host visibility allows to examine with GDB the internal status and memory
+of Valgrind.
+Usage: valgrind v.set hostvisibility
+"""
+
+@Vinit("valgrind", "v.set hostvisibility yes", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Hostvisibility_Yes_Command(Valgrind_Command):
+ """Enable visibility of the internal Valgrind 'host' state.
+Usage: valgrind v.set hostvisibility yes
+See "help v.set hostvisibility".
+"""
+
+@Vinit("valgrind", "v.set hostvisibility no", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Hostvisibility_No_Command(Valgrind_Command):
+ """Disable visibility of the internal Valgrind 'host' state.
+Usage: valgrind v.set hostvisibility no
+See "help v.set hostvisibility".
+"""
+
+def base2(value : int) -> str:
+ """Image of value in base 2 prefixed with 0b."""
+ "0b" + "{0:b}".format(value)
+
+@Vinit("valgrind", "v.translate", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Translate_Command(Valgrind_Command):
+ """Show the translation of instructions at ADDR with TRACEFLAGS.
+Usage: valgrind v.translate ADDR [TRACEFLAG]
+For TRACEFLAG values, type in shell "valgrind --help-debug".
+An additional flag 0b100000000 allows one to show gdbserver instrumentation.
+ADDR is an address expression evaluated by GDB.
+TRACEFLAG is an integer expression (used as a bitmask) evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute_2(self, arg_str,
+ False, "ADDR (address expression)", hex,
+ True, "TRACEFLAGS (bit mask expression)", base2,
+ from_tty)
+
+############# memcheck commands.
+
+###### Top of the hierarchy of the memcheck commands.
+@Vinit("memcheck", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Memcheck_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind memcheck gdbserver monitor commands.
+Usage: memcheck MEMCHECK_MONITOR_COMMAND [ARG...]
+MEMCHECK_MONITOR_COMMAND is a memcheck subcommand, matching
+a gdbserver Valgrind memcheck monitor command.
+ARG... are optional arguments. They depend on the MEMCHECK_MONITOR_COMMAND.
+"""
+
+def_alias("mc", "memcheck")
+
+@Vinit("memcheck", "xtmemory", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Memcheck_Xtmemory_Command(Valgrind_Command):
+ """Dump xtree memory profile in FILENAME (default xtmemory.kcg.%p.%n).
+Usage: memcheck xtmemory [FILENAME]
+
+Example: (gdb) memcheck xtmemory my_program_xtree.kcg
+"""
+
+@Vinit("memcheck", "xb", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Xb_Command(Valgrind_ADDR_LEN_opt):
+ """Print validity bits for LEN (default 1) bytes at ADDR.
+ bit values 0 = valid, 1 = invalid, __ = unaddressable byte
+Prints the bytes values below the corresponding validity bits
+in a layout similar to the gdb command 'x /LENxb ADDR
+Usage: memcheck xb ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck xb &p sizeof(p)
+"""
+
+@Vinit("memcheck", "get_vbits", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Get_Vbits_Command(Valgrind_ADDR_LEN_opt):
+ """Print validity bits for LEN (default 1) bytes at ADDR.
+ bit values 0 = valid, 1 = invalid, __ = unaddressable byte
+Usage: memcheck get_vbits ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck get_vbits &p sizeof(p)
+
+Note: the command 'memcheck xb ADDR [LEN]' prints the value
+and validity bits of ADDR [LEN] bytes in an easier to read format.
+"""
+
+@Vinit("memcheck", "make_memory", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, True)
+class Memcheck_Make_Memory_Command(Valgrind_Prefix_Command):
+ """Prefix command to change memory accessibility."""
+
+@Vinit("memcheck", "make_memory noaccess", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Noaccess_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as noaccess.
+Usage: memcheck make_memory noaccess ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory noaccess &p sizeof(p)
+"""
+
+@Vinit("memcheck", "make_memory undefined", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Undefined_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as undefined.
+Usage: memcheck make_memory undefined ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory undefined &p sizeof(p)
+"""
+
+@Vinit("memcheck", "make_memory defined", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Defined_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as defined.
+Usage: memcheck make_memory defined ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory defined &p sizeof(p)
+"""
+
+@Vinit("memcheck", "make_memory Definedifaddressable", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Definedifaddressable_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as Definedifaddressable.
+Usage: memcheck make_memory Definedifaddressable ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory Definedifaddressable &p sizeof(p)
+"""
+
+@Vinit("memcheck", "check_memory", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, True)
+class Memcheck_Check_Memory_Command(Valgrind_Prefix_Command):
+ """Command to check memory accessibility."""
+
+@Vinit("memcheck", "check_memory addressable", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Check_Memory_Addressable_Command(Valgrind_ADDR_LEN_opt):
+ """Check that LEN (default 1) bytes at ADDR are addressable.
+Usage: memcheck check_memory addressable ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck check_memory addressable &p sizeof(p)
+"""
+
+@Vinit("memcheck", "check_memory defined", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Check_Memory_Defined_Command(Valgrind_ADDR_LEN_opt):
+ """Check that LEN (default 1) bytes at ADDR are defined.
+Usage: memcheck check_memory defined ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck check_memory defined &p sizeof(p)
+"""
+
+@Vinit("memcheck", "leak_check", gdb.COMMAND_DATA, gdb.COMPLETE_NONE, False)
+class Memcheck_Leak_Check_Command(Valgrind_Command):
+ """Execute a memcheck leak search.
+Usage: leak_check [full*|summary|xtleak]
+ [kinds KIND1,KIND2,...|reachable|possibleleak*|definiteleak]
+ [heuristics HEUR1,HEUR2,...]
+ [increased*|changed|any]
+ [unlimited*|limited MAX_LOSS_RECORDS_OUTPUT]
+ * = defaults
+
+full: outputs stacktraces of all leaks followed by a summary.
+summary: outputs only the leak summary.
+xtleak: produce an xtree full leak result in xtleak.kcg.%p.%n
+
+KIND indicates which kind of leaks to report, and is one of:
+ definite indirect possible reachable all none
+
+HEUR indicates an heuristic to activate when doing leak search and is one of:
+ stdstring length64 newarray multipleinheritance all none*
+
+increased: only outputs the leak loss records with an increase since last leak search.
+changed: also outputs the leak loss records with a decrease.
+any: also outputs the leak loss records that did not change.
+
+unlimited: outputs all matching loss records.
+limited: outputs only the first matching MAX_LOSS_RECORDS_OUTPUT.
+
+Examples: (gdb) memcheck leak_check
+ (gdb) memcheck leak_check summary any
+ (gdb) memcheck leak_check full kinds indirect,possible
+ (gdb) memcheck leak_check full reachable any limited 100
+"""
+
+ def complete(self, text, word):
+ # print('/' + text + ' ' + word + '/\n')
+ leak_check_mode = ["full", "summary", "xtleak"]
+ leak_kind = ["kinds", "reachable", "possibleleak", "definiteleak"]
+ leak_heuristic = ["heuristics"]
+ leak_check_delta_mode = ["increased", "changed", "any"]
+ leak_check_loss_record_limit = ["unlimited", "limited"]
+ kwd_lists = [leak_check_mode, leak_kind, leak_heuristic, leak_check_delta_mode,
+ leak_check_loss_record_limit]
+ # Build the list of still allowed keywords.
+ # We append all the keywords of a list unless we find already one
+ # existing word in text that starts with the first letter of a keyword
+ # of the list. Checking the first letter is ok (currently!)
+ # as all keywords of leak_check monitor command starts with a different letter.
+ keywords = []
+ command_words = text.split()
+ # command_words.pop(0) # we do not match with the command itself.
+ for kwd_list in kwd_lists:
+ list_ok = True
+ # print('list:/' + str(kwd_list) + '/')
+ for kwd in kwd_list:
+ for command_word in command_words:
+ # print('word:/' + command_word + '/' + kwd)
+ if kwd[0] == command_word[0]:
+ # print("setting to false")
+ list_ok = False
+ if kwd.startswith(word) and word != kwd and kwd not in command_words:
+ # print('/' + word + '/' + kwd + '/')
+ keywords.append(kwd)
+ if list_ok:
+ for kwd in kwd_list:
+ keywords.append(kwd)
+ result = []
+ for keyword in keywords:
+ if keyword.startswith(word):
+ result.append(keyword)
+ return result
+
+@Vinit("memcheck", "block_list", gdb.COMMAND_DATA, gdb.COMPLETE_NONE, False)
+class Memcheck_Block_List_Command(Valgrind_Command):
+ """Show the list of blocks for a leak search loss record.
+Usage: memcheck block_list LOSS_RECORD_NR|LOSS_RECORD_NR_FROM..LOSS_RECORD_NR_TO
+ unlimited*|limited MAX_BLOCKS
+ [heuristics HEUR1,HEUR2,...]
+ * = defaults
+
+After a leak search, use block_list to show the list of blocks matching a loss
+record or matching a range of loss records.
+
+unlimited: outputs all blocks matching the selected loss records.
+limited: outputs only the first matching MAX_BLOCKS.
+
+Use heuristics to only output the blocks found via one of the given heuristics,
+where HEUR is one of:
+ stdstring length64 newarray multipleinheritance all none*
+ """
+
+@Vinit("memcheck", "who_points_at", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Who_Points_At_Command(Valgrind_ADDR_LEN_opt):
+ """Show places pointing inside LEN (default 1) bytes at ADDR.
+Usage: memcheck who_points_at ADDR [MEN]
+With LEN 1, only shows "start pointers" pointing exactly to ADDR.
+With LEN > 1, will also show "interior pointers"
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+"""
+
+############# helgrind commands.
+
+###### Top of the hierarchy of the helgrind commands.
+@Vinit("helgrind", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Helgrind_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind helgrind gdbserver monitor commands.
+Usage: helgrind HELGRIND_MONITOR_COMMAND [ARG...]
+HELGRIND_MONITOR_COMMAND is a helgrind subcommand, matching
+a gdbserver Valgrind helgrind monitor command.
+ARG... are optional arguments. They depend on the HELGRIND_MONITOR_COMMAND.
+"""
+
+def_alias("hg", "helgrind")
+
+@Vinit("helgrind", "info", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, True)
+class Helgrind_Info_Command(Valgrind_Prefix_Command):
+ """Get various information about helgrind tool status.
+Usage: helgrind info WHAT
+WHAT is the helgrind info subcommand, specifying the type of information requested.
+"""
+
+@Vinit("helgrind", "info locks", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Helgrind_Info_Locks_Command(Valgrind_ADDR_opt):
+ """Show the status of one or all locks recorded by helgrind.
+Usage: helgrind info locks [ADDR]
+ADDR is an address expression evaluated by GDB.
+When ADDR is provided, shows the status of the lock located at ADDR,
+otherwise shows the status of all locks.
+"""
+
+@Vinit("helgrind", "accesshistory", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Helgrind_Accesshistory_Command(Valgrind_ADDR_LEN_opt):
+ """Show access history recorded for LEN (default 1) bytes at ADDR.
+Usage: helgrind accesshistory ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) helgrind accesshistory &p sizeof(p)
+"""
+
+@Vinit("helgrind", "xtmemory", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Helgrind_Xtmemory_Command(Valgrind_Command):
+ """Dump xtree memory profile in FILENAME (default xtmemory.kcg.%p.%n).
+Usage: helgrind xtmemory [FILENAME]
+
+Example: (gdb) helgrind xtmemory my_program_xtree.kcg
+"""
+
+############# callgrind commands.
+
+###### Top of the hierarchy of the callgrind commands.
+@Vinit("callgrind", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Callgrind_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind callgrind gdbserver monitor commands.
+Usage: callgrind CALLGRIND_MONITOR_COMMAND [ARG...]
+CALLGRIND_MONITOR_COMMAND is a callgrind subcommand, matching
+a gdbserver Valgrind callgrind monitor command.
+ARG... are optional arguments. They depend on the CALLGRIND_MONITOR_COMMAND.
+"""
+
+def_alias("cg", "callgrind")
+
+@Vinit("callgrind", "dump", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, False)
+class Callgrind_Dump_Command(Valgrind_Command):
+ """Dump the callgrind counters.
+Usage: callgrind dump [DUMP_HINT]
+DUMP_HINT is a message stored in the resulting callgrind dump file.
+"""
+
+@Vinit("callgrind", "zero", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, False)
+class Callgrind_Zero_Command(Valgrind_Command):
+ """Set the callgrind counters to zero.
+Usage: callgrind zero
+"""
+
+@Vinit("callgrind", "status", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Callgrind_Status_Command(Valgrind_Command):
+ """Show the status of callgrind.
+Usage: callgrind status
+"""
+
+@Vinit("callgrind", "instrumentation", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, False)
+class Callgrind_Instrumentation_Command(Valgrind_Command):
+ """Get or set the callgrind instrumentation state.
+Usage: callgrind instrumentation [on|off]
+Without argument, shows the current state of instrumentation,
+otherwise changes the instrumentation state to the given argument.
+"""
+
+############# massif commands.
+
+###### Top of the hierarchy of the massif commands.
+@Vinit("massif", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Massif_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind massif gdbserver monitor commands.
+Usage: massif MASSIF_MONITOR_COMMAND [ARG...]
+MASSIF_MONITOR_COMMAND is a massif subcommand, matching
+a gdbserver Valgrind massif monitor command.
+ARG... are optional arguments. They depend on the MASSIF_MONITOR_COMMAND.
+"""
+
+def_alias("ms", "massif")
+
+@Vinit("massif", "snapshot", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massif_Dump_Command(Valgrind_Command):
+ """Take a massif snapshot in FILENAME (default massif.vgdb.out).
+Usage: massif snapshot [FILENAME]
+"""
+
+@Vinit("massif", "detailed_snapshot", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massif_Dump_Command(Valgrind_Command):
+ """Take a massif detailed snapshot in FILENAME (default massif.vgdb.out).
+Usage: massif detailed_snapshot [FILENAME]
+"""
+
+@Vinit("massif", "all_snapshots", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massif_Dump_Command(Valgrind_Command):
+ """Save all snapshot(s) taken so far in FILENAME (default massif.vgdb.out).
+Usage: massif all_snapshots [FILENAME]
+"""
+
+@Vinit("massif", "xtmemory", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massic_Xtmemory_Command(Valgrind_Command):
+ """Dump xtree memory profile in FILENAME (default xtmemory.kcg.%p.%n).
+Usage: massif xtmemory [FILENAME]
+
+Example: (gdb) massif xtmemory my_program_xtree.kcg
+"""
diff --git a/coregrind/m_gdbserver/valgrind-monitor.py b/coregrind/m_gdbserver/valgrind-monitor.py
new file mode 100644
index 000000000..a1feaab53
--- /dev/null
+++ b/coregrind/m_gdbserver/valgrind-monitor.py
@@ -0,0 +1,32 @@
+# This file is part of Valgrind, a dynamic binary instrumentation
+# framework.
+
+# Copyright (C) 2022-2022 Philippe Waroquiers
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# The GNU General Public License is contained in the file COPYING.
+
+"""
+Loads valgrind-monitor-def.py if not yet loaded.
+The purpose of this file is to avoid re-defining the python commands
+by reloading valgrind-monitor-def.py, as such redefinition causes a
+segmentation violation in GDB <= 13.
+"""
+
+import os
+
+if gdb.convenience_variable("_valgrind-monitor-def-loaded") == None:
+ gdb.set_convenience_variable ("_valgrind-monitor-def-loaded", 1)
+ gdb.execute("source " + os.path.dirname(__file__) + "/valgrind-monitor-def.py")
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 2b4a8748f..362648ab8 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -68,6 +68,18 @@
#include "pub_core_clreq.h"
#endif
+/* Instruct GDB via a .debug_gdb_scripts section to load the valgrind and tool
+ front-end commands. */
+/* Note: The "MS" section flags are to remove duplicates. */
+#define DEFINE_GDB_PY_SCRIPT(script_name) \
+ asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte 1 /* Python */\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_PY_SCRIPT(VG_LIBDIR "/valgrind-monitor.py")
/*====================================================================*/
/*=== Command-line: variables, processing, etc ===*/
diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c
index 3809811ae..75a3b7ed0 100644
--- a/coregrind/vg_preloaded.c
+++ b/coregrind/vg_preloaded.c
@@ -49,6 +49,19 @@
#include <features.h>
#endif
+/* Instruct GDB via a .debug_gdb_scripts section to load the valgrind and tool
+ front-end commands. */
+/* Note: The "MS" section flags are to remove duplicates. */
+#define DEFINE_GDB_PY_SCRIPT(script_name) \
+ asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte 1 /* Python */\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_PY_SCRIPT(VG_LIBDIR "/valgrind-monitor.py")
+
#if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
/* ---------------------------------------------------------------------
--
2.30.2
|
|
From: Paul F. <pa...@so...> - 2022-12-26 10:09:13
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=9acdd79b6947b3ddd3cdfa3f3d5afc7b8c8bee33 commit 9acdd79b6947b3ddd3cdfa3f3d5afc7b8c8bee33 Author: Paul Floyd <pj...@wa...> Date: Mon Dec 26 11:06:32 2022 +0100 Disable some memcheck tests on FreeBSD Fail due to differences in DWARF varinfo generated by clang compared to GCC. No fix in perspective. Diff: --- memcheck/tests/origin5-bz2.vgtest | 1 + memcheck/tests/varinfo2.vgtest | 1 + memcheck/tests/varinfo6.vgtest | 1 + 3 files changed, 3 insertions(+) diff --git a/memcheck/tests/origin5-bz2.vgtest b/memcheck/tests/origin5-bz2.vgtest index 5f9f573125..40fe6bb5a5 100644 --- a/memcheck/tests/origin5-bz2.vgtest +++ b/memcheck/tests/origin5-bz2.vgtest @@ -1,3 +1,4 @@ +prereq: ! ../../tests/os_test freebsd prog: origin5-bz2 vgopts: -q --track-origins=yes args: x diff --git a/memcheck/tests/varinfo2.vgtest b/memcheck/tests/varinfo2.vgtest index 0f73065462..6a86e6e531 100644 --- a/memcheck/tests/varinfo2.vgtest +++ b/memcheck/tests/varinfo2.vgtest @@ -1,3 +1,4 @@ +prereq: ! ../../tests/os_test freebsd prog: varinfo2 vgopts: --read-var-info=yes -q stderr_filter: filter_varinfo3 diff --git a/memcheck/tests/varinfo6.vgtest b/memcheck/tests/varinfo6.vgtest index 8855247a47..41984b19ba 100644 --- a/memcheck/tests/varinfo6.vgtest +++ b/memcheck/tests/varinfo6.vgtest @@ -1,2 +1,3 @@ +prereq: ! ../../tests/os_test freebsd prog: varinfo6 vgopts: --read-var-info=yes -q |
|
From: Paul F. <pa...@so...> - 2022-12-26 08:07:29
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=4dcfc05c20b508d8418309af61c403a6381e8a08 commit 4dcfc05c20b508d8418309af61c403a6381e8a08 Author: Paul Floyd <pj...@wa...> Date: Mon Dec 26 09:04:17 2022 +0100 Fixes related to Bug 392331 1. Added C++17 check to configure.ac 2. Needed Linux version of suppression 3. Added a filter for pthread_cond_signal Diff: --- configure.ac | 20 ++++++++++++++++++++ helgrind/tests/Makefile.am | 4 +++- helgrind/tests/bug392331.supp | 20 +++++++++++++++++++- helgrind/tests/bug392331.vgtest | 1 + helgrind/tests/bug392331_supp.vgtest | 1 + helgrind/tests/filter_stderr.in | 3 +++ helgrind/tests/tc20_verifywrap.stderr.exp | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-mips32 | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-s390x | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-solaris | 2 +- 13 files changed, 54 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 5ae9377119..467c98e023 100755 --- a/configure.ac +++ b/configure.ac @@ -2009,6 +2009,26 @@ AC_MSG_RESULT([no]) # clang 3.3 cannot process <thread> from e.g. # gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 +AC_MSG_CHECKING([that C++ compiler can compile C++17 code]) +AC_LANG(C++) +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS=-std=c++17 + +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +int x; +])], +[ +ac_have_cxx_17=yes +AC_MSG_RESULT([yes]) +], [ +ac_have_cxx_17=no +AC_MSG_RESULT([no]) +]) +CXXFLAGS=$safe_CXXFLAGS +AC_LANG(C) + +AM_CONDITIONAL(HAVE_CXX17, test x$ac_have_cxx_17 = xyes) + AC_MSG_CHECKING([that C++ compiler can include <thread> header file]) AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 926a367c7e..2286e220f1 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -142,7 +142,6 @@ noinst_HEADERS = safe-pthread.h safe-semaphore.h # should be conditionally compiled like tc20_verifywrap is. check_PROGRAMS = \ annotate_hbefore \ - bug392331 \ cond_init_destroy \ cond_timedwait_invalid \ cond_timedwait_test \ @@ -242,6 +241,9 @@ annotate_hbefore_CFLAGS = $(AM_CFLAGS) endif bug322621_SOURCES = bug322621.cpp +if HAVE_CXX17 +check_PROGRAMS += bug392331 bug392331_SOURCES = bug392331.cpp bug392331_CXXFLAGS = $(AM_CXXFLAGS) -std=c++17 +endif diff --git a/helgrind/tests/bug392331.supp b/helgrind/tests/bug392331.supp index 8262d142e1..6b8c5e1174 100644 --- a/helgrind/tests/bug392331.supp +++ b/helgrind/tests/bug392331.supp @@ -1,7 +1,25 @@ { - Check that Dubious suppression works + Check that Dubious suppression works FreeBSD Helgrind:Dubious fun:pthread_cond_signal_WRK fun:pthread_cond_signal fun:_ZNSt3__118condition_variable10notify_oneEv } +{ + Check that Dubious suppression works Linux standalone + Helgrind:Dubious + fun:pthread_cond_signal_WRK + fun:pthread_cond_signal@* + fun:__gthread_cond_signal + fun:UnknownInlinedFun + fun:_ZNSt18condition_variable10notify_oneEv +} +# for some very strange reason the suppression is different +# when running under regtest +{ + Check that Dubious suppression works Linux regtest + Helgrind:Dubious + fun:pthread_cond_signal_WRK + fun:pthread_cond_signal@* + fun:_ZNSt18condition_variable10notify_oneEv +} diff --git a/helgrind/tests/bug392331.vgtest b/helgrind/tests/bug392331.vgtest index 6c4aff6bf1..c160dcd40e 100644 --- a/helgrind/tests/bug392331.vgtest +++ b/helgrind/tests/bug392331.vgtest @@ -1,2 +1,3 @@ +prereq: test -e bug392331 vgopts: -q prog: bug392331 diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest index 611b4ca814..64fc729607 100644 --- a/helgrind/tests/bug392331_supp.vgtest +++ b/helgrind/tests/bug392331_supp.vgtest @@ -1,2 +1,3 @@ +prereq: test -e bug392331 vgopts: -q --suppressions=bug392331.supp prog: bug392331 diff --git a/helgrind/tests/filter_stderr.in b/helgrind/tests/filter_stderr.in index 9953b6527f..e7fecf5916 100755 --- a/helgrind/tests/filter_stderr.in +++ b/helgrind/tests/filter_stderr.in @@ -60,6 +60,9 @@ $SED \ # Some arches return ENOSYS instead of EINVAL for undefined futex operations. $SED -e "s/with error code 38 (ENOSYS: Function not implemented)/with error code 22 (EINVAL: Invalid argument)/" | +# filter differences in pthread_cond_signal +$SED -e "s/pthread_cond_signal@\*/pthread_cond_signal/" | + $dir/../../helgrind/tests/filter_helgrind "$@" exit 0 diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp b/helgrind/tests/tc20_verifywrap.stderr.exp index 372daeab76..e5e128d837 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp +++ b/helgrind/tests/tc20_verifywrap.stderr.exp @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 index b823d4000c..8b691ab838 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 @@ -116,7 +116,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 index 2a2ee9b5d2..cef930f2ad 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 index be73900790..7aecc1df2d 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b index d3f17d1506..d5bb6f83d8 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x index f19215efb5..7737447ba4 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x @@ -126,7 +126,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris index 891b504908..64edaaca2f 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris @@ -116,7 +116,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) |
|
From: Paul F. <pa...@so...> - 2022-12-25 21:33:09
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=67bb7eeec920ffcc2edef5fdf48db04e653f10b9 commit 67bb7eeec920ffcc2edef5fdf48db04e653f10b9 Author: Paul Floyd <pj...@wa...> Date: Sun Dec 25 22:31:55 2022 +0100 Fix suppression file inconsistency from previous commit for Bug 392331 Diff: --- helgrind/tests/{bug392331.suppr => bug392331.supp} | 0 helgrind/tests/bug392331_supp.vgtest | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/helgrind/tests/bug392331.suppr b/helgrind/tests/bug392331.supp similarity index 100% rename from helgrind/tests/bug392331.suppr rename to helgrind/tests/bug392331.supp diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest index 8e0fc7a38c..611b4ca814 100644 --- a/helgrind/tests/bug392331_supp.vgtest +++ b/helgrind/tests/bug392331_supp.vgtest @@ -1,2 +1,2 @@ -vgopts: -q --suppressions=bug392331.suppr +vgopts: -q --suppressions=bug392331.supp prog: bug392331 |
|
From: Paul F. <pa...@so...> - 2022-12-25 20:51:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=7d0389956e5e6ff182fdf4c2a3a9f8a202a927d4 commit 7d0389956e5e6ff182fdf4c2a3a9f8a202a927d4 Author: Paul Floyd <pj...@wa...> Date: Sun Dec 25 21:43:36 2022 +0100 Bug 392331 - Spurious lock not held error from inside pthread_cond_timedwait Added a "Dubious" error category to cover this kind of error. Diff: --- .gitignore | 1 + NEWS | 1 + helgrind/hg_errors.c | 74 +++++++++++++++++++++++++++++++- helgrind/hg_errors.h | 5 +++ helgrind/hg_main.c | 2 +- helgrind/tests/Makefile.am | 7 +++ helgrind/tests/bug392331.cpp | 58 +++++++++++++++++++++++++ helgrind/tests/bug392331.stderr.exp | 31 +++++++++++++ helgrind/tests/bug392331.stdout.exp | 4 ++ helgrind/tests/bug392331.suppr | 7 +++ helgrind/tests/bug392331.vgtest | 2 + helgrind/tests/bug392331_supp.stderr.exp | 0 helgrind/tests/bug392331_supp.stdout.exp | 4 ++ helgrind/tests/bug392331_supp.vgtest | 2 + 14 files changed, 195 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index a72b1dcae0..20282b8a20 100644 --- a/.gitignore +++ b/.gitignore @@ -653,6 +653,7 @@ /helgrind/tests/bar_bad /helgrind/tests/bar_trivial /helgrind/tests/bug322621 +/helgrind/tests/bug392331 /helgrind/tests/cond_init_destroy /helgrind/tests/cond_timedwait_invalid /helgrind/tests/cond_timedwait_test diff --git a/NEWS b/NEWS index e1befb56f5..b538ad5241 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 170510 Don't warn about ioctl of size 0 without direction hint 351857 confusing error message about valid command line option +392331 Spurious lock not held error from inside pthread_cond_timedwait 444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition. 444488 Use glibc.pthread.stack_cache_size tunable 444568 drd/tests/pth_barrier_thr_cr fails on Fedora 38 diff --git a/helgrind/hg_errors.c b/helgrind/hg_errors.c index e612449b54..638739dc6e 100644 --- a/helgrind/hg_errors.c +++ b/helgrind/hg_errors.c @@ -293,7 +293,9 @@ typedef XE_UnlockBogus, // unlocking an address not known to be a lock XE_PthAPIerror, // error from the POSIX pthreads API XE_LockOrder, // lock order error - XE_Misc // misc other error (w/ string to describe it) + XE_Misc, // misc other error (w/ string to describe it) + XE_Dubious // a bit like misc for cases where the POSIX + // spec is unclear on error conditons } XErrorTag; @@ -381,7 +383,8 @@ typedef XS_UnlockBogus, XS_PthAPIerror, XS_LockOrder, - XS_Misc + XS_Misc, + XS_Dubious } XSuppTag; @@ -654,6 +657,30 @@ void HG_(record_error_Misc) ( Thread* thr, const HChar* errstr ) HG_(record_error_Misc_w_aux)(thr, errstr, NULL, NULL); } +void HG_(record_error_Dubious_w_aux) ( Thread* thr, const HChar* errstr, + const HChar* auxstr, ExeContext* auxctx ) +{ + XError xe; + tl_assert( HG_(is_sane_Thread)(thr) ); + tl_assert(errstr); + init_XError(&xe); + xe.tag = XE_Dubious; + xe.XE.Misc.thr = thr; + xe.XE.Misc.errstr = string_table_strdup(errstr); + xe.XE.Misc.auxstr = auxstr ? string_table_strdup(auxstr) : NULL; + xe.XE.Misc.auxctx = auxctx; + // FIXME: tid vs thr + tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); + tl_assert( thr->coretid != VG_INVALID_THREADID ); + VG_(maybe_record_error)( thr->coretid, + XE_Dubious, 0, NULL, &xe ); +} + +void HG_(record_error_Dubious) ( Thread* thr, const HChar* errstr ) +{ + HG_(record_error_Dubious_w_aux)(thr, errstr, NULL, NULL); +} + Bool HG_(eq_Error) ( VgRes not_used, const Error* e1, const Error* e2 ) { XError *xe1, *xe2; @@ -692,6 +719,9 @@ Bool HG_(eq_Error) ( VgRes not_used, const Error* e1, const Error* e2 ) case XE_Misc: return xe1->XE.Misc.thr == xe2->XE.Misc.thr && 0==VG_(strcmp)(xe1->XE.Misc.errstr, xe2->XE.Misc.errstr); + case XE_Dubious: + return xe1->XE.Misc.thr == xe2->XE.Misc.thr + && 0==VG_(strcmp)(xe1->XE.Misc.errstr, xe2->XE.Misc.errstr); default: tl_assert(0); } @@ -872,6 +902,9 @@ void HG_(before_pp_Error) ( const Error* err ) tl_assert(xe); switch (VG_(get_error_kind)(err)) { + case XE_Dubious: + announce_one_thread( xe->XE.Misc.thr ); + break; case XE_Misc: announce_one_thread( xe->XE.Misc.thr ); break; @@ -931,6 +964,40 @@ void HG_(pp_Error) ( const Error* err ) emit( " <kind>%s</kind>\n", HG_(get_error_name)(err)); switch (VG_(get_error_kind)(err)) { + case XE_Dubious: { + tl_assert( HG_(is_sane_Thread)( xe->XE.Misc.thr ) ); + + if (xml) { + + emit( " <xwhat>\n" ); + emit( " <text>Thread #%d: %s</text>\n", + (Int)xe->XE.Misc.thr->errmsg_index, + xe->XE.Misc.errstr ); + emit( " <hthreadid>%d</hthreadid>\n", + (Int)xe->XE.Misc.thr->errmsg_index ); + emit( " </xwhat>\n" ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + if (xe->XE.Misc.auxstr) { + emit(" <auxwhat>%s</auxwhat>\n", xe->XE.Misc.auxstr); + if (xe->XE.Misc.auxctx) + VG_(pp_ExeContext)( xe->XE.Misc.auxctx ); + } + + } else { + + emit( "Thread #%d: %s\n", + (Int)xe->XE.Misc.thr->errmsg_index, + xe->XE.Misc.errstr ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + if (xe->XE.Misc.auxstr) { + emit(" %s\n", xe->XE.Misc.auxstr); + if (xe->XE.Misc.auxctx) + VG_(pp_ExeContext)( xe->XE.Misc.auxctx ); + } + + } + break; + } case XE_Misc: { tl_assert( HG_(is_sane_Thread)( xe->XE.Misc.thr ) ); @@ -1325,6 +1392,7 @@ const HChar* HG_(get_error_name) ( const Error* err ) case XE_PthAPIerror: return "PthAPIerror"; case XE_LockOrder: return "LockOrder"; case XE_Misc: return "Misc"; + case XE_Dubious: return "Dubious"; default: tl_assert(0); /* fill in missing case */ } } @@ -1344,6 +1412,7 @@ Bool HG_(recognised_suppression) ( const HChar* name, Supp *su ) TRY("PthAPIerror", XS_PthAPIerror); TRY("LockOrder", XS_LockOrder); TRY("Misc", XS_Misc); + TRY("Dubious", XS_Dubious); return False; # undef TRY } @@ -1366,6 +1435,7 @@ Bool HG_(error_matches_suppression) ( const Error* err, const Supp* su ) case XS_PthAPIerror: return VG_(get_error_kind)(err) == XE_PthAPIerror; case XS_LockOrder: return VG_(get_error_kind)(err) == XE_LockOrder; case XS_Misc: return VG_(get_error_kind)(err) == XE_Misc; + case XS_Dubious: return VG_(get_error_kind)(err) == XE_Dubious; //case XS_: return VG_(get_error_kind)(err) == XE_; default: tl_assert(0); /* fill in missing cases */ } diff --git a/helgrind/hg_errors.h b/helgrind/hg_errors.h index 08191e1b3d..5824151c9a 100644 --- a/helgrind/hg_errors.h +++ b/helgrind/hg_errors.h @@ -78,6 +78,11 @@ void HG_(record_error_Misc_w_aux) ( Thread*, const HChar* errstr, ExeContext* auxctx ); void HG_(record_error_Misc) ( Thread* thr, const HChar* errstr ); +void HG_(record_error_Dubious_w_aux) ( Thread*, const HChar* errstr, + const HChar* auxstr, + ExeContext* auxctx ); +void HG_(record_error_Dubious) ( Thread* thr, const HChar* errstr ); + /* Statistics pertaining to error management. */ extern ULong HG_(stats__LockN_to_P_queries); diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 490fc38fef..813c983a4c 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -2448,7 +2448,7 @@ static void evh__HG_PTHREAD_COND_SIGNAL_PRE ( ThreadId tid, void* cond ) "pthread_cond_{signal,broadcast}: associated lock is a rwlock"); } if (lk->heldBy == NULL) { - HG_(record_error_Misc)(thr, + HG_(record_error_Dubious)(thr, "pthread_cond_{signal,broadcast}: dubious: " "associated lock is not held by any thread"); } diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 05e145f7b8..926a367c7e 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -16,6 +16,9 @@ EXTRA_DIST = \ annotate_smart_pointer.vgtest annotate_smart_pointer.stdout.exp \ annotate_smart_pointer.stderr.exp \ bug322621.vgtest bug322621.stderr.exp \ + bug392331.vgtest bug392331.stdout.exp bug392331.stderr.exp \ + bug392331_supp.vgtest bug392331_supp.stdout.exp bug392331_supp.stderr.exp \ + bug392331.supp \ cond_init_destroy.vgtest cond_init_destroy.stderr.exp \ cond_timedwait_invalid.vgtest cond_timedwait_invalid.stdout.exp \ cond_timedwait_invalid.stderr.exp \ @@ -139,6 +142,7 @@ noinst_HEADERS = safe-pthread.h safe-semaphore.h # should be conditionally compiled like tc20_verifywrap is. check_PROGRAMS = \ annotate_hbefore \ + bug392331 \ cond_init_destroy \ cond_timedwait_invalid \ cond_timedwait_test \ @@ -238,3 +242,6 @@ annotate_hbefore_CFLAGS = $(AM_CFLAGS) endif bug322621_SOURCES = bug322621.cpp +bug392331_SOURCES = bug392331.cpp +bug392331_CXXFLAGS = $(AM_CXXFLAGS) -std=c++17 + diff --git a/helgrind/tests/bug392331.cpp b/helgrind/tests/bug392331.cpp new file mode 100644 index 0000000000..ff26883b76 --- /dev/null +++ b/helgrind/tests/bug392331.cpp @@ -0,0 +1,58 @@ +// For this Bugzilla item https://bugs.kde.org/show_bug.cgi?id=392331 +// Example from https://en.cppreference.com/w/cpp/thread/condition_variable + +#include <iostream> +#include <string> +#include <thread> +#include <mutex> +#include <condition_variable> + +std::mutex m; +std::condition_variable cv; +std::string data; +bool ready = false; +bool processed = false; + +void worker_thread() +{ + // Wait until main() sends data + std::unique_lock lk(m); + cv.wait(lk, []{return ready;}); + + // after the wait, we own the lock. + std::cout << "Worker thread is processing data\n"; + data += " after processing"; + + // Send data back to main() + processed = true; + std::cout << "Worker thread signals data processing completed\n"; + + // Manual unlocking is done before notifying, to avoid waking up + // the waiting thread only to block again (see notify_one for details) + lk.unlock(); + cv.notify_one(); +} + +int main() +{ + std::thread worker(worker_thread); + + data = "Example data"; + // send data to the worker thread + { + std::lock_guard lk(m); + ready = true; + std::cout << "main() signals data ready for processing\n"; + } + cv.notify_one(); + + // wait for the worker + { + std::unique_lock lk(m); + cv.wait(lk, []{return processed;}); + } + std::cout << "Back in main(), data = " << data << '\n'; + + worker.join(); +} + diff --git a/helgrind/tests/bug392331.stderr.exp b/helgrind/tests/bug392331.stderr.exp new file mode 100644 index 0000000000..f278e3b089 --- /dev/null +++ b/helgrind/tests/bug392331.stderr.exp @@ -0,0 +1,31 @@ +---Thread-Announcement------------------------------------------ + +Thread #x is the program's root thread + +---------------------------------------------------------------- + +Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) + ... + by 0x........: main (bug392331.cpp:47) + +---Thread-Announcement------------------------------------------ + +Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) + ... + by 0x........: main (bug392331.cpp:38) + +---------------------------------------------------------------- + +Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) + ... + by 0x........: worker_thread() (bug392331.cpp:33) + ... + by 0x........: mythread_wrapper (hg_intercepts.c:...) + ... + diff --git a/helgrind/tests/bug392331.stdout.exp b/helgrind/tests/bug392331.stdout.exp new file mode 100644 index 0000000000..4d6f703ee5 --- /dev/null +++ b/helgrind/tests/bug392331.stdout.exp @@ -0,0 +1,4 @@ +main() signals data ready for processing +Worker thread is processing data +Worker thread signals data processing completed +Back in main(), data = Example data after processing diff --git a/helgrind/tests/bug392331.suppr b/helgrind/tests/bug392331.suppr new file mode 100644 index 0000000000..8262d142e1 --- /dev/null +++ b/helgrind/tests/bug392331.suppr @@ -0,0 +1,7 @@ +{ + Check that Dubious suppression works + Helgrind:Dubious + fun:pthread_cond_signal_WRK + fun:pthread_cond_signal + fun:_ZNSt3__118condition_variable10notify_oneEv +} diff --git a/helgrind/tests/bug392331.vgtest b/helgrind/tests/bug392331.vgtest new file mode 100644 index 0000000000..6c4aff6bf1 --- /dev/null +++ b/helgrind/tests/bug392331.vgtest @@ -0,0 +1,2 @@ +vgopts: -q +prog: bug392331 diff --git a/helgrind/tests/bug392331_supp.stderr.exp b/helgrind/tests/bug392331_supp.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helgrind/tests/bug392331_supp.stdout.exp b/helgrind/tests/bug392331_supp.stdout.exp new file mode 100644 index 0000000000..4d6f703ee5 --- /dev/null +++ b/helgrind/tests/bug392331_supp.stdout.exp @@ -0,0 +1,4 @@ +main() signals data ready for processing +Worker thread is processing data +Worker thread signals data processing completed +Back in main(), data = Example data after processing diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest new file mode 100644 index 0000000000..8e0fc7a38c --- /dev/null +++ b/helgrind/tests/bug392331_supp.vgtest @@ -0,0 +1,2 @@ +vgopts: -q --suppressions=bug392331.suppr +prog: bug392331 |
|
From: Paul F. <pa...@so...> - 2022-12-25 17:38:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=227fa1d53bccaa236af3a72764d5efe763bcf036 commit 227fa1d53bccaa236af3a72764d5efe763bcf036 Author: Paul Floyd <pj...@wa...> Date: Sun Dec 25 18:36:20 2022 +0100 Cleanup for clangd, mostly FreeBSD Consistently use braces. Make some bitwise expressions use unsigned. Use some named variables for magic numbers. Diff: --- coregrind/m_debuginfo/readpdb.c | 3 +- coregrind/m_initimg/initimg-freebsd.c | 132 +++++--- coregrind/m_sigframe/sigframe-amd64-freebsd.c | 22 +- coregrind/m_syswrap/priv_types_n_macros.h | 12 +- coregrind/m_syswrap/syswrap-amd64-freebsd.c | 10 +- coregrind/m_syswrap/syswrap-freebsd.c | 459 ++++++++++++++------------ include/vki/vki-amd64-freebsd.h | 2 +- include/vki/vki-freebsd.h | 16 +- 8 files changed, 380 insertions(+), 276 deletions(-) diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c index f3a3817d89..7c5467d379 100644 --- a/coregrind/m_debuginfo/readpdb.c +++ b/coregrind/m_debuginfo/readpdb.c @@ -1545,8 +1545,9 @@ static ULong DEBUG_SnarfLinetab( Bool debug = di->trace_symtab; ULong n_lines_read = 0; - if (debug) + if (debug) { VG_(umsg)("BEGIN SnarfLineTab linetab=%p size=%d\n", linetab, size); + } /* * Now get the important bits. diff --git a/coregrind/m_initimg/initimg-freebsd.c b/coregrind/m_initimg/initimg-freebsd.c index ece565e66d..f0e2bcfd07 100644 --- a/coregrind/m_initimg/initimg-freebsd.c +++ b/coregrind/m_initimg/initimg-freebsd.c @@ -86,8 +86,9 @@ static void load_client ( /*OUT*/ExeInfo* info, /* Get hold of a file descriptor which refers to the client executable. This is needed for attaching to GDB. */ res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); - if (!sr_isError(res)) + if (!sr_isError(res)) { VG_(cl_exec_fd) = sr_Res(res); + } /* Copy necessary bits of 'info' that were filled in */ *client_ip = info->init_ip; @@ -137,7 +138,8 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) HChar** cpp; HChar** ret; HChar* preload_tool_path; - Int envc, i; + Int envc; + Int i; /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so paths. We might not need the space for vgpreload_<tool>.so, but it @@ -168,11 +170,15 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string); /* Count the original size of the env */ - if (debug) VG_(printf)("\n\n"); + if (debug) { + VG_(printf)("\n\n"); + } envc = 0; for (cpp = origenv; cpp && *cpp; cpp++) { envc++; - if (debug) VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp); + if (debug) { + VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp); + } } /* Allocate a new space */ @@ -181,7 +187,9 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) /* copy it over */ for (cpp = ret; *origenv; ) { - if (debug) VG_(printf)("XXXXXXXXX: COPY %s\n", *origenv); + if (debug) { + VG_(printf)("XXXXXXXXX: COPY %s\n", *origenv); + } *cpp++ = *origenv++; } *cpp = NULL; @@ -202,7 +210,9 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) ld_preload_done = True; } - if (debug) VG_(printf)("XXXXXXXXX: MASH %s\n", *cpp); + if (debug) { + VG_(printf)("XXXXXXXXX: MASH %s\n", *cpp); + } } /* Add the missing bits */ @@ -213,7 +223,9 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string); ret[envc++] = cp; - if (debug) VG_(printf)("XXXXXXXXX: ADD %s\n", cp); + if (debug) { + VG_(printf)("XXXXXXXXX: ADD %s\n", cp); + } } #if defined(VGP_x86_freebsd) @@ -249,13 +261,16 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) /* ret[0 .. envc-1] is live now. */ /* Find and remove a binding for VALGRIND_LAUNCHER. */ - for (i = 0; i < envc; i++) - if (0 == VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) + for (i = 0; i < envc; i++) { + if (0 == VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) { break; + } + } if (i < envc) { - for (; i < envc-1; i++) + for (; i < envc-1; i++) { ret[i] = ret[i+1]; + } envc--; } @@ -263,7 +278,9 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) ret[envc] = NULL; for (i = 0; i < envc; i++) { - if (debug) VG_(printf)("XXXXXXXXX: FINAL %s\n", ret[i]); + if (debug) { + VG_(printf)("XXXXXXXXX: FINAL %s\n", ret[i]); + } } return ret; @@ -280,12 +297,14 @@ static HChar *copy_str(HChar **tab, const HChar *str) HChar *cp = *tab; HChar *orig = cp; - while(*str) + while(*str) { *cp++ = *str++; + } *cp++ = '\0'; - if (0) + if (0) { VG_(printf)("copied %p \"%s\" len %lld\n", (void*)orig, orig, (Long)(cp-orig)); + } *tab = cp; @@ -348,12 +367,14 @@ struct auxv *find_auxv(UWord* sp) { sp++; // skip argc (Nb: is word-sized, not int-sized!) - while (*sp != 0) // skip argv + while (*sp != 0) { // skip argv sp++; + } sp++; - while (*sp != 0) // skip env + while (*sp != 0) { // skip env sp++; + } sp++; return (struct auxv *)sp; @@ -411,8 +432,9 @@ Addr setup_client_stack( void* init_sp, } /* now scan the args we're given... */ - if (have_exename) + if (have_exename) { stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; + } for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { argc++; @@ -480,7 +502,9 @@ Addr setup_client_stack( void* init_sp, auxsize + /* auxv */ VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ - if (0) VG_(printf)("stacksize = %u\n", stacksize); + if (0) { + VG_(printf)("stacksize = %u\n", stacksize); + } /* client_SP is the client's stack pointer */ client_SP = clstack_end - stacksize; @@ -495,12 +519,13 @@ Addr setup_client_stack( void* init_sp, /* The max stack size */ clstack_max_size = VG_PGROUNDUP(clstack_max_size); - if (0) + if (0) { VG_(printf)("stringsize=%u auxsize=%u stacksize=%u maxsize=0x%lx\n" "clstack_start %p\n" "clstack_end %p\n", stringsize, auxsize, stacksize, clstack_max_size, (void*)clstack_start, (void*)clstack_end); + } /* ==================== allocate space ==================== */ @@ -540,9 +565,10 @@ Addr setup_client_stack( void* init_sp, inner_HACK = 1024*1024; // create 1M non-fault-extending stack # endif - if (0) + if (0) { VG_(printf)("%#lx 0x%lx %#lx 0x%lx\n", resvn_start, resvn_size, anon_start, anon_size); + } /* Create a shrinkable reservation followed by an anonymous segment. Together these constitute a growdown stack. */ @@ -589,13 +615,16 @@ Addr setup_client_stack( void* init_sp, /* --- client argv --- */ client_argv = (Word)ptr; - if (info->interp_name) + if (info->interp_name) { *ptr++ = (Addr)copy_str(&strtab, info->interp_name); - if (info->interp_args) + } + if (info->interp_args) { *ptr++ = (Addr)copy_str(&strtab, info->interp_args); + } - if (have_exename) + if (have_exename) { *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); + } for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { *ptr++ = (Addr)copy_str( @@ -607,8 +636,9 @@ Addr setup_client_stack( void* init_sp, /* --- envp --- */ VG_(client_envp) = (HChar **)ptr; - for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) + for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) { *ptr = (Addr)copy_str(&strtab, *cpp); + } *ptr++ = 0; /* --- auxv --- */ @@ -658,16 +688,18 @@ Addr setup_client_stack( void* init_sp, auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr); break; case VKI_AT_CANARY: - if (canarylen >= 1) + if (canarylen >= 1) { auxv->u.a_ptr = copy_bytes(&strtab, orig_auxv->u.a_ptr, canarylen); - else + } else { auxv->a_type = VKI_AT_IGNORE; + } break; case VKI_AT_PAGESIZES: - if (pagesizeslen >= 1) + if (pagesizeslen >= 1) { auxv->u.a_ptr = copy_bytes(&strtab, orig_auxv->u.a_ptr, pagesizeslen); - else + } else { auxv->a_type = VKI_AT_IGNORE; + } break; #if 0 /* @@ -717,17 +749,19 @@ Addr setup_client_stack( void* init_sp, #endif case VKI_AT_PHDR: - if (info->phdr == 0) + if (info->phdr == 0) { auxv->a_type = VKI_AT_IGNORE; - else + } else { auxv->u.a_val = info->phdr; + } break; case VKI_AT_PHNUM: - if (info->phdr == 0) + if (info->phdr == 0) { auxv->a_type = VKI_AT_IGNORE; - else + } else { auxv->u.a_val = info->phnum; + } break; case VKI_AT_BASE: @@ -754,7 +788,9 @@ Addr setup_client_stack( void* init_sp, /* client_SP is pointing at client's argc/argv */ - if (0) VG_(printf)("startup SP = %#lx\n", client_SP); + if (0) { + VG_(printf)("startup SP = %#lx\n", client_SP); + } return client_SP; } @@ -803,8 +839,9 @@ static void setup_client_dataseg ( SizeT max_size ) SmLower, anon_size ); - if (ok) + if (ok) { VG_(brk_base) = VG_(brk_limit) = anon_start; + } } /* that too might have failed, but if it has, we're hosed: there is no Plan C. */ @@ -848,8 +885,9 @@ IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, //-------------------------------------------------------------- VG_(debugLog)(1, "initimg", "Loading client\n"); - if (VG_(args_the_exename) == NULL) + if (VG_(args_the_exename) == NULL) { VG_(err_missing_prog)(); + } VG_(memset)(&info, 0, sizeof(info)); @@ -883,10 +921,18 @@ IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, SizeT m1 = 1024 * 1024; SizeT m16 = 16 * m1; SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur; - if (szB < m1) szB = m1; - if (szB > m16) szB = m16; - if (VG_(clo_main_stacksize) > 0) szB = VG_(clo_main_stacksize); - if (szB < m1) szB = m1; + if (szB < m1) { + szB = m1; + } + if (szB > m16) { + szB = m16; + } + if (VG_(clo_main_stacksize) > 0) { + szB = VG_(clo_main_stacksize); + } + if (szB < m1) { + szB = m1; + } szB = VG_PGROUNDUP(szB); VG_(debugLog)(1, "initimg", "Setup client stack: size will be %lu\n", szB); @@ -923,8 +969,12 @@ IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, SizeT m8 = 8 * m1; SizeT dseg_max_size = (SizeT)VG_(client_rlimit_data).rlim_cur; VG_(debugLog)(1, "initimg", "Setup client data (brk) segment\n"); - if (dseg_max_size < m1) dseg_max_size = m1; - if (dseg_max_size > m8) dseg_max_size = m8; + if (dseg_max_size < m1) { + dseg_max_size = m1; + } + if (dseg_max_size > m8) { + dseg_max_size = m8; + } dseg_max_size = VG_PGROUNDUP(dseg_max_size); setup_client_dataseg( dseg_max_size ); @@ -988,7 +1038,7 @@ void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State)); /* Put essential stuff into the new state. */ - arch->vex.guest_RSP = ((iifii.initial_client_SP - 8) & ~0xFul) + 8; + arch->vex.guest_RSP = ((iifii.initial_client_SP - 8) & ~0xFUL) + 8; arch->vex.guest_RDI = iifii.initial_client_SP; arch->vex.guest_RIP = iifii.initial_client_IP; diff --git a/coregrind/m_sigframe/sigframe-amd64-freebsd.c b/coregrind/m_sigframe/sigframe-amd64-freebsd.c index 31e6e784ae..7ae0ec291d 100644 --- a/coregrind/m_sigframe/sigframe-amd64-freebsd.c +++ b/coregrind/m_sigframe/sigframe-amd64-freebsd.c @@ -49,6 +49,8 @@ on amd64-freebsd. */ +const UInt MAGIC_PI = 0x31415927U; +const UInt MAGIC_E = 0x27182818U; /*------------------------------------------------------------*/ /*--- Signal frame layouts ---*/ @@ -153,12 +155,12 @@ void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, XXX */ SC2(rip,RIP); - sc->addr = (UWord)si->si_addr; - sc->err = err; + sc->addr = (vki_register_t)si->si_addr; + sc->err = (vki_register_t)err; sc->fpformat = VKI_FPFMT_NODEV; sc->ownedfp = VKI_FPOWNED_NONE; sc->len = sizeof(*sc); - sc->rflags = LibVEX_GuestAMD64_get_rflags(&tst->arch.vex); + sc->rflags = (vki_register_t)LibVEX_GuestAMD64_get_rflags(&tst->arch.vex); sc->trapno = trapno; # undef SC2 } @@ -219,7 +221,7 @@ static void build_vg_sigframe(struct vg_sigframe *frame, Int sigNo) { frame->sigNo_private = sigNo; - frame->magicPI = 0x31415927; + frame->magicPI = MAGIC_PI; frame->vex_shadow1 = tst->arch.vex_shadow1; frame->vex_shadow2 = tst->arch.vex_shadow2; /* HACK ALERT */ @@ -227,7 +229,7 @@ static void build_vg_sigframe(struct vg_sigframe *frame, /* end HACK ALERT */ frame->mask = tst->sig_mask; frame->handlerflags = flags; - frame->magicE = 0x27182818; + frame->magicE = MAGIC_E; } static Addr build_sigframe(ThreadState *tst, @@ -268,8 +270,9 @@ static Addr build_sigframe(ThreadState *tst, VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); - if (sigNo == VKI_SIGILL && siginfo->si_code > 0) + if (sigNo == VKI_SIGILL && siginfo->si_code > 0) { frame->sigInfo.si_addr = (void*)tst->arch.vex.guest_RIP; + } synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uContext, &frame->fpstate); @@ -336,8 +339,8 @@ static Bool restore_vg_sigframe ( ThreadState *tst, struct vg_sigframe *frame, Int *sigNo ) { - if (frame->magicPI != 0x31415927 || - frame->magicE != 0x27182818) { + if (frame->magicPI != MAGIC_PI || + frame->magicE != MAGIC_E) { VG_(message)(Vg_UserMsg, "Thread %u return signal frame " "corrupted. Killing process.\n", tst->tid); @@ -419,11 +422,12 @@ void VG_(sigframe_destroy)( ThreadId tid ) VG_TRACK( die_mem_stack_signal, rsp - VG_STACK_REDZONE_SZB, size + VG_STACK_REDZONE_SZB ); - if (VG_(clo_trace_signals)) + if (VG_(clo_trace_signals)) { VG_(message)( Vg_DebugMsg, "VG_(signal_return) (thread %u): valid magic; RIP=%#llx\n", tid, tst->arch.vex.guest_RIP); + } /* tell the tools */ VG_TRACK( post_deliver_signal, tid, sigNo ); diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h index 461019ad7b..dd241839a6 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -180,12 +180,12 @@ typedef SyscallArgLayout; /* Flags describing syscall wrappers */ -#define SfMayBlock (1 << 1) /* may block */ -#define SfPostOnFail (1 << 2) /* call POST() function on failure */ -#define SfPollAfter (1 << 3) /* poll for signals on completion */ -#define SfYieldAfter (1 << 4) /* yield on completion */ -#define SfNoWriteResult (1 << 5) /* don't write result to guest state */ -#define SfKernelRestart (1 << 6) /* needs a manual restart */ +#define SfMayBlock (1U << 1U) /* may block */ +#define SfPostOnFail (1U << 2U) /* call POST() function on failure */ +#define SfPollAfter (1U << 3U) /* poll for signals on completion */ +#define SfYieldAfter (1U << 4U) /* yield on completion */ +#define SfNoWriteResult (1U << 5U) /* don't write result to guest state */ +#define SfKernelRestart (1U << 6U) /* needs a manual restart */ /* --------------------------------------------------------------------- diff --git a/coregrind/m_syswrap/syswrap-amd64-freebsd.c b/coregrind/m_syswrap/syswrap-amd64-freebsd.c index aa58140e2c..52eeb808cc 100644 --- a/coregrind/m_syswrap/syswrap-amd64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-amd64-freebsd.c @@ -761,10 +761,11 @@ PRE(sys_pread) unsigned int, fd, char *, buf, vki_size_t, count, unsigned long, off); - if (!ML_(fd_allowed)(ARG1, "read", tid, False)) + if (!ML_(fd_allowed)(ARG1, "read", tid, False)) { SET_STATUS_Failure( VKI_EBADF ); - else + } else { PRE_MEM_WRITE( "pread(buf)", ARG2, ARG3 ); + } } POST(sys_pread) @@ -789,10 +790,11 @@ PRE(sys_pwrite) if (!ok && ARG1 == 2/*stderr*/ && SimHintiS(SimHint_enable_outer, VG_(clo_sim_hints))) ok = True; - if (!ok) + if (!ok) { SET_STATUS_Failure( VKI_EBADF ); - else + } else { PRE_MEM_READ( "pwrite(buf)", ARG2, ARG3 ); + } } // SYS_mmap 477 diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 71443e399b..8bf4fcddee 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -90,9 +90,10 @@ static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW) /* make sure we get the CPU lock before doing anything significant */ VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)"); - if (0) + if (0) { VG_(printf)("thread tid %u started: stack = %p\n", tid, (void*)&tid); + } /* Make sure error reporting is enabled in the new thread. */ tst->err_disablement_level = 0; @@ -171,8 +172,9 @@ static void run_a_thread_NORETURN ( Word tidW ) vg_assert(c >= 1); /* stay sane */ /* Deregister thread's stack. */ - if (tst->os_state.stk_id != NULL_STK_ID) + if (tst->os_state.stk_id != NULL_STK_ID) { VG_(deregister_stack)(tst->os_state.stk_id); + } // Tell the tool this thread is exiting VG_TRACK( pre_thread_ll_exit, tid ); @@ -312,11 +314,12 @@ Addr ML_(allocstack)(ThreadId tid) } } - if (0) + if (0) { VG_(printf)( "stack for tid %u at %p; init_SP=%p\n", tid, (void*)tst->os_state.valgrind_stack_base, (void*)tst->os_state.valgrind_stack_init_SP ); + } return tst->os_state.valgrind_stack_init_SP; } @@ -394,9 +397,10 @@ SysRes ML_(do_fork) ( ThreadId tid ) /* parent */ VG_(do_atfork_parent)(tid); - if (VG_(clo_trace_syscalls)) + if (VG_(clo_trace_syscalls)) { VG_(printf)(" clone(fork): process %d created child %lu\n", VG_(getpid)(), sr_Res(res)); + } /* restore signal mask */ VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); @@ -454,8 +458,9 @@ PRE(sys_exit) /* Mark all threads (including this one) to exit. */ for (t = 1; t < VG_N_THREADS; t++) { - if ( /* not alive */ VG_(threads)[t].status == VgTs_Empty ) + if ( /* not alive */ VG_(threads)[t].status == VgTs_Empty ) { continue; + } //VG_(threads)[t].exitreason = VgSrc_ExitThread; VG_(threads)[t].os_state.exitcode = ARG1; @@ -573,11 +578,8 @@ PRE(sys_ptrace) switch (ARG1) { case VKI_PTRACE_TRACEME: - break; case VKI_PTRACE_READ_I: case VKI_PTRACE_READ_D: - break; - case VKI_PTRACE_WRITE_I: case VKI_PTRACE_WRITE_D: break; @@ -598,46 +600,38 @@ PRE(sys_ptrace) break; case VKI_PTRACE_CONTINUE: - break; - case VKI_PTRACE_STEP: - break; - case VKI_PTRACE_KILL: - break; - case VKI_PTRACE_ATTACH: - break; - case VKI_PTRACE_DETACH: break; case VKI_PTRACE_GETREGS: - PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_user_regs_struct)); + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); break; case VKI_PTRACE_SETREGS: - PRE_MEM_READ( "ptrace", ARG3, sizeof(struct vki_user_regs_struct)); + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); break; case VKI_PTRACE_GETFPREGS: - PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_fpreg)); + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_fpreg)); break; case VKI_PTRACE_SETFPREGS: - PRE_MEM_READ( "ptrace", ARG3, sizeof(struct vki_fpreg)); + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_fpreg)); break; case VKI_PTRACE_GETDBREGS: - PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_dbreg)); + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_dbreg)); break; case VKI_PTRACE_SETDBREGS: - PRE_MEM_READ( "ptrace", ARG3, sizeof(struct vki_dbreg)); + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_dbreg)); break; case VKI_PTRACE_LWPINFO: - PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_ptrace_lwpinfo)); + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_ptrace_lwpinfo)); break; case VKI_PTRACE_GETNUMLWPS: @@ -648,29 +642,14 @@ PRE(sys_ptrace) break; case VKI_PTRACE_SETSTEP: - break; - case VKI_PTRACE_CLEARSTEP: - break; - case VKI_PTRACE_SUSPEND: - break; - case VKI_PTRACE_RESUME: - break; - case VKI_PTRACE_TO_SCE: - break; - case VKI_PTRACE_TO_SCX: - break; - case VKI_PTRACE_SYSCALL: - break; - case VKI_PTRACE_VM_TIMESTAMP: break; - case VKI_PTRACE_VM_ENTRY: PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_ptrace_vm_entry)); break; @@ -683,11 +662,8 @@ POST(sys_ptrace) switch (ARG1) { case VKI_PTRACE_TRACEME: - break; case VKI_PTRACE_READ_I: case VKI_PTRACE_READ_D: - break; - case VKI_PTRACE_WRITE_I: case VKI_PTRACE_WRITE_D: break; @@ -697,8 +673,9 @@ POST(sys_ptrace) switch (io_desc->piod_op) { case VKI_PIOD_READ_D: case VKI_PIOD_READ_I: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE((UWord)io_desc->piod_addr, io_desc->piod_len); + } break; case VKI_PIOD_WRITE_D: case VKI_PIOD_WRITE_I: @@ -707,84 +684,68 @@ POST(sys_ptrace) break; case VKI_PTRACE_CONTINUE: - break; - case VKI_PTRACE_STEP: - break; - case VKI_PTRACE_KILL: - break; - case VKI_PTRACE_ATTACH: - break; - case VKI_PTRACE_DETACH: break; case VKI_PTRACE_GETREGS: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE(ARG3, sizeof(struct vki_user_regs_struct)); + } break; case VKI_PTRACE_SETREGS: break; case VKI_PTRACE_GETFPREGS: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE(ARG3, sizeof(struct vki_fpreg)); + } break; case VKI_PTRACE_SETFPREGS: break; case VKI_PTRACE_GETDBREGS: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE(ARG3, sizeof(struct vki_dbreg)); + } break; case VKI_PTRACE_SETDBREGS: break; case VKI_PTRACE_LWPINFO: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_lwpinfo)); + } break; case VKI_PTRACE_GETNUMLWPS: break; case VKI_PTRACE_GETLWPLIST: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE(ARG3, sizeof(vki_lwpid_t) * RES); + } break; case VKI_PTRACE_SETSTEP: - break; - case VKI_PTRACE_CLEARSTEP: - break; - case VKI_PTRACE_SUSPEND: - break; - case VKI_PTRACE_RESUME: - break; - case VKI_PTRACE_TO_SCE: - break; - case VKI_PTRACE_TO_SCX: - break; - case VKI_PTRACE_SYSCALL: - break; - case VKI_PTRACE_VM_TIMESTAMP: break; case VKI_PTRACE_VM_ENTRY: - if ((Word)RES != -1) + if ((Word)RES != -1) { POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_vm_entry)); + } break; } } @@ -1022,8 +983,9 @@ PRE(sys_ioctl) /* Check if have not already moaned for this request. */ UInt i; for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) { - if (unknown_ioctl[i] == ARG2) + if (unknown_ioctl[i] == ARG2) { break; + } if (unknown_ioctl[i] == 0) { unknown_ioctl[i] = ARG2; moans--; @@ -1037,10 +999,12 @@ PRE(sys_ioctl) } } } else { - if ((dir & _VKI_IOC_WRITE) && size > 0) + if ((dir & _VKI_IOC_WRITE) && size > 0) { PRE_MEM_READ( "ioctl(generic)", ARG3, size); - if ((dir & _VKI_IOC_READ) && size > 0) + } + if ((dir & _VKI_IOC_READ) && size > 0) { PRE_MEM_WRITE( "ioctl(generic)", ARG3, size); + } } // The block below is from Ryan Stone @@ -1111,8 +1075,9 @@ POST(sys_ioctl) UInt size = _VKI_IOC_SIZE(ARG2); vg_assert(SUCCESS); if (size > 0 && (dir & _VKI_IOC_READ) - && RES == 0 && ARG3 != (Addr)NULL) + && RES == 0 && ARG3 != (Addr)NULL) { POST_MEM_WRITE(ARG3, size); + } #if 0 /* Handle specific ioctls which pass structures which may have pointers to other @@ -1353,16 +1318,18 @@ POST(sys_fcntl) VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_named)(tid, RES); + } } } else if (ARG2 == VKI_F_DUPFD_CLOEXEC) { if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) { VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_named)(tid, RES); + } } } } @@ -1718,8 +1685,9 @@ PRE(sys_rtprio) POST(sys_rtprio) { - if (ARG1 == VKI_RTP_LOOKUP && RES == 0) + if (ARG1 == VKI_RTP_LOOKUP && RES == 0) { POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio)); + } } // freebsd6_pread 173 FREEBSD_VERS <= 10 @@ -1891,8 +1859,9 @@ PRE(sys_freebsd11_getdirentries) int, nbytes, long *, basep); PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); - if (ARG4) + if (ARG4) { PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); + } } POST(sys_freebsd11_getdirentries) @@ -1900,8 +1869,9 @@ POST(sys_freebsd11_getdirentries) vg_assert(SUCCESS); if (RES > 0) { POST_MEM_WRITE( ARG2, RES ); - if ( ARG4 != 0 ) + if ( ARG4 != 0 ) { POST_MEM_WRITE( ARG4, sizeof (long)); + } } } #else @@ -2059,8 +2029,9 @@ PRE(sys___sysctl) PRE_MEM_READ("sysctl(name)", (Addr)ARG1, ARG2 * sizeof(int)); // if 'newp' is not NULL can read namelen bytes from that address - if (ARG5 != (UWord)NULL) + if (ARG5 != (UWord)NULL) { PRE_MEM_READ("sysctl(newp)", (Addr)ARG5, ARG6); + } // there are two scenarios for oldlenp/oldp // 1. oldval is NULL and oldlenp is non-NULL @@ -2094,8 +2065,9 @@ POST(sys___sysctl) if (ARG3 != (UWord)NULL) { //POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); POST_MEM_WRITE((Addr)ARG3, *(vki_size_t *)ARG4); - } else + } else { POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); + } } } @@ -2121,8 +2093,9 @@ PRE(sys_futimes) { PRINT("sys_lutimes ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2); PRE_REG_READ2(long, "futimes", int, fd, struct timeval *, times); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_READ( "futimes(times)", ARG2, sizeof(struct vki_timeval) ); + } } // SYS_getpgid 207 @@ -2265,10 +2238,11 @@ PRE(sys_shmat) PRE_REG_READ3(void *, "shmat", int, shmid, const void *, addr, int, flag); arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3); - if (arg2tmp == 0) + if (arg2tmp == 0) { SET_STATUS_Failure( VKI_EINVAL ); - else + } else { ARG2 = arg2tmp; + } } POST(sys_shmat) @@ -2308,8 +2282,9 @@ PRE(sys_shmdt) { PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1); PRE_REG_READ1(int, "shmdt", const void *, addr); - if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1)) + if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1)) { SET_STATUS_Failure( VKI_EINVAL ); + } } POST(sys_shmdt) @@ -2360,14 +2335,16 @@ PRE(sys_clock_getres) // defined above! PRE_REG_READ2(int, "clock_getres", vki_clockid_t, clock_id, struct timespec *, tp); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_WRITE( "clock_getres(tp)", ARG2, sizeof(struct vki_timespec) ); + } } POST(sys_clock_getres) { - if (ARG2 != 0) + if (ARG2 != 0) { POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) ); + } } // SYS_ktimer_create 235 @@ -2379,8 +2356,9 @@ PRE(sys_timer_create) PRE_REG_READ3(int, "timer_create", vki_clockid_t, clockid, struct sigevent *, evp, vki_timer_t *, timerid); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) ); + } PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) ); } @@ -2410,15 +2388,17 @@ PRE(sys_timer_settime) struct itimerspec *, ovalue); PRE_MEM_READ( "timer_settime(value)", ARG3, sizeof(struct vki_itimerspec) ); - if (ARG4 != 0) + if (ARG4 != 0) { PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4, sizeof(struct vki_itimerspec) ); + } } POST(sys_timer_settime) { - if (ARG4 != 0) + if (ARG4 != 0) { POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) ); + } } // SYS_ktimer_gettime 238 @@ -2471,15 +2451,16 @@ PRE(sys_clock_nanosleep) PRE_REG_READ4(int, "clock_nanosleep", clockid_t, clock_id, int, flags, const struct timespec *, rqtp, struct timespec *, rmtp); PRE_MEM_READ("clock_nanosleep(rqtp)", ARG1, sizeof(struct vki_timespec)); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG2, sizeof(struct vki_timespec) ); - + } } POST(sys_clock_nanosleep) { - if (ARG2 != 0) + if (ARG2 != 0) { POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) ); + } } // SYS_clock_getcpuclockid2 247 @@ -2502,14 +2483,16 @@ PRE(sys_minherit) PRINT("sys_minherit( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); PRE_REG_READ3(int, "minherit", void *, addr, vki_size_t, len, int, inherit); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_WRITE( "minherit(addr)", ARG1,ARG2 ); + } } POST(sys_minherit) { - if (ARG2 != 0) + if (ARG2 != 0) { POST_MEM_WRITE( ARG1, ARG2 ); + } } // SYS_rfork 251 @@ -2622,8 +2605,9 @@ PRE(sys_lutimes) PRINT("sys_lutimes ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2); PRE_REG_READ2(int, "lutimes", char *, path, struct timeval *, times); PRE_MEM_RASCIIZ( "lutimes(path)", ARG1 ); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_READ( "lutimes(times)", ARG2, sizeof(struct vki_timeval) ); + } } // SYS_freebsd11_nstat 278 @@ -2661,8 +2645,9 @@ POST(sys_fhopen) VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_nameless)(tid, RES); + } } } @@ -2932,9 +2917,10 @@ PRE(sys_sched_setscheduler) PRINT("sys_sched_setscheduler ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3); PRE_REG_READ3(int, "sched_setscheduler", vki_pid_t, pid, int, policy, struct sched_param *, param); - if (ARG3 != 0) + if (ARG3 != 0) { PRE_MEM_READ("sched_setscheduler(param)", ARG3, sizeof(struct vki_sched_param)); + } } // SYS_sched_getscheduler 330 @@ -3033,10 +3019,12 @@ PRE(sys_sigprocmask) PRINT("sys_sigprocmask ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); PRE_REG_READ3(int, "sigprocmask", int, how, vki_sigset_t *, set, vki_sigset_t *, oset); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t)); - if (ARG3 != 0) + } + if (ARG3 != 0) { PRE_MEM_WRITE( "sigprocmask(oset)", ARG3, sizeof(vki_sigset_t)); + } if (ARG2 != 0 && !ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) { @@ -3054,15 +3042,17 @@ PRE(sys_sigprocmask) (vki_sigset_t*)(Addr)ARG3)); } - if (SUCCESS) + if (SUCCESS) { *flags |= SfPollAfter; + } } POST(sys_sigprocmask) { vg_assert(SUCCESS); - if (RES == 0 && ARG3 != 0) + if (RES == 0 && ARG3 != 0) { POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t)); + } } // SYS_sigsuspend 341 @@ -3109,19 +3099,23 @@ PRE(sys_sigtimedwait) PRE_REG_READ3(int, "sigtimedwait", const vki_sigset_t *, set, vki_siginfo_t *, info, const struct timespec *, timeout); - if (ARG1 != 0) + if (ARG1 != 0) { PRE_MEM_READ( "sigtimedwait(set)", ARG1, sizeof(vki_sigset_t)); - if (ARG2 != 0) + } + if (ARG2 != 0) { PRE_MEM_WRITE( "sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) ); - if (ARG3 != 0) + } + if (ARG3 != 0) { PRE_MEM_READ( "sigtimedwait(timeout)", ARG3, sizeof(struct vki_timespec) ); + } } POST(sys_sigtimedwait) { - if (ARG2 != 0) + if (ARG2 != 0) { POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) ); + } } // SYS_sigwaitinfo 346 @@ -3133,16 +3127,19 @@ PRE(sys_sigwaitinfo) ARG1,ARG2); PRE_REG_READ2(int, "sigwaitinfo", const vki_sigset_t *, set, vki_siginfo_t *, info); - if (ARG1 != 0) + if (ARG1 != 0) { PRE_MEM_READ( "sigwaitinfo(set)", ARG1, sizeof(vki_sigset_t)); - if (ARG2 != 0) + } + if (ARG2 != 0) { PRE_MEM_WRITE( "sigwaitinfo(info)", ARG2, sizeof(vki_siginfo_t) ); + } } POST(sys_sigwaitinfo) { - if (ARG2 != 0) + if (ARG2 != 0) { POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) ); + } } // SYS___acl_get_file 347 @@ -3396,23 +3393,28 @@ PRE(sys_freebsd11_kevent) int, fd, const struct vki_kevent_freebsd11 *, changelist, int, nchanges, struct vki_kevent_freebsd11 *, eventlist, int, nevents, struct timespec *, timeout); - if (ARG2 != 0 && ARG3 != 0) + if (ARG2 != 0 && ARG3 != 0) { PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent_freebsd11)*ARG3 ); - if (ARG4 != 0 && ARG5 != 0) + } + if (ARG4 != 0 && ARG5 != 0) { PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent_freebsd11)*ARG5); - if (ARG5 != 0) + } + if (ARG5 != 0) { *flags |= SfMayBlock; - if (ARG6 != 0) + } + if (ARG6 != 0) { PRE_MEM_READ( "kevent(timeout)", ARG6, sizeof(struct vki_timespec)); + } } POST(sys_freebsd11_kevent) { vg_assert(SUCCESS); if ((Word)RES != -1) { - if (ARG4 != 0) + if (ARG4 != 0) { POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent_freebsd11)*RES) ; + } } } #else @@ -3555,8 +3557,9 @@ POST(sys_kenv) POST_MEM_WRITE(ARG3, ARG4); break; case VKI_KENV_DUMP: - if (ARG3 != (Addr)NULL) + if (ARG3 != (Addr)NULL) { POST_MEM_WRITE(ARG3, ARG4); + } break; } } @@ -3584,8 +3587,9 @@ PRE(sys_uuidgen) POST(sys_uuidgen) { - if (SUCCESS) + if (SUCCESS) { POST_MEM_WRITE( ARG1, ARG2 * sizeof(struct vki_uuid) ); + } } // SYS_sendfile 393 @@ -3812,8 +3816,10 @@ PRE(sys_extattr_delete_link) // struct sigaction * restrict oact); PRE(sys_sigaction) { - vki_sigaction_toK_t new, *newp; - vki_sigaction_fromK_t old, *oldp; + vki_sigaction_toK_t new; + vki_sigaction_toK_t *newp; + vki_sigaction_fromK_t old; + vki_sigaction_fromK_t *oldp; PRINT("sys_sigaction ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,ARG2,ARG3); @@ -3874,8 +3880,9 @@ PRE(sys_sigaction) POST(sys_sigaction) { vg_assert(SUCCESS); - if (RES == 0 && ARG3 != 0) + if (RES == 0 && ARG3 != 0) { POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction)); + } } // SYS_sigreturn 417 @@ -3893,8 +3900,9 @@ POST(sys_getcontext) POST(sys_swapcontext) { - if (SUCCESS) + if (SUCCESS) { POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) ); + } } #if (FREEBSD_VERS >= FREEBSD_13_1) @@ -3976,16 +3984,19 @@ PRE(sys_sigwait) ARG1,ARG2); PRE_REG_READ2(int, "sigwait", const vki_sigset_t *, set, int *, sig); - if (ARG1 != 0) + if (ARG1 != 0) { PRE_MEM_READ( "sigwait(set)", ARG1, sizeof(vki_sigset_t)); - if (ARG2 != 0) + } + if (ARG2 != 0) { PRE_MEM_WRITE( "sigwait(sig)", ARG2, sizeof(int)); + } } POST(sys_sigwait) { - if (ARG2 != 0) + if (ARG2 != 0) { POST_MEM_WRITE( ARG2, sizeof(int)); + } } // SYS_thr_create 430 @@ -4049,9 +4060,10 @@ PRE(sys_thr_kill) /* Check to see if this kill gave us a pending signal */ *flags |= SfPollAfter; - if (VG_(clo_trace_signals)) + if (VG_(clo_trace_signals)) { VG_(message)(Vg_DebugMsg, "thr_kill: sending signal %lu to tid %lu\n", ARG2, ARG1); + } /* If we're sending SIGKILL, check to see if the target is one of our threads and handle it specially. */ @@ -4074,9 +4086,10 @@ PRE(sys_thr_kill) POST(sys_thr_kill) { - if (VG_(clo_trace_signals)) + if (VG_(clo_trace_signals)) { VG_(message)(Vg_DebugMsg, "thr_kill: sent signal %lu to tid %lu\n", ARG2, ARG1); + } } #if (FREEBSD_VERS <= FREEBSD_10) @@ -4091,8 +4104,9 @@ PRE(sys__umtx_lock) POST(sys__umtx_lock) { - if (SUCCESS) + if (SUCCESS) { POST_MEM_WRITE(ARG1, sizeof(struct vki_umtx)); + } } // SYS__umtx_unlock 434 @@ -4106,8 +4120,9 @@ PRE(sys__umtx_unlock) POST(sys__umtx_unlock) { - if (SUCCESS) + if (SUCCESS) { POST_MEM_WRITE(ARG1, sizeof(struct vki_umtx)); + } } #endif @@ -4504,12 +4519,10 @@ POST(sys__umtx_op) { switch(ARG2) { case VKI_UMTX_OP_LOCK: - if (SUCCESS) - POST_MEM_WRITE( ARG1, sizeof(struct vki_umtx) ); - break; case VKI_UMTX_OP_UNLOCK: - if (SUCCESS) + if (SUCCESS) { POST_MEM_WRITE( ARG1, sizeof(struct vki_umtx) ); + } break; case VKI_UMTX_OP_WAIT: case VKI_UMTX_OP_WAKE: @@ -4522,14 +4535,16 @@ POST(sys__umtx_op) case VKI_UMTX_OP_MUTEX_UNLOCK: case VKI_UMTX_OP_MUTEX_WAIT: /* Sets/clears contested bits */ case VKI_UMTX_OP_MUTEX_WAKE: /* Sets/clears contested bits */ - if (SUCCESS) + if (SUCCESS) { POST_MEM_WRITE( ARG1, sizeof(struct vki_umutex) ); + } break; case VKI_UMTX_OP_SET_CEILING: if (SUCCESS) { POST_MEM_WRITE( ARG1, sizeof(struct vki_umutex) ); - if (ARG4) + if (ARG4) { POST_MEM_WRITE( ARG4, sizeof(vki_uint32_t) ); + } } break; case VKI_UMTX_OP_CV_WAIT: @@ -4539,10 +4554,6 @@ POST(sys__umtx_op) } break; case VKI_UMTX_OP_CV_SIGNAL: - if (SUCCESS) { - POST_MEM_WRITE( ARG1, sizeof(struct vki_ucond) ); - } - break; case VKI_UMTX_OP_CV_BROADCAST: if (SUCCESS) { POST_MEM_WRITE( ARG1, sizeof(struct vki_ucond) ); @@ -4617,8 +4628,9 @@ POST(sys_kmq_open) VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_with_given_name)(tid, RES, (const HChar*)ARG1); + } } } @@ -4660,20 +4672,23 @@ PRE(sys_kmq_timedreceive) SET_STATUS_Failure( VKI_EBADF ); } else { PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 ); - if (ARG4 != 0) + if (ARG4 != 0) { PRE_MEM_WRITE( "mq_timedreceive(msg_prio)", ARG4, sizeof(unsigned int) ); - if (ARG5 != 0) + } + if (ARG5 != 0) { PRE_MEM_READ( "mq_timedreceive(abs_timeout)", ARG5, sizeof(struct vki_timespec) ); + } } } POST(sys_kmq_timedreceive) { POST_MEM_WRITE( ARG2, ARG3 ); - if (ARG4 != 0) + if (ARG4 != 0) { POST_MEM_WRITE( ARG4, sizeof(unsigned int) ); + } } // SYS_kmq_timedsend 460 @@ -4691,9 +4706,10 @@ PRE(sys_kmq_timedsend) SET_STATUS_Failure( VKI_EBADF ); } else { PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 ); - if (ARG5 != 0) + if (ARG5 != 0) { PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5, sizeof(struct vki_timespec) ); + } } } @@ -4704,11 +4720,13 @@ PRE(sys_kmq_notify) PRINT("sys_kmq_notify( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2 ); PRE_REG_READ2(int, "mq_notify", vki_mqd_t, mqdes, const struct sigevent *, notification); - if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False)) + if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False)) { SET_STATUS_Failure( VKI_EBADF ); - else if (ARG2 != 0) + } + else if (ARG2 != 0) { PRE_MEM_READ( "mq_notify(notification)", ARG2, sizeof(struct vki_sigevent) ); + } } // SYS_kmq_unlink 462 @@ -4776,8 +4794,9 @@ PRE(sys_rtprio_thread) POST(sys_rtprio_thread) { - if (ARG1 == VKI_RTP_LOOKUP && RES == 0) + if (ARG1 == VKI_RTP_LOOKUP && RES == 0) { POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio)); + } } // SYS_sctp_peeloff 471 @@ -4803,8 +4822,9 @@ PRE(sys_sctp_generic_sendmsg) ML_(pre_mem_read_sockaddr) (tid, "sctp_generic_sendmsg(to)", (struct vki_sockaddr *)ARG4, ARG5); - if (ARG6 != (Addr)NULL) + if (ARG6 != (Addr)NULL) { PRE_MEM_READ( "sctp_generic_sendmsg(sinfo)", ARG6, sizeof(struct vki_sctp_sndrcvinfo)); + } } // SYS_sctp_generic_sendmsg_iov 473 @@ -4836,16 +4856,19 @@ PRE(sys_sctp_generic_recvmsg) PRE_MEM_WRITE("sctp_generic_recvmsg(iov.iov_base)", (Addr)iovec->iov_base, iovec->iov_len); } - if (ARG4 != (Addr)NULL) + if (ARG4 != (Addr)NULL) { ML_(buf_and_len_pre_check) (tid, ARG4, ARG5, "sctp_generic_recvmsg(from)", "sctp_generic_recvmsg(fromlen_in)"); + } - if (ARG6 != (Addr)NULL) + if (ARG6 != (Addr)NULL) { PRE_MEM_WRITE("sctp_generic_recvmsg(sinfo)", ARG6, sizeof(struct vki_sctp_sndrcvinfo)); + } - if (ARG7 != (Addr)NULL) + if (ARG7 != (Addr)NULL) { PRE_MEM_WRITE("sctp_generic_recvmsg(msgflags)", ARG7, sizeof(int)); + } } POST(sys_sctp_generic_recvmsg) @@ -4856,15 +4879,18 @@ POST(sys_sctp_generic_recvmsg) POST_MEM_WRITE( ARG2, ARG3*sizeof(struct vki_iovec) ); - if (ARG4 != (Addr)NULL) + if (ARG4 != (Addr)NULL) { ML_(buf_and_len_post_check) (tid, VG_(mk_SysRes_Success)(RES), ARG4, ARG5, "sctp_generic_recvmsg(fromlen_out)"); + } - if (ARG6 != (Addr)NULL) + if (ARG6 != (Addr)NULL) { POST_MEM_WRITE(ARG6, sizeof(struct vki_sctp_sndrcvinfo)); + } - if (ARG7 != (Addr)NULL) + if (ARG7 != (Addr)NULL) { POST_MEM_WRITE(ARG7, sizeof(int)); + } } // SYS_pread 475 @@ -4899,9 +4925,10 @@ PRE(sys_thr_kill2) /* Check to see if this kill gave us a pending signal */ *flags |= SfPollAfter; - if (VG_(clo_trace_signals)) + if (VG_(clo_trace_signals)) { VG_(message)(Vg_DebugMsg, "thr_kill2: sending signal %lu to pid %lu/%lu\n", ARG3, ARG1, ARG2); + } /* If we're sending SIGKILL, check to see if the target is one of our threads and handle it specially. */ @@ -4924,9 +4951,10 @@ PRE(sys_thr_kill2) POST(sys_thr_kill2) { - if (VG_(clo_trace_signals)) + if (VG_(clo_trace_signals)) { VG_(message)(Vg_DebugMsg, "thr_kill2: sent signal %lu to pid %lu/%lu\n", ARG3, ARG1, ARG2); + } } // SYS_shm_open 482 @@ -4951,8 +4979,9 @@ POST(sys_shm_open) VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); + } } } @@ -5077,14 +5106,13 @@ PRE(sys_fexecve) if (sr_isError(res)) { SET_STATUS_Failure(VKI_ENOENT); return; - } else { - char buf[2]; - VG_(read)((Int)sr_Res(res), buf, 2); - VG_(close)((Int)sr_Res(res)); - if (buf[0] == '#' && buf[1] == '!') - { - isScript = True; - } + } + + char buf[2]; + VG_(read)((Int)sr_Res(res), buf, 2); + VG_(close)((Int)sr_Res(res)); + if (buf[0] == '#' && buf[1] == '!') { + isScript = True; } if (isScript) { @@ -5145,10 +5173,12 @@ PRE(sys_futimesat) PRINT("sys_futimesat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(int, "futimesat", int, fd, const char *, path, struct timeval *, times); - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_RASCIIZ( "futimesat(path)", ARG2 ); - if (ARG3 != 0) + } + if (ARG3 != 0) { PRE_MEM_READ( "futimesat(times)", ARG3, 2 * sizeof(struct vki_timeval) ); + } } // SYS_linkat 495 @@ -5224,10 +5254,11 @@ PRE(sys_openat) int, fd, const char *, path, int, flags); } - if (ARG1 != (unsigned)VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat", tid, False)) + if (ARG1 != (unsigned)VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat", tid, False)) { SET_STATUS_Failure( VKI_EBADF ); - else + } else { PRE_MEM_RASCIIZ( "openat(path)", ARG2 ); + } /* Otherwise handle normally */ *flags |= SfMayBlock; @@ -5240,8 +5271,9 @@ POST(sys_openat) VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2); + } } } @@ -5549,11 +5581,13 @@ PRE(sys_pdfork) SET_STATUS_from_SysRes( VG_(do_syscall2)(__NR_pdfork, ARG1, ARG2) ); - if (!SUCCESS) return; + if (!SUCCESS) { + return; + } // RES is 0 for child, non-0 (the child's PID) for parent. is_child = ( RES == 0 ? True : False ); - child_pid = ( is_child ? -1 : RES ); + child_pid = ( is_child ? -1 : (Int)RES ); if (is_child) { VG_(do_atfork_child)(tid); @@ -5618,9 +5652,10 @@ PRE(sys_pdkill) SET_STATUS_from_SysRes(VG_(do_syscall2)(SYSNO, ARG1, ARG2)); - if (VG_(clo_trace_signals)) + if (VG_(clo_trace_signals)) { VG_(message)(Vg_DebugMsg, "pdkill: sent signal %ld to fd %ld\n", SARG2, SARG1); + } /* This kill might have given us a pending signal. Ask for a check once the syscall is done. */ @@ -5660,17 +5695,21 @@ PRE(sys_pselect) vki_fd_set *, exceptfds, struct vki_timespec *, timeout, const sigset_t *, newsigmask); // XXX: this possibly understates how much memory is read. - if (ARG2 != 0) + if (ARG2 != 0) { PRE_MEM_READ( "pselect(readfds)", ARG2, ARG1/8 /* __FD_SETSIZE/8 */ ); - if (ARG3 != 0) + } + if (ARG3 != 0) { PRE_MEM_READ( "pselect(writefds)", ARG3, ARG1/8 /* __FD_SETSIZE/8 */ ); - if (ARG4 != 0) + } + if (ARG4 != 0) { PRE_MEM_READ( "pselect(exceptfds)", ARG4, ARG1/8 /* __FD_SETSIZE/8 */ ); - if (ARG5 != 0) + } + if (ARG5 != 0) { PRE_MEM_READ( "pselect(timeout)", ARG5, sizeof(struct vki_timeval) ); + } if (ARG6 != 0) { PRE_MEM_READ( "pselect(sig)", ARG6, sizeof(vki_sigset_t) ); @@ -5935,8 +5974,9 @@ POST(sys_pipe2) { int *fildes; - if (RES != 0) + if (RES != 0) { return; + } POST_MEM_WRITE(ARG1, 2 * sizeof(int)); fildes = (int *)ARG1; @@ -6101,8 +6141,9 @@ PRE(sys_getdirentries) size_t, nbytes, off_t *, basep); PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); - if (ARG4) + if (ARG4) { PRE_MEM_WRITE("getdirentries(basep)", ARG4, sizeof (vki_off_t)); + } } POST(sys_getdirentries) @@ -6110,8 +6151,9 @@ POST(sys_getdirentries) vg_assert(SUCCESS); if (RES > 0) { POST_MEM_WRITE( ARG2, RES ); - if ( ARG4 != 0 ) + if ( ARG4 != 0 ) { POST_MEM_WRITE( ARG4, sizeof (vki_off_t)); + } } } @@ -6318,31 +6360,33 @@ PRE(sys_funlinkat) // size_t len, unsigned int flags); PRE(sys_copy_file_range) { - PRINT("sys_copy_file_range (%" FMT_REGWORD"d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "d, %" FMT_REGWORD "d)", - SARG1, ARG2, SARG3, ARG4, (char*)ARG4, SARG5, SARG6); - - PRE_REG_READ6(vki_ssize_t, "copy_file_range", - int, "infd", - vki_off_t *, "inoffp", - int, "outfd", - vki_off_t *, "outoffp", - vki_size_t, "len", - unsigned int, "flags"); - - /* File descriptors are "specially" tracked by valgrind. - valgrind itself uses some, so make sure someone didn't - put in one of our own... */ - if (!ML_(fd_allowed)(ARG1, "copy_file_range(infd)", tid, False) || - !ML_(fd_allowed)(ARG3, "copy_file_range(infd)", tid, False)) { - SET_STATUS_Failure( VKI_EBADF ); - } else { - /* Now see if the offsets are defined. PRE_MEM_READ will - double check it can dereference them. */ - if (ARG2 != 0) - PRE_MEM_READ( "copy_file_range(inoffp)", ARG2, sizeof(vki_off_t)); - if (ARG4 != 0) - PRE_MEM_READ( "copy_file_range(outoffp)", ARG4, sizeof(vki_off_t)); - } + PRINT("sys_copy_file_range (%" FMT_REGWORD"d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "d, %" FMT_REGWORD "d)", + SARG1, ARG2, SARG3, ARG4, (char*)ARG4, SARG5, SARG6); + + PRE_REG_READ6(vki_ssize_t, "copy_file_range", + int, "infd", + vki_off_t *, "inoffp", + int, "outfd", + vki_off_t *, "outoffp", + vki_size_t, "len", + unsigned int, "flags"); + + /* File descriptors are "specially" tracked by valgrind. + valgrind itself uses some, so make sure someone didn't + put in one of our own... */ + if (!ML_(fd_allowed)(ARG1, "copy_file_range(infd)", tid, False) || + !ML_(fd_allowed)(ARG3, "copy_file_range(infd)", tid, False)) { + SET_STATUS_Failure( VKI_EBADF ); + } else { + /* Now see if the offsets are defined. PRE_MEM_READ will + double check it can dereference them. */ + if (ARG2 != 0) { + PRE_MEM_READ( "copy_file_range(inoffp)", ARG2, sizeof(vki_off_t)); + } + if (ARG4 != 0) { + PRE_MEM_READ( "copy_file_range(outoffp)", ARG4, sizeof(vki_off_t)); + } + } } @@ -6383,8 +6427,9 @@ PRE(sys___sysctlbyname) PRE_MEM_READ("__sysctlbyname(name)", (Addr)ARG1, ARG2 * sizeof(int)); // if 'newp' is not NULL can read namelen bytes from that addess - if (ARG5 != (UWord)NULL) + if (ARG5 != (UWord)NULL) { PRE_MEM_READ("__sysctlbyname(newp)", (Addr)ARG5, ARG6); + } // there are two scenarios for oldlenp/oldp // 1. oldval is NULL and oldlenp is non-NULL @@ -6418,8 +6463,9 @@ POST(sys___sysctlbyname) if (ARG3 != (UWord)NULL) { //POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); POST_MEM_WRITE((Addr)ARG3, *(vki_size_t *)ARG4); - } else + } else { POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); + } } } @@ -6460,8 +6506,9 @@ POST(sys_shm_open2) VG_(close)(RES); SET_STATUS_Failure( VKI_EMFILE ); } else { - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds)) { ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); + } } } diff --git a/include/vki/vki-amd64-freebsd.h b/include/vki/vki-amd64-freebsd.h index 213c805cdf..44f4ce8c95 100644 --- a/include/vki/vki-amd64-freebsd.h +++ b/include/vki/vki-amd64-freebsd.h @@ -27,7 +27,7 @@ #define VKI_AMD64_FREEBSD_H /* PAGE_SHIFT determines the page size. */ -#define VKI_PAGE_SHIFT 12 +#define VKI_PAGE_SHIFT 12UL #define VKI_PAGE_SIZE (1UL << VKI_PAGE_SHIFT) #define VKI_MAX_PAGE_SHIFT VKI_PAGE_SHIFT #define VKI_MAX_PAGE_SIZE VKI_PAGE_SIZE diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 936abc8e3a..929eb74adb 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -959,12 +959,12 @@ struct vki_termios { * We actually have a 16 bit "base" ioctl, which may or may not be decoded * into number/group */ -#define _VKI_IOC_BASEBITS 16 -#define _VKI_IOC_NRBITS 8 /* "num" on freebsd */ -#define _VKI_IOC_TYPEBITS 8 /* "group" on freebsd */ +#define _VKI_IOC_BASEBITS 16U +#define _VKI_IOC_NRBITS 8U /* "num" on freebsd */ +#define _VKI_IOC_TYPEBITS 8U /* "group" on freebsd */ -#define _VKI_IOC_SIZEBITS 13 -#define _VKI_IOC_DIRBITS 3 +#define _VKI_IOC_SIZEBITS 13U +#define _VKI_IOC_DIRBITS 3U #define _VKI_IOC_BASEMASK ((1ul << _VKI_IOC_BASEBITS)-1) #define _VKI_IOC_NRMASK ((1ul << _VKI_IOC_NRBITS)-1) @@ -972,8 +972,8 @@ struct vki_termios { #define _VKI_IOC_SIZEMASK ((1ul << _VKI_IOC_SIZEBITS)-1) #define _VKI_IOC_DIRMASK ((1ul << _VKI_IOC_DIRBITS)-1) -#define _VKI_IOC_BASESHIFT 0 -#define _VKI_IOC_NRSHIFT 0 +#define _VKI_IOC_BASESHIFT 0U +#define _VKI_IOC_NRSHIFT 0U #define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS) #define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS) #define _VKI_IOC_DIRSHIFT (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS) @@ -1013,7 +1013,7 @@ extern unsigned int __vki_invalid_size_argument_for_IOC; // From sys/random.h //---------------------------------------------------------------------- -#define VKI_GRND_NONBLOCK 0x1 +#define VKI_GRND_NONBLOCK 0x1U //---------------------------------------------------------------------- // From sys/termios.h |
|
From: Paul F. <pa...@so...> - 2022-12-25 09:21:11
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=d8cc70f6d5a37b9b773c85f8666d6c5f7f65a29b commit d8cc70f6d5a37b9b773c85f8666d6c5f7f65a29b Author: Paul Floyd <pj...@wa...> Date: Sun Dec 25 10:18:51 2022 +0100 FreeBSD only: fix 445743 Restart 3 of the umtx_op mutex operations if they are interrupted. Diff: --- coregrind/m_signals.c | 2 +- coregrind/m_syswrap/priv_types_n_macros.h | 1 + coregrind/m_syswrap/syswrap-freebsd.c | 32 +++++++++++++++++++++---------- coregrind/m_syswrap/syswrap-main.c | 8 +++++++- coregrind/pub_core_syswrap.h | 2 ++ 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index bfddbe392a..b3c94fcc90 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -2604,7 +2604,7 @@ void async_signalhandler ( Int sigNo, tid, VG_UCONTEXT_INSTR_PTR(uc), sres, - !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART), + !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART) || VG_(is_in_kernel_restart_syscall)(tid), uc ); diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h index 3966cfa604..461019ad7b 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -185,6 +185,7 @@ typedef #define SfPollAfter (1 << 3) /* poll for signals on completion */ #define SfYieldAfter (1 << 4) /* yield on completion */ #define SfNoWriteResult (1 << 5) /* don't write result to guest state */ +#define SfKernelRestart (1 << 6) /* needs a manual restart */ /* --------------------------------------------------------------------- diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 53d09f89f0..71443e399b 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -4253,8 +4253,9 @@ PRE(sys__umtx_op) struct umtx *, obj, int, op, unsigned long, id, size_t, timeout_size, struct vki_timespec *, timeout); PRE_MEM_READ( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_lock(timespec)", ARG5, ARG4 ); + } PRE_MEM_WRITE( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) ); *flags |= SfMayBlock; break; @@ -4279,6 +4280,8 @@ PRE(sys__umtx_op) if (ARG5) { PRE_MEM_READ( "_umtx_op_wait(timeout)", ARG5, ARG4 ); + } else { + *flags |= SfKernelRestart; } break; @@ -4294,9 +4297,11 @@ PRE(sys__umtx_op) struct umutex *, obj, int, op, unsigned long, noid, size_t, timeout_size, struct vki_timespec *, timeout); PRE_MEM_READ( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_mutex_trylock(timespec)", ARG5, ARG4 ); + } PRE_MEM_WRITE( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) ); + *flags |= SfMayBlock | SfKernelRestart; break; case VKI_UMTX_OP_MUTEX_LOCK: PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_LOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); @@ -4304,10 +4309,11 @@ PRE(sys__umtx_op) struct umutex *, obj, int, op, unsigned long, noid, size_t, timeout_size, struct vki_timespec *, timeout); PRE_MEM_READ( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_mutex_lock(timespec)", ARG5, ARG4 ); + } PRE_MEM_WRITE( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) ); - *flags |= SfMayBlock; + *flags |= SfMayBlock | SfKernelRestart; break; case VKI_UMTX_OP_MUTEX_UNLOCK: PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_UNLOCK)", ARG1); @@ -4323,8 +4329,9 @@ PRE(sys__umtx_op) unsigned int *, old_ceiling); PRE_MEM_READ( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) ); PRE_MEM_WRITE( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) ); - if (ARG4) + if (ARG4) { PRE_MEM_WRITE( "_umtx_op_set_ceiling(old_ceiling)", ARG4, sizeof(vki_uint32_t) ); + } break; case VKI_UMTX_OP_CV_WAIT: PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); @@ -4335,8 +4342,9 @@ PRE(sys__umtx_op) PRE_MEM_WRITE( "_umtx_op_cv_wait(cond)", ARG1, sizeof(struct vki_ucond) ); PRE_MEM_READ( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) ); PRE_MEM_WRITE( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_cv_wait(timespec)", ARG5, sizeof(struct vki_timespec) ); + } *flags |= SfMayBlock; break; case VKI_UMTX_OP_CV_SIGNAL: @@ -4359,8 +4367,9 @@ PRE(sys__umtx_op) int *, obj, int, op, unsigned long, id, size_t, timeout_wait, struct vki_timespec *, timeout); PRE_MEM_READ( "_umtx_op_wait(uint)", ARG1, sizeof(int) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_wait(timespec)", ARG5, ARG4 ); + } *flags |= SfMayBlock; break; case VKI_UMTX_OP_RW_RDLOCK: @@ -4394,8 +4403,9 @@ PRE(sys__umtx_op) int *, obj, int, op, unsigned long, id, size_t, timeout_size, struct vki_timespec *, timeout); PRE_MEM_READ( "_umtx_op_wait_private(uint)", ARG1, sizeof(int) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_wait_private(umtx_time)", ARG5, ARG4 ); + } *flags |= SfMayBlock; break; case VKI_UMTX_OP_WAKE_PRIVATE: @@ -4426,8 +4436,9 @@ PRE(sys__umtx_op) size_t, timeout_size, struct vki_timespec *, timeout); PRE_MEM_READ( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) ); PRE_MEM_WRITE( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) ); - if (ARG5) + if (ARG5) { PRE_MEM_READ( "_umtx_op_sem_wait(umtx_time)", ARG5, ARG4 ); + } *flags |= SfMayBlock; break; case VKI_UMTX_OP_SEM_WAKE: @@ -4474,8 +4485,9 @@ PRE(sys__umtx_op) case VKI_UMTX_OP_ROBUST_LISTS: // val (ARG2) ought to be the same as sizeof(struct vki_umtx_robust_lists_params) // then the structure contains a pointer to mutex structures - if (ARG1 != sizeof(struct vki_umtx_robust_lists_params)) + if (ARG1 != sizeof(struct vki_umtx_robust_lists_params)) { SET_STATUS_Failure( VKI_ENOSYS ); + } PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, ROBUST_LISTS, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); PRE_REG_READ3(long, "_umtx_op_robust_lists", struct umtx_robust_lists_params *, obj, int, op, unsigned long, flags); diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index 5077a7da73..abd8472e92 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -2000,6 +2000,12 @@ Bool VG_(is_in_syscall) ( ThreadId tid ) return (syscallInfo && syscallInfo[tid].status.what != SsIdle); } +Bool VG_(is_in_kernel_restart_syscall) ( ThreadId tid ) +{ + vg_assert(tid >= 0 && tid < VG_N_THREADS); + return (syscallInfo && ((syscallInfo[tid].flags & SfKernelRestart) != 0)); +} + Word VG_(is_in_syscall_no) (ThreadId tid ) { vg_assert(tid >= 0 && tid < VG_N_THREADS); @@ -2302,7 +2308,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* Check that the given flags are allowable: MayBlock, PollAfter and PostOnFail are ok. */ - vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter))); + vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter | SfKernelRestart))); if (sci->flags & SfMayBlock) { diff --git a/coregrind/pub_core_syswrap.h b/coregrind/pub_core_syswrap.h index a17620afc2..0b40b501d6 100644 --- a/coregrind/pub_core_syswrap.h +++ b/coregrind/pub_core_syswrap.h @@ -52,6 +52,8 @@ 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) ( ThreadId tid ); +extern Bool VG_(is_in_kernel_restart_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 ); |
|
From: Paul F. <pa...@so...> - 2022-12-25 08:29:43
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=29cfa77b23c5edcfc22508f79a1a8b616cf473cd commit 29cfa77b23c5edcfc22508f79a1a8b616cf473cd Author: Paul Floyd <pj...@wa...> Date: Sun Dec 25 09:25:01 2022 +0100 FreeBSD: enable PERF_FAST_LOADV for x86 and cleanup for clangd clangd doesn't like asm, prefers __asm__ some hicpp-braces-around-statements fixes Diff: --- coregrind/m_sigframe/sigframe-amd64-freebsd.c | 14 +++++++---- coregrind/m_syswrap/syswrap-amd64-freebsd.c | 33 ++++++++++++++++---------- coregrind/m_syswrap/syswrap-freebsd.c | 34 +++++++++++++++++---------- coregrind/m_syswrap/syswrap-x86-freebsd.c | 2 +- coregrind/vgdb-invoker-freebsd.c | 16 +++++++++---- memcheck/mc_main.c | 4 ++-- memcheck/mc_main_asm.c | 2 +- 7 files changed, 66 insertions(+), 39 deletions(-) diff --git a/coregrind/m_sigframe/sigframe-amd64-freebsd.c b/coregrind/m_sigframe/sigframe-amd64-freebsd.c index 997cf77c7e..31e6e784ae 100644 --- a/coregrind/m_sigframe/sigframe-amd64-freebsd.c +++ b/coregrind/m_sigframe/sigframe-amd64-freebsd.c @@ -175,9 +175,10 @@ static Bool extend ( ThreadState *tst, Addr addr, SizeT size ) if (VG_(extend_stack)(tid, addr)) { stackseg = VG_(am_find_nsegment)(addr); - if (0 && stackseg) + if (0 && stackseg) { VG_(printf)("frame=%#lx seg=%#lx-%#lx\n", addr, stackseg->start, stackseg->end); + } } if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) { @@ -185,10 +186,11 @@ static Bool extend ( ThreadState *tst, Addr addr, SizeT size ) Vg_UserMsg, "Can't extend stack to %#lx during signal delivery for thread %u:\n", addr, tid); - if (stackseg == NULL) + if (stackseg == NULL) { VG_(message)(Vg_UserMsg, " no stack segment\n"); - else + } else { VG_(message)(Vg_UserMsg, " too small or bad protection modes\n"); + } /* set SIGSEGV to default handler */ VG_(set_default_handler)(VKI_SIGSEGV); @@ -246,8 +248,9 @@ static Addr build_sigframe(ThreadState *tst, rsp = VG_ROUNDDN(rsp, 16) - 8; frame = (struct sigframe *)rsp; - if (!extend(tst, rsp, sizeof(*frame))) + if (!extend(tst, rsp, sizeof(*frame))) { return rsp_top_of_frame; + } /* retaddr, siginfo, uContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", @@ -392,8 +395,9 @@ static SizeT restore_sigframe ( ThreadState *tst, struct sigframe *frame, Int *sigNo ) { - if (restore_vg_sigframe(tst, &frame->vg, sigNo)) + if (restore_vg_sigframe(tst, &frame->vg, sigNo)) { restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate); + } return sizeof(*frame); } diff --git a/coregrind/m_syswrap/syswrap-amd64-freebsd.c b/coregrind/m_syswrap/syswrap-amd64-freebsd.c index 3b2f9397d1..aa58140e2c 100644 --- a/coregrind/m_syswrap/syswrap-amd64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-amd64-freebsd.c @@ -72,7 +72,7 @@ void ML_(call_on_new_stack_0_1) ( Addr stack, // %rsi == retaddr // %rdx == f // %rcx == arg1 -asm( +__asm__( ".text\n" ".globl vgModuleLocal_call_on_new_stack_0_1\n" "vgModuleLocal_call_on_new_stack_0_1:\n" @@ -178,8 +178,6 @@ POST(sys_sysarch) case VKI_AMD64_SET_FSBASE: break; case VKI_AMD64_GET_FSBASE: - POST_MEM_WRITE( ARG2, sizeof(void *) ); - break; case VKI_AMD64_GET_XFPUSTATE: POST_MEM_WRITE( ARG2, sizeof(void *) ); break; @@ -331,8 +329,9 @@ PRE(sys_preadv) if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) { SET_STATUS_Failure( VKI_EBADF ); } else { - if ((Int)ARG3 > 0) + if ((Int)ARG3 > 0) { PRE_MEM_READ( "preadv(iov)", ARG2, ARG3 * sizeof(struct vki_iovec) ); + } if (ML_(safe_to_deref)((struct vki_iovec *)ARG2, ARG3 * sizeof(struct vki_iovec))) { vec = (struct vki_iovec *)(Addr)ARG2; @@ -355,10 +354,14 @@ POST(sys_preadv) /* RES holds the number of bytes read. */ for (i = 0; i < (Int)ARG3; i++) { Int nReadThisBuf = vec[i].iov_len; - if (nReadThisBuf > remains) nReadThisBuf = remains; + if (nReadThisBuf > remains) { + nReadThisBuf = remains; + } POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf ); remains -= nReadThisBuf; - if (remains < 0) VG_(core_panic)("preadv: remains < 0"); + if (remains < 0) { + VG_(core_panic)("preadv: remains < 0"); + } } } } @@ -381,8 +384,9 @@ PRE(sys_pwritev) if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) { SET_STATUS_Failure( VKI_EBADF ); } else { - if ((Int)ARG3 >= 0) + if ((Int)ARG3 >= 0) { PRE_MEM_READ( "pwritev(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) ); + } if (ML_(safe_to_deref)((struct vki_iovec *)ARG2, ARG3 * sizeof(struct vki_iovec))) { vec = (struct vki_iovec *)(Addr)ARG2; for (i = 0; i < (Int)ARG3; i++) { @@ -406,11 +410,13 @@ PRE(sys_sendfile) int, fd, int, s, vki_off_t, offset, size_t, nbytes, void *, hdtr, vki_off_t *, sbytes, int, flags); - if (ARG5 != 0) + if (ARG5 != 0) { PRE_MEM_READ("sendfile(hdtr)", ARG5, sizeof(struct vki_sf_hdtr)); + } - if (ARG6 != 0) + if (ARG6 != 0) { PRE_MEM_WRITE( "sendfile(sbytes)", ARG6, sizeof(vki_off_t) ); + } } POST(sys_sendfile) @@ -567,7 +573,8 @@ PRE(sys_setcontext) // int swapcontext(ucontext_t *oucp, const ucontext_t *ucp); PRE(sys_swapcontext) { - struct vki_ucontext *ucp, *oucp; + struct vki_ucontext *ucp; + struct vki_ucontext *oucp; ThreadState* tst; PRINT("sys_swapcontext ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2); @@ -623,7 +630,8 @@ PRE(sys_thr_new) ThreadState* ptst = VG_(get_ThreadState)(tid); ThreadState* ctst = VG_(get_ThreadState)(ctid); SysRes res; - vki_sigset_t blockall, savedmask; + vki_sigset_t blockall; + vki_sigset_t savedmask; struct vki_thr_param tp; Addr stk; @@ -689,8 +697,9 @@ PRE(sys_thr_new) label below, to clean up. */ VG_TRACK ( pre_thread_ll_create, tid, ctid ); - if (debug) + if (debug) { VG_(printf)("clone child has SETTLS: tls at %#lx\n", (Addr)tp.tls_base); + } ctst->arch.vex.guest_FS_CONST = (UWord)tp.tls_base; tp.tls_base = 0; /* Don't have the kernel do it too */ diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index dc43050070..53d09f89f0 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -235,7 +235,7 @@ static void run_a_thread_NORETURN ( Word tidW ) between marking it Empty and exiting. Hence the assembler. */ #if defined(VGP_x86_freebsd) /* FreeBSD has args on the stack */ - asm volatile ( + __asm__ volatile ( "movl %1, %0\n" /* set tst->status = VgTs_Empty */ "movl %2, %%eax\n" /* set %eax = __NR_thr_exit */ "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */ @@ -249,7 +249,7 @@ static void run_a_thread_NORETURN ( Word tidW ) : "eax", "ebx" ); #elif defined(VGP_amd64_freebsd) - asm volatile ( + __asm__ volatile ( "movl %1, %0\n" /* set tst->status = VgTs_Empty */ "movq %2, %%rax\n" /* set %rax = __NR_thr_exit */ "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */ @@ -294,11 +294,13 @@ Addr ML_(allocstack)(ThreadId tid) case a stack hasn't been allocated) or they are both non-zero, in which case it has. */ - if (tst->os_state.valgrind_stack_base == 0) + if (tst->os_state.valgrind_stack_base == 0) { vg_assert(tst->os_state.valgrind_stack_init_SP == 0); + } - if (tst->os_state.valgrind_stack_base != 0) + if (tst->os_state.valgrind_stack_base != 0) { vg_assert(tst->os_state.valgrind_stack_init_SP != 0); + } /* If no stack is present, allocate one. */ @@ -5994,8 +5996,9 @@ POST(sys_ppoll) if (SUCCESS && ((Word)RES != -1)) { UInt i; struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1; - for (i = 0; i < ARG2; i++) + for (i = 0; i < ARG2; i++) { POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) ); + } } ML_(free_safe_mask) ( (Addr)ARG4 ); } @@ -6184,23 +6187,28 @@ PRE(sys_kevent) int, kq, struct vki_kevent *, changelist, int, nchanges, struct vki_kevent *, eventlist, int, nevents, struct timespec *, timeout); - if (ARG2 != 0 && ARG3 != 0) + if (ARG2 != 0 && ARG3 != 0) { PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent)*ARG3 ); - if (ARG4 != 0 && ARG5 != 0) + } + if (ARG4 != 0 && ARG5 != 0) { PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent)*ARG5); - if (ARG5 != 0) + } + if (ARG5 != 0) { *flags |= SfMayBlock; - if (ARG6 != 0) + } + if (ARG6 != 0) { PRE_MEM_READ( "kevent(timeout)", ARG6, sizeof(struct vki_timespec)); + } } POST(sys_kevent) { vg_assert(SUCCESS); if ((Word)RES != -1) { - if (ARG4 != 0) + if (ARG4 != 0) { POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent)*RES) ; + } } } @@ -7233,10 +7241,10 @@ const SyscallTableEntry* ML_(get_freebsd_syscall_entry) ( UInt sysno ) /* Is it in the contiguous initial section of the table? */ if (sysno < syscall_table_size) { const SyscallTableEntry* sys = &ML_(syscall_table)[sysno]; - if (sys->before == NULL) + if (sys->before == NULL) { return NULL; /* no entry */ - else - return sys; + } + return sys; } /* Can't find a wrapper */ diff --git a/coregrind/m_syswrap/syswrap-x86-freebsd.c b/coregrind/m_syswrap/syswrap-x86-freebsd.c index 0e92270144..cd7db23646 100644 --- a/coregrind/m_syswrap/syswrap-x86-freebsd.c +++ b/coregrind/m_syswrap/syswrap-x86-freebsd.c @@ -79,7 +79,7 @@ void ML_(call_on_new_stack_0_1) ( Addr stack, // 8(%esp) == retaddr // 12(%esp) == f // 16(%esp) == arg1 -asm( +__asm__( ".text\n" ".globl vgModuleLocal_call_on_new_stack_0_1\n" "vgModuleLocal_call_on_new_stack_0_1:\n" diff --git a/coregrind/vgdb-invoker-freebsd.c b/coregrind/vgdb-invoker-freebsd.c index d9f3584f80..6de80c9071 100644 --- a/coregrind/vgdb-invoker-freebsd.c +++ b/coregrind/vgdb-invoker-freebsd.c @@ -110,8 +110,9 @@ int ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr, if (debuglevel >= 1) { DEBUG (1, "Writing "); - for (i = 0; i < len; i++) + for (i = 0; i < len; i++) { PDEBUG (1, "%02x", ((const unsigned char*)myaddr)[i]); + } PDEBUG(1, " to %p\n", (void *) memaddr); } @@ -139,8 +140,9 @@ int ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr, errno = 0; ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]); - if (errno) + if (errno) { return errno; + } } return 0; @@ -160,15 +162,18 @@ char *status_image (int status) if (WIFSIGNALED(status)) { APPEND ("WIFSIGNALED %d ", WTERMSIG(status)); - if (WCOREDUMP(status)) APPEND ("WCOREDUMP "); + if (WCOREDUMP(status)) { + APPEND ("WCOREDUMP "); + } } if (WIFSTOPPED(status)) APPEND ("WIFSTOPPED %d ", WSTOPSIG(status)); #ifdef WIFCONTINUED - if (WIFCONTINUED(status)) + if (WIFCONTINUED(status)) { APPEND ("WIFCONTINUED "); + } #endif return result; @@ -212,8 +217,9 @@ Bool waitstopped (pid_t pid, int signal_expected, const char *msg) assert (WIFSTOPPED(status)); signal_received = WSTOPSIG(status); - if (signal_received == signal_expected) + if (signal_received == signal_expected) { break; + } /* pid received a signal which is not the signal we are waiting for. If we have not (yet) changed the registers of the inferior diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 141cfe19e1..94af5b28a2 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -369,7 +369,7 @@ static void update_SM_counts(SecMap* oldSM, SecMap* newSM) */ #if ENABLE_ASSEMBLY_HELPERS && defined(PERF_FAST_LOADV) \ && (defined(VGP_arm_linux) \ - || defined(VGP_x86_linux) || defined(VGP_x86_solaris)) + || defined(VGP_x86_linux) || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd)) /* mc_main_asm.c needs visibility on a few things declared in this file. MC_MAIN_STATIC allows to define them static if ok, i.e. on platforms that are not using hand-coded asm statements. */ @@ -5028,7 +5028,7 @@ VG_REGPARM(1) ULong MC_(helperc_LOADV64be) ( Addr a ) /* See mc_main_asm.c */ #elif ENABLE_ASSEMBLY_HELPERS && defined(PERF_FAST_LOADV) \ - && (defined(VGP_x86_linux) || defined(VGP_x86_solaris)) + && (defined(VGP_x86_linux) || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd)) /* See mc_main_asm.c */ #else diff --git a/memcheck/mc_main_asm.c b/memcheck/mc_main_asm.c index 06033d78c2..c221b800fb 100644 --- a/memcheck/mc_main_asm.c +++ b/memcheck/mc_main_asm.c @@ -83,7 +83,7 @@ __asm__( /* Derived from the 32 bit assembly helper */ ); #elif ENABLE_ASSEMBLY_HELPERS && defined(PERF_FAST_LOADV) \ - && (defined(VGP_x86_linux) || defined(VGP_x86_solaris)) + && (defined(VGP_x86_linux) || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd)) __asm__( ".text\n" ".align 16\n" |
|
From: Bart V. A. <bva...@so...> - 2022-12-25 00:51:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1845f517283562f11ce05757bb62d988cbf273bd commit 1845f517283562f11ce05757bb62d988cbf273bd Author: Bart Van Assche <bva...@ac...> Date: Sat Dec 24 16:49:56 2022 -0800 Revert "syscall" Revert an incomplete commit that got published accidentally. Diff: --- memcheck/tests/arm64-linux/scalar.h | 8 +++++++- memcheck/tests/x86-linux/scalar.h | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/memcheck/tests/arm64-linux/scalar.h b/memcheck/tests/arm64-linux/scalar.h index 3dbfa79673..9008816d6e 100644 --- a/memcheck/tests/arm64-linux/scalar.h +++ b/memcheck/tests/arm64-linux/scalar.h @@ -1,3 +1,6 @@ +/* This is the arm64 variant of memcheck/tests/x86-linux/scalar.h */ +#include "../../../include/vki/vki-scnums-arm64-linux.h" + #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -8,7 +11,10 @@ #include <sys/ptrace.h> #include <sys/types.h> #include <sys/mman.h> -#include <unistd.h> + +// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to +// declare this ourselves. +extern long int syscall (long int __sysno, ...) __THROW; // Thorough syscall scalar arg checking. Also serves as thorough checking // for (very) basic syscall use. Generally not trying to do anything diff --git a/memcheck/tests/x86-linux/scalar.h b/memcheck/tests/x86-linux/scalar.h index 3dbfa79673..ef28b03550 100644 --- a/memcheck/tests/x86-linux/scalar.h +++ b/memcheck/tests/x86-linux/scalar.h @@ -1,3 +1,5 @@ +#include "../../../include/vki/vki-scnums-x86-linux.h" + #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -8,7 +10,10 @@ #include <sys/ptrace.h> #include <sys/types.h> #include <sys/mman.h> -#include <unistd.h> + +// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to +// declare this ourselves. +extern long int syscall (long int __sysno, ...) __THROW; // Thorough syscall scalar arg checking. Also serves as thorough checking // for (very) basic syscall use. Generally not trying to do anything |
|
From: Mark W. <ma...@kl...> - 2022-12-25 00:45:49
|
Hi Bart, On Sat, Dec 24, 2022 at 04:38:53PM -0800, Bart Van Assche wrote: > That commit is incomplete work that should not have been published. I tried > to remove that commit but apparently I do not have permission to do a > force-push: > > ---------------------------------------------------------------------- > $ git push origin +master > Enumerating objects: 9, done. > Counting objects: 100% (9/9), done. > Delta compression using up to 8 threads > Compressing objects: 100% (5/5), done. > Writing objects: 100% (5/5), 557 bytes | 557.00 KiB/s, done. > Total 5 (delta 4), reused 0 (delta 0), pack-reused 0 > remote: error: denying non-fast-forward refs/heads/master (you should pull > first) > To ssh://sourceware.org/git/valgrind.git/ > ! [remote rejected] master -> master (non-fast-forward) > error: failed to push some refs to 'ssh://sourceware.org/git/valgrind.git/' > ---------------------------------------------------------------------- > > Does that mean that my only option is to revert that patch? Ah, yes, sorry, once pushed publicly it cannot be taken back. But no worries, you can indeed just git revert 2bd7f7042 and push that. Thanks, Mark |
|
From: Bart V. A. <bva...@ac...> - 2022-12-25 00:39:03
|
On 12/24/22 16:33, Mark Wielaard wrote: > Hi Bart, > > On Sat, Dec 24, 2022 at 11:37:34PM +0000, Bart Van Assche wrote: >> https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2bd7f7042125c99326ffa21c52f368f0721040ca >> >> commit 2bd7f7042125c99326ffa21c52f368f0721040ca >> Author: Bart Van Assche <bva...@ac...> >> Date: Mon Jun 20 12:46:40 2022 -0700 >> >> syscall > > Could you explain this commit a bit more? > It seems to have broken the build on at least debian-i386: Hi Mark, That commit is incomplete work that should not have been published. I tried to remove that commit but apparently I do not have permission to do a force-push: ---------------------------------------------------------------------- $ git push origin +master Enumerating objects: 9, done. Counting objects: 100% (9/9), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 557 bytes | 557.00 KiB/s, done. Total 5 (delta 4), reused 0 (delta 0), pack-reused 0 remote: error: denying non-fast-forward refs/heads/master (you should pull first) To ssh://sourceware.org/git/valgrind.git/ ! [remote rejected] master -> master (non-fast-forward) error: failed to push some refs to 'ssh://sourceware.org/git/valgrind.git/' ---------------------------------------------------------------------- Does that mean that my only option is to revert that patch? Thanks, Bart. |
|
From: Mark W. <ma...@kl...> - 2022-12-25 00:33:48
|
Hi Bart, On Sat, Dec 24, 2022 at 11:37:34PM +0000, Bart Van Assche wrote: > https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2bd7f7042125c99326ffa21c52f368f0721040ca > > commit 2bd7f7042125c99326ffa21c52f368f0721040ca > Author: Bart Van Assche <bva...@ac...> > Date: Mon Jun 20 12:46:40 2022 -0700 > > syscall Could you explain this commit a bit more? It seems to have broken the build on at least debian-i386: In file included from scalar.c:4: scalar.c: In function ‘main’: scalar.c:1272:7: error: ‘__NR_sys_kexec_load’ undeclared (first use in this function) 1272 | GO(__NR_sys_kexec_load, "ni"); | ^~~~~~~~~~~~~~~~~~~ scalar.h:21:20: note: in definition of macro ‘GO’ 21 | __NR_xxx, #__NR_xxx, s); | ^~~~~~~~ scalar.c:1272:7: note: each undeclared identifier is reported only once for each function it appears in 1272 | GO(__NR_sys_kexec_load, "ni"); | ^~~~~~~~~~~~~~~~~~~ scalar.h:21:20: note: in definition of macro ‘GO’ 21 | __NR_xxx, #__NR_xxx, s); | ^~~~~~~~ make[5]: *** [Makefile:755: scalar.o] Error 1 Thanks, Mark > Diff: > --- > memcheck/tests/arm64-linux/scalar.h | 8 +------- > memcheck/tests/x86-linux/scalar.h | 7 +------ > 2 files changed, 2 insertions(+), 13 deletions(-) > > diff --git a/memcheck/tests/arm64-linux/scalar.h b/memcheck/tests/arm64-linux/scalar.h > index 9008816d6e..3dbfa79673 100644 > --- a/memcheck/tests/arm64-linux/scalar.h > +++ b/memcheck/tests/arm64-linux/scalar.h > @@ -1,6 +1,3 @@ > -/* This is the arm64 variant of memcheck/tests/x86-linux/scalar.h */ > -#include "../../../include/vki/vki-scnums-arm64-linux.h" > - > #include <assert.h> > #include <errno.h> > #include <fcntl.h> > @@ -11,10 +8,7 @@ > #include <sys/ptrace.h> > #include <sys/types.h> > #include <sys/mman.h> > - > -// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to > -// declare this ourselves. > -extern long int syscall (long int __sysno, ...) __THROW; > +#include <unistd.h> > > // Thorough syscall scalar arg checking. Also serves as thorough checking > // for (very) basic syscall use. Generally not trying to do anything > diff --git a/memcheck/tests/x86-linux/scalar.h b/memcheck/tests/x86-linux/scalar.h > index ef28b03550..3dbfa79673 100644 > --- a/memcheck/tests/x86-linux/scalar.h > +++ b/memcheck/tests/x86-linux/scalar.h > @@ -1,5 +1,3 @@ > -#include "../../../include/vki/vki-scnums-x86-linux.h" > - > #include <assert.h> > #include <errno.h> > #include <fcntl.h> > @@ -10,10 +8,7 @@ > #include <sys/ptrace.h> > #include <sys/types.h> > #include <sys/mman.h> > - > -// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to > -// declare this ourselves. > -extern long int syscall (long int __sysno, ...) __THROW; > +#include <unistd.h> > > // Thorough syscall scalar arg checking. Also serves as thorough checking > // for (very) basic syscall use. Generally not trying to do anything > > > _______________________________________________ > Valgrind-developers mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-developers |
|
From: Bart V. A. <bva...@so...> - 2022-12-24 23:37:53
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=72b556ab15f120d6ffe5eecaed2f0e2c3f9dc975 commit 72b556ab15f120d6ffe5eecaed2f0e2c3f9dc975 Author: Bart Van Assche <bva...@ac...> Date: Sat Dec 24 14:43:40 2022 -0800 drd: Improve barrier support Make test drd/tests/pth_barrier_thr_cr pass on Fedora 38. Diff: --- NEWS | 1 + drd/drd_barrier.c | 19 ------------------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 4dd33a364e..e1befb56f5 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 351857 confusing error message about valid command line option 444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition. 444488 Use glibc.pthread.stack_cache_size tunable +444568 drd/tests/pth_barrier_thr_cr fails on Fedora 38 459476 vgdb: allow address reuse to avoid "address already in use" errorsuse" errors 462830 WARNING: unhandled amd64-freebsd syscall: 474 463027 broken check for MPX instruction support in assembler diff --git a/drd/drd_barrier.c b/drd/drd_barrier.c index 4602837244..0d6d2136ae 100644 --- a/drd/drd_barrier.c +++ b/drd/drd_barrier.c @@ -431,25 +431,6 @@ void DRD_(barrier_post_wait)(const DrdThreadId tid, const Addr barrier, oset = p->oset[p->post_iteration & 1]; q = VG_(OSetGen_Lookup)(oset, &word_tid); - if (p->pre_iteration - p->post_iteration > 1) { - BarrierErrInfo bei = { DRD_(thread_get_running_tid)(), p->a1, 0, 0 }; - VG_(maybe_record_error)(VG_(get_running_tid)(), - BarrierErr, - VG_(get_IP)(VG_(get_running_tid)()), - "Number of concurrent pthread_barrier_wait()" - " calls exceeds the barrier count", - &bei); - } else if (q == NULL) { - BarrierErrInfo bei = { DRD_(thread_get_running_tid)(), p->a1, 0, 0 }; - VG_(maybe_record_error)(VG_(get_running_tid)(), - BarrierErr, - VG_(get_IP)(VG_(get_running_tid)()), - "Error in barrier implementation" - " -- barrier_wait() started before" - " barrier_destroy() and finished after" - " barrier_destroy()", - &bei); - } if (q == NULL) { q = VG_(OSetGen_AllocNode)(oset, sizeof(*q)); DRD_(barrier_thread_initialize)(q, tid); |
|
From: Bart V. A. <bva...@so...> - 2022-12-24 23:37:45
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2bd7f7042125c99326ffa21c52f368f0721040ca commit 2bd7f7042125c99326ffa21c52f368f0721040ca Author: Bart Van Assche <bva...@ac...> Date: Mon Jun 20 12:46:40 2022 -0700 syscall Diff: --- memcheck/tests/arm64-linux/scalar.h | 8 +------- memcheck/tests/x86-linux/scalar.h | 7 +------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/memcheck/tests/arm64-linux/scalar.h b/memcheck/tests/arm64-linux/scalar.h index 9008816d6e..3dbfa79673 100644 --- a/memcheck/tests/arm64-linux/scalar.h +++ b/memcheck/tests/arm64-linux/scalar.h @@ -1,6 +1,3 @@ -/* This is the arm64 variant of memcheck/tests/x86-linux/scalar.h */ -#include "../../../include/vki/vki-scnums-arm64-linux.h" - #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -11,10 +8,7 @@ #include <sys/ptrace.h> #include <sys/types.h> #include <sys/mman.h> - -// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to -// declare this ourselves. -extern long int syscall (long int __sysno, ...) __THROW; +#include <unistd.h> // Thorough syscall scalar arg checking. Also serves as thorough checking // for (very) basic syscall use. Generally not trying to do anything diff --git a/memcheck/tests/x86-linux/scalar.h b/memcheck/tests/x86-linux/scalar.h index ef28b03550..3dbfa79673 100644 --- a/memcheck/tests/x86-linux/scalar.h +++ b/memcheck/tests/x86-linux/scalar.h @@ -1,5 +1,3 @@ -#include "../../../include/vki/vki-scnums-x86-linux.h" - #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -10,10 +8,7 @@ #include <sys/ptrace.h> #include <sys/types.h> #include <sys/mman.h> - -// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to -// declare this ourselves. -extern long int syscall (long int __sysno, ...) __THROW; +#include <unistd.h> // Thorough syscall scalar arg checking. Also serves as thorough checking // for (very) basic syscall use. Generally not trying to do anything |
|
From: Paul F. <pa...@so...> - 2022-12-23 15:53:51
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2de91d914cc5ed4ed7ea8e70d5e06c46e991f39f commit 2de91d914cc5ed4ed7ea8e70d5e06c46e991f39f Author: Paul Floyd <pj...@wa...> Date: Fri Dec 23 16:49:20 2022 +0100 Bug 444488 - Use glibc.pthread.stack_cache_size tunable Try to use GLIBC_TUNABLES to disable the pthread stack cache. Diff: --- NEWS | 1 + coregrind/m_clientstate.c | 2 ++ coregrind/m_initimg/initimg-linux.c | 61 +++++++++++++++++++++++++++++-------- coregrind/m_redir.c | 19 +++++++++++- coregrind/m_scheduler/scheduler.c | 32 +++++++++++++++++-- coregrind/pub_core_clientstate.h | 2 ++ 6 files changed, 102 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index c9376dcca9..4dd33a364e 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 170510 Don't warn about ioctl of size 0 without direction hint 351857 confusing error message about valid command line option 444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition. +444488 Use glibc.pthread.stack_cache_size tunable 459476 vgdb: allow address reuse to avoid "address already in use" errorsuse" errors 462830 WARNING: unhandled amd64-freebsd syscall: 474 463027 broken check for MPX instruction support in assembler diff --git a/coregrind/m_clientstate.c b/coregrind/m_clientstate.c index 23c846d6b8..93662dcb3d 100644 --- a/coregrind/m_clientstate.c +++ b/coregrind/m_clientstate.c @@ -121,6 +121,8 @@ Addr VG_(client__dl_sysinfo_int80) = 0; in nptl/allocatestack.c */ SizeT* VG_(client__stack_cache_actsize__addr) = 0; +client__gnu_get_libc_version_type VG_(client__gnu_get_libc_version_addr) = 0; + #if defined(VGO_solaris) /* Address of variable vg_vfork_fildes in vgpreload_core.so.0 (vg_preloaded.c). */ diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index 48df8c1225..4da9a8b976 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -120,19 +120,19 @@ static void load_client ( /*MOD*/ExeInfo* info, If this needs to handle any more variables it should be hacked into something table driven. The copy is VG_(malloc)'d space. */ -static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) +static HChar** setup_client_env ( HChar** origenv, const HChar* toolname, Bool use_stack_cache_tunable) { vg_assert(origenv); vg_assert(toolname); - const HChar* preload_core = "vgpreload_core"; - const HChar* ld_preload = "LD_PRELOAD="; - const HChar* v_launcher = VALGRIND_LAUNCHER "="; - Int ld_preload_len = VG_(strlen)( ld_preload ); - Int v_launcher_len = VG_(strlen)( v_launcher ); - Bool ld_preload_done = False; - Int vglib_len = VG_(strlen)(VG_(libdir)); - Bool debug = False; + const HChar* preload_core = "vgpreload_core"; + const HChar* ld_preload = "LD_PRELOAD="; + const HChar* v_launcher = VALGRIND_LAUNCHER "="; + Int ld_preload_len = VG_(strlen)( ld_preload ); + Int v_launcher_len = VG_(strlen)( v_launcher ); + Bool ld_preload_done = False; + Int vglib_len = VG_(strlen)(VG_(libdir)); + Bool debug = False; HChar** cpp; HChar** ret; @@ -175,9 +175,10 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) if (debug) VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp); } - /* Allocate a new space */ + /* Allocate a new space + * Size is envc + 1 new entry + maybe one for GLIBC_TUNABLES + NULL */ ret = VG_(malloc) ("initimg-linux.sce.3", - sizeof(HChar *) * (envc+1+1)); /* 1 new entry + NULL */ + sizeof(HChar *) * (envc+1+1+(use_stack_cache_tunable ? 1 : 0))); /* copy it over */ for (cpp = ret; *origenv; ) { @@ -201,6 +202,18 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) ld_preload_done = True; } + if (use_stack_cache_tunable) { + /* overwrite value found with zeroes */ + const HChar* search_string = "glibc.pthread.stack_cache_size="; + HChar* val; + if ((val = VG_(strstr)(*cpp, search_string))) { + val += VG_(strlen)(search_string); + while (*val != '\0' && *val != ':') { + *val++ = '0'; + } + use_stack_cache_tunable = False; + } + } if (debug) VG_(printf)("XXXXXXXXX: MASH %s\n", *cpp); } @@ -215,6 +228,10 @@ static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) if (debug) VG_(printf)("XXXXXXXXX: ADD %s\n", cp); } + if (use_stack_cache_tunable) { + ret[envc++] = VG_(strdup)("initimg-linux.sce.6", "GLIBC_TUNABLES=glibc.pthread.stack_cache_size=0"); + } + /* ret[0 .. envc-1] is live now. */ /* Find and remove a binding for VALGRIND_LAUNCHER. */ for (i = 0; i < envc; i++) @@ -1004,6 +1021,26 @@ static void setup_client_dataseg ( SizeT max_size ) vg_assert(sr_Res(sres) == anon_start); } +/* + * In glibc 2.34 we need to use the TUNABLE mechanism to + * disable stack cache when --sim-hints=no-nptl-pthread-stackcache + * is specified. This needs to be done in the same manner + * as LD_PRELOAD. + * + * See https://bugs.kde.org/show_bug.cgi?id=444488 + */ +static Bool need_stack_cache_tunable(HChar** argv) +{ + while (argv && *argv) { + if (VG_(strncmp)(*argv, "--sim-hints=", VG_(strlen)("--sim-hints=")) == 0) { + if (VG_(strstr)(*argv, "no-nptl-pthread-stackcache")) { + return True; + } + } + ++argv; + } + return False; +} /*====================================================================*/ /*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/ @@ -1046,7 +1083,7 @@ IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, // p: get_helprequest_and_toolname [for toolname] //-------------------------------------------------------------- VG_(debugLog)(1, "initimg", "Setup client env\n"); - env = setup_client_env(iicii.envp, iicii.toolname); + env = setup_client_env(iicii.envp, iicii.toolname, need_stack_cache_tunable(iicii.argv)); //-------------------------------------------------------------- // Setup client stack, eip, and VG_(client_arg[cv]) diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index 66a3c0c4f9..37c67f4c13 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -405,6 +405,8 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) const HChar* const pthread_soname = "libpthread.so.0"; const HChar* const pthread_stack_cache_actsize_varname = "stack_cache_actsize"; + const HChar* const libc_soname = "libc.so.6"; + const HChar* const libc_gnu_get_libc_version_funcname = "gnu_get_libc_version"; #if defined(VGO_solaris) Bool vg_vfork_fildes_var_search = False; const HChar* const vg_preload_core_soname = "vgpreload_core.so.0"; @@ -506,7 +508,8 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) dehacktivate_pthread_stack_cache_var_search = SimHintiS(SimHint_no_nptl_pthread_stackcache, VG_(clo_sim_hints)) - && 0 == VG_(strcmp)(newdi_soname, pthread_soname); + && (0 == VG_(strcmp)(newdi_soname, pthread_soname) || + 0 == VG_(strcmp)(newdi_soname, libc_soname)); #if defined(VGO_solaris) vg_vfork_fildes_var_search = @@ -529,6 +532,20 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) &demangled_sopatt, &demangled_fnpatt, &isWrap, &becTag, &becPrio ); + + if (isText && dehacktivate_pthread_stack_cache_var_search) { + if (0 == VG_(strcmp)(*names, libc_gnu_get_libc_version_funcname)) { + if ( VG_(clo_verbosity) > 1 ) { + VG_(message)( Vg_DebugMsg, + "deactivate nptl pthread stackcache via tunable:" + " found symbol %s at addr %p\n", + *names, (void*) sym_avmas.main); + } + VG_(client__gnu_get_libc_version_addr) = (client__gnu_get_libc_version_type) sym_avmas.main; + dehacktivate_pthread_stack_cache_var_search = False; + } + } + /* ignore data symbols */ if (!isText) { /* But search for dehacktivate stack cache var if needed. */ diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index 00cc0c6889..027560c2ad 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -1348,8 +1348,36 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid ) to be added without risk of overflow. */ } } else { - VG_(debugLog)(0,"sched", - "WARNING: pthread stack cache cannot be disabled!\n"); + /* + * glibc 2.34 no longer has stack_cache_actsize as a visible variable + * so we switch to using the GLIBC_TUNABLES env var. Processing for that + * is done in initimg-linux.c / setup_client_env for all glibc + * + * If we don't detect stack_cache_actsize we want to be able to tell + * whether it is an unexpected error or if it is no longer there. + * In the latter case we don't print a warning. + */ + Bool print_warning = True; + if (VG_(client__gnu_get_libc_version_addr) != NULL) { + const HChar* gnu_libc_version = VG_(client__gnu_get_libc_version_addr)(); + if (gnu_libc_version != NULL) { + HChar* glibc_version_tok = VG_(strdup)("scheduler.1", gnu_libc_version); + const HChar* str_major = VG_(strtok)(glibc_version_tok, "."); + Long major = VG_(strtoll10)(str_major, NULL); + const HChar* str_minor = VG_(strtok)(NULL, "."); + Long minor = VG_(strtoll10)(str_minor, NULL); + if (major >= 2 && minor >= 34) { + print_warning = False; + } + VG_(free)(glibc_version_tok); + } + } else { + + } + if (print_warning) { + VG_(debugLog)(0,"sched", + "WARNING: pthread stack cache cannot be disabled!\n"); + } VG_(clo_sim_hints) &= ~SimHint2S(SimHint_no_nptl_pthread_stackcache); /* Remove SimHint_no_nptl_pthread_stackcache from VG_(clo_sim_hints) to avoid having a msg for all following threads. */ diff --git a/coregrind/pub_core_clientstate.h b/coregrind/pub_core_clientstate.h index fb83a9ea23..824ce1e05f 100644 --- a/coregrind/pub_core_clientstate.h +++ b/coregrind/pub_core_clientstate.h @@ -118,6 +118,8 @@ extern Addr VG_(get_initial_client_SP)(void); It would be much cleaner to have a documented and supported way to disable the pthread stack cache. */ extern SizeT* VG_(client__stack_cache_actsize__addr); +typedef const HChar* (*client__gnu_get_libc_version_type)(void); +extern client__gnu_get_libc_version_type VG_(client__gnu_get_libc_version_addr); #if defined(VGO_solaris) /* Address of variable vg_vfork_fildes in vgpreload_core.so.0 |
|
From: Philippe W. <phi...@so...> - 2022-12-23 15:15:52
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=7e03a15d8d4f9a6fb50b59353a13f93ed0bafc3c commit 7e03a15d8d4f9a6fb50b59353a13f93ed0bafc3c Author: Philippe Waroquiers <phi...@sk...> Date: Fri Dec 23 16:12:53 2022 +0100 Pass a dummy process_option_state for dynamic options The process_option_state is functionally needed during initial parsing of CLO options. When later changing them, only changing the CLO itself is good enough. But the processing of option needs to have a state. Diff: --- coregrind/m_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coregrind/m_main.c b/coregrind/m_main.c index f02a8b0eb5..2b4a8748ff 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -889,9 +889,9 @@ static void process_option (Clo_Mode mode, void VG_(process_dynamic_option) (Clo_Mode mode, HChar *value) { - process_option (mode, value, NULL); - // This is not supposed to change values in process_option_state, - // so we can give a NULL. + struct process_option_state dummy; + process_option (mode, value, &dummy); + // No need to handle a process_option_state once valgrind has started. } /* Peer at previously set up VG_(args_for_valgrind) and do some |
|
From: Paul F. <pa...@so...> - 2022-12-23 13:51:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=316282cd3b357fe94cac466754adb42c17fad7d2 commit 316282cd3b357fe94cac466754adb42c17fad7d2 Author: Paul Floyd <pj...@wa...> Date: Fri Dec 23 14:49:39 2022 +0100 Bug 463027 - broken check for MPX instruction support in assembler Diff: --- NEWS | 1 + configure.ac | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index d777d9160c..c9376dcca9 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition. 459476 vgdb: allow address reuse to avoid "address already in use" errorsuse" errors 462830 WARNING: unhandled amd64-freebsd syscall: 474 +463027 broken check for MPX instruction support in assembler To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/configure.ac b/configure.ac index 41047dc2c6..5ae9377119 100755 --- a/configure.ac +++ b/configure.ac @@ -3410,9 +3410,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ asm ("bndmov %bnd0,(%rsp)"); asm ("bndldx 3(%rbx,%rdx), %bnd2"); asm ("bnd call foo\n" - bnd jmp end\n" - foo: bnd ret\n" - end: nop"); + "bnd jmp end\n" + "foo: bnd ret\n" + "end: nop"); } while (0) ]])], [ ac_have_as_mpx=yes |