You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
1
(8) |
2
(11) |
3
(21) |
4
(15) |
5
(10) |
|
6
(7) |
7
(7) |
8
(5) |
9
(7) |
10
(5) |
11
(1) |
12
(21) |
|
13
(8) |
14
(17) |
15
(6) |
16
(10) |
17
(7) |
18
(6) |
19
(15) |
|
20
(12) |
21
(16) |
22
(25) |
23
(14) |
24
(10) |
25
(7) |
26
(6) |
|
27
(34) |
28
(13) |
29
(10) |
30
(8) |
|
|
|
|
From: Tom H. <th...@cy...> - 2004-06-12 19:47:27
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> It seems that there should be an associated configure script update
> since this CVS update causes the following compilation errors:
Have you rerun autogen.sh to update configure?
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Bob F. <bfr...@si...> - 2004-06-12 18:40:55
|
A component is missing after 'make dist': Index: Makefile.am =================================================================== RCS file: /home/kde/valgrind/coregrind/Makefile.am,v retrieving revision 1.71 diff -u -r1.71 Makefile.am --- Makefile.am 16 Apr 2004 23:02:28 -0000 1.71 +++ Makefile.am 12 Jun 2004 18:34:54 -0000 @@ -23,7 +23,7 @@ EXTRA_DIST = \ vg_libpthread.vs valgrind.vs \ - gen_toolint.pl toolfuncs.def \ + gen_intercepts.pl gen_toolint.pl toolfuncs.def \ vg_replace_malloc.c BUILT_SOURCES = vg_toolint.c vg_toolint.h |
|
From: Bob F. <bfr...@si...> - 2004-06-12 18:33:38
|
It seems that there should be an associated configure script update
since this CVS update causes the following compilation errors:
vg_libpthread.c:182: error: conflicting types for
`__pthread_unwind_buf_t'
/usr/include/pthread.h:431: error: previous declaration of
`__pthread_unwind_buf_t'
vg_libpthread.c:972: error: conflicting types for
`__pthread_register_cancel'
/usr/include/pthread.h:581: error: previous declaration of
`__pthread_register_cancel'
vg_libpthread.c:1013: error: conflicting types for
`__pthread_unregister_cancel'
/usr/include/pthread.h:592: error: previous declaration of
`__pthread_unregister_cancel'
vg_libpthread.c:1081: error: conflicting types for
`__pthread_unwind_next'
/usr/include/pthread.h:636: error: previous declaration of
`__pthread_unwind_next'
Bob
On Sat, 12 Jun 2004, Tom Hughes wrote:
> CVS commit by thughes:
>
> Fixed the NPTL cleanup handler support to try and make sure it will
> compile on systems with NPTL header files.
>
>
> M +1 -0 configure.in 1.110
> M +1 -7 coregrind/vg_include.h 1.193
> M +41 -21 coregrind/vg_libpthread.c 1.155
>
>
> --- valgrind/configure.in #1.109:1.110
> @@ -339,4 +339,5 @@
> AC_TYPE_SIZE_T
> AC_HEADER_TIME
> +AC_CHECK_TYPES(__pthread_unwind_buf_t,,,[#include <pthread.h>])
>
> # Checks for library functions.
>
> --- valgrind/coregrind/vg_include.h #1.192:1.193
> @@ -714,10 +714,4 @@ typedef
> CleanupType;
>
> -/* A thread unwind buffer */
> -typedef
> - struct {
> - jmp_buf jb;
> - } ThreadUnwindBuf;
> -
> /* An entry in a threads's cleanup stack. */
> typedef
> @@ -730,5 +724,5 @@ typedef
> } function;
> struct {
> - ThreadUnwindBuf *ub;
> + void *ub;
> int ctype;
> } longjmp;
>
> --- valgrind/coregrind/vg_libpthread.c #1.154:1.155
> @@ -165,4 +165,23 @@ typedef struct
> x = 0; // ensure we don't accidentally use x again!
>
> +
> +/* ---------------------------------------------------------------------
> + Our own definition of types that only exist in NPTL.
> + ------------------------------------------------------------------ */
> +
> +#ifndef HAVE___PTHREAD_UNWIND_BUF_T
> +
> +typedef struct
> +{
> + struct
> + {
> + jmp_buf __cancel_jmp_buf;
> + int __mask_was_saved;
> + } __cancel_jmp_buf[1];
> + void *__pad[4];
> +} __pthread_unwind_buf_t __attribute__ ((__aligned__));
> +
> +#endif
> +
> /* ---------------------------------------------------------------------
> Forwardses.
> @@ -778,5 +797,5 @@ void thread_wrapper ( NewThreadInfo* inf
> void* arg;
> void* ret_val;
> - ThreadUnwindBuf ub;
> + __pthread_unwind_buf_t ub;
>
> attr__detachstate = info->attr__detachstate;
> @@ -834,5 +853,5 @@ void thread_wrapper ( NewThreadInfo* inf
>
>
> - if (setjmp(ub.jb) == 0) {
> + if (setjmp(ub.__cancel_jmp_buf[0].__cancel_jmp_buf) == 0) {
> CleanupEntry cu;
> int res;
> @@ -950,5 +969,5 @@ void _pthread_cleanup_pop_restore (struc
>
> __attribute ((regparm (1)))
> -void __pthread_register_cancel (ThreadUnwindBuf *ub)
> +void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
> {
> int res;
> @@ -956,5 +975,5 @@ void __pthread_register_cancel (ThreadUn
> ensure_valgrind("__pthread_register_cancel");
> cu.type = VgCt_Longjmp;
> - cu.data.longjmp.ub = ub;
> + cu.data.longjmp.ub = __buf;
> VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
> VG_USERREQ__CLEANUP_PUSH,
> @@ -965,5 +984,5 @@ void __pthread_register_cancel (ThreadUn
>
> __attribute ((regparm (1)))
> -void __pthread_register_cancel_defer (ThreadUnwindBuf *ub)
> +void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
> {
> /* As __pthread_register cancel, but save the thread's original
> @@ -973,5 +992,5 @@ void __pthread_register_cancel_defer (Th
> ensure_valgrind("__pthread_register_cancel_defer");
> cu.type = VgCt_Longjmp;
> - cu.data.longjmp.ub = ub;
> + cu.data.longjmp.ub = __buf;
> /* Set to Deferred, and save the old cancellation type. */
> my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
> @@ -991,5 +1010,5 @@ void __pthread_register_cancel_defer (Th
>
> __attribute ((regparm (1)))
> -void __pthread_unregister_cancel (ThreadUnwindBuf *ub)
> +void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
> {
> int res;
> @@ -1001,5 +1020,5 @@ void __pthread_unregister_cancel (Thread
> &cu, 0, 0, 0);
> my_assert(cu.type == VgCt_Longjmp);
> - my_assert(cu.data.longjmp.ub == ub);
> + my_assert(cu.data.longjmp.ub == __buf);
> return;
> }
> @@ -1007,5 +1026,5 @@ void __pthread_unregister_cancel (Thread
>
> __attribute ((regparm (1)))
> -void __pthread_unregister_restore (ThreadUnwindBuf *ub)
> +void __pthread_unregister_restore (__pthread_unwind_buf_t *__buf)
> {
> int res;
> @@ -1020,5 +1039,5 @@ void __pthread_unregister_restore (Threa
> &cu, 0, 0, 0);
> my_assert(cu.type == VgCt_Longjmp);
> - my_assert(cu.data.longjmp.ub == ub);
> + my_assert(cu.data.longjmp.ub == __buf);
> /* Restore the original cancellation type. */
> my_assert(cu.data.longjmp.ctype == PTHREAD_CANCEL_DEFERRED
> @@ -1035,5 +1054,5 @@ void __pthread_unregister_restore (Threa
> __attribute ((regparm (1)))
> __attribute ((__noreturn__))
> -void __pthread_unwind (ThreadUnwindBuf *ub)
> +void __pthread_unwind (__pthread_unwind_buf_t *__buf)
> {
> int res;
> @@ -1050,6 +1069,7 @@ void __pthread_unwind (ThreadUnwindBuf *
> }
> my_assert(cu.type == VgCt_Longjmp);
> - my_assert(ub == NULL || ub == cu.data.longjmp.ub);
> - longjmp(cu.data.longjmp.ub->jb, 1);
> + my_assert(__buf == NULL || __buf == cu.data.longjmp.ub);
> + __buf = cu.data.longjmp.ub;
> + longjmp(__buf->__cancel_jmp_buf[0].__cancel_jmp_buf, 1);
> /* NOTREACHED */
> }
> @@ -1058,5 +1078,5 @@ void __pthread_unwind (ThreadUnwindBuf *
> __attribute ((regparm (1)))
> __attribute ((__noreturn__))
> -void __pthread_unwind_next (ThreadUnwindBuf *ub)
> +void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
> {
> __pthread_unwind(NULL);
>
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by the new InstallShield X.
>> From Windows to Linux, servers to mobile, InstallShield X is the
> one installation-authoring solution that does it all. Learn more and
> evaluate today! http://www.installshield.com/Dev2Dev/0504
> _______________________________________________
> Valgrind-developers mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
>
======================================
Bob Friesenhahn
bfr...@si...
http://www.simplesystems.org/users/bfriesen
|
|
From: Tom H. <th...@cy...> - 2004-06-12 17:25:30
|
CVS commit by thughes:
Fixed the NPTL cleanup handler support to try and make sure it will
compile on systems with NPTL header files.
M +1 -0 configure.in 1.110
M +1 -7 coregrind/vg_include.h 1.193
M +41 -21 coregrind/vg_libpthread.c 1.155
--- valgrind/configure.in #1.109:1.110
@@ -339,4 +339,5 @@
AC_TYPE_SIZE_T
AC_HEADER_TIME
+AC_CHECK_TYPES(__pthread_unwind_buf_t,,,[#include <pthread.h>])
# Checks for library functions.
--- valgrind/coregrind/vg_include.h #1.192:1.193
@@ -714,10 +714,4 @@ typedef
CleanupType;
-/* A thread unwind buffer */
-typedef
- struct {
- jmp_buf jb;
- } ThreadUnwindBuf;
-
/* An entry in a threads's cleanup stack. */
typedef
@@ -730,5 +724,5 @@ typedef
} function;
struct {
- ThreadUnwindBuf *ub;
+ void *ub;
int ctype;
} longjmp;
--- valgrind/coregrind/vg_libpthread.c #1.154:1.155
@@ -165,4 +165,23 @@ typedef struct
x = 0; // ensure we don't accidentally use x again!
+
+/* ---------------------------------------------------------------------
+ Our own definition of types that only exist in NPTL.
+ ------------------------------------------------------------------ */
+
+#ifndef HAVE___PTHREAD_UNWIND_BUF_T
+
+typedef struct
+{
+ struct
+ {
+ jmp_buf __cancel_jmp_buf;
+ int __mask_was_saved;
+ } __cancel_jmp_buf[1];
+ void *__pad[4];
+} __pthread_unwind_buf_t __attribute__ ((__aligned__));
+
+#endif
+
/* ---------------------------------------------------------------------
Forwardses.
@@ -778,5 +797,5 @@ void thread_wrapper ( NewThreadInfo* inf
void* arg;
void* ret_val;
- ThreadUnwindBuf ub;
+ __pthread_unwind_buf_t ub;
attr__detachstate = info->attr__detachstate;
@@ -834,5 +853,5 @@ void thread_wrapper ( NewThreadInfo* inf
- if (setjmp(ub.jb) == 0) {
+ if (setjmp(ub.__cancel_jmp_buf[0].__cancel_jmp_buf) == 0) {
CleanupEntry cu;
int res;
@@ -950,5 +969,5 @@ void _pthread_cleanup_pop_restore (struc
__attribute ((regparm (1)))
-void __pthread_register_cancel (ThreadUnwindBuf *ub)
+void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
{
int res;
@@ -956,5 +975,5 @@ void __pthread_register_cancel (ThreadUn
ensure_valgrind("__pthread_register_cancel");
cu.type = VgCt_Longjmp;
- cu.data.longjmp.ub = ub;
+ cu.data.longjmp.ub = __buf;
VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
VG_USERREQ__CLEANUP_PUSH,
@@ -965,5 +984,5 @@ void __pthread_register_cancel (ThreadUn
__attribute ((regparm (1)))
-void __pthread_register_cancel_defer (ThreadUnwindBuf *ub)
+void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
{
/* As __pthread_register cancel, but save the thread's original
@@ -973,5 +992,5 @@ void __pthread_register_cancel_defer (Th
ensure_valgrind("__pthread_register_cancel_defer");
cu.type = VgCt_Longjmp;
- cu.data.longjmp.ub = ub;
+ cu.data.longjmp.ub = __buf;
/* Set to Deferred, and save the old cancellation type. */
my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
@@ -991,5 +1010,5 @@ void __pthread_register_cancel_defer (Th
__attribute ((regparm (1)))
-void __pthread_unregister_cancel (ThreadUnwindBuf *ub)
+void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
{
int res;
@@ -1001,5 +1020,5 @@ void __pthread_unregister_cancel (Thread
&cu, 0, 0, 0);
my_assert(cu.type == VgCt_Longjmp);
- my_assert(cu.data.longjmp.ub == ub);
+ my_assert(cu.data.longjmp.ub == __buf);
return;
}
@@ -1007,5 +1026,5 @@ void __pthread_unregister_cancel (Thread
__attribute ((regparm (1)))
-void __pthread_unregister_restore (ThreadUnwindBuf *ub)
+void __pthread_unregister_restore (__pthread_unwind_buf_t *__buf)
{
int res;
@@ -1020,5 +1039,5 @@ void __pthread_unregister_restore (Threa
&cu, 0, 0, 0);
my_assert(cu.type == VgCt_Longjmp);
- my_assert(cu.data.longjmp.ub == ub);
+ my_assert(cu.data.longjmp.ub == __buf);
/* Restore the original cancellation type. */
my_assert(cu.data.longjmp.ctype == PTHREAD_CANCEL_DEFERRED
@@ -1035,5 +1054,5 @@ void __pthread_unregister_restore (Threa
__attribute ((regparm (1)))
__attribute ((__noreturn__))
-void __pthread_unwind (ThreadUnwindBuf *ub)
+void __pthread_unwind (__pthread_unwind_buf_t *__buf)
{
int res;
@@ -1050,6 +1069,7 @@ void __pthread_unwind (ThreadUnwindBuf *
}
my_assert(cu.type == VgCt_Longjmp);
- my_assert(ub == NULL || ub == cu.data.longjmp.ub);
- longjmp(cu.data.longjmp.ub->jb, 1);
+ my_assert(__buf == NULL || __buf == cu.data.longjmp.ub);
+ __buf = cu.data.longjmp.ub;
+ longjmp(__buf->__cancel_jmp_buf[0].__cancel_jmp_buf, 1);
/* NOTREACHED */
}
@@ -1058,5 +1078,5 @@ void __pthread_unwind (ThreadUnwindBuf *
__attribute ((regparm (1)))
__attribute ((__noreturn__))
-void __pthread_unwind_next (ThreadUnwindBuf *ub)
+void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
{
__pthread_unwind(NULL);
|
|
From: Tom H. <th...@cy...> - 2004-06-12 17:20:47
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> On Sat, 12 Jun 2004, Tom Hughes wrote:
> >> Unfortunately I did not record the exact assertion message and don't
> >> have an unmodified valgrind immediately available. However, the
> >> assertion was from valgrind and was due to support for timer_create
> >> not being implemented. It said not to "panic" since it is easy to add
> >> system calls to valgrind.
> >
> > Was it this message?
> >
> > --9067-- WARNING: unhandled syscall: 266
> > --9067-- Do not panic. You may be able to fix this easily.
> > --9067-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
> >
> > If so then that isn't an assertion, it's just a warning and valgrind
> > will happily carry on return ENOSYS to the application code.
>
> Yes, it was this message. I must have been confused. However, the
> program did immediately crash after this point. It was probably our
> own assertion because timer_create returned an error.
Are you calling the timer_create system call directly then?
Only if you're calling the timer_create function in glibc (actually
in librt) then glibc should hide the error from you anyway.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Bob F. <bfr...@si...> - 2004-06-12 16:58:55
|
On Sat, 12 Jun 2004, Tom Hughes wrote: >> Unfortunately I did not record the exact assertion message and don't >> have an unmodified valgrind immediately available. However, the >> assertion was from valgrind and was due to support for timer_create >> not being implemented. It said not to "panic" since it is easy to add >> system calls to valgrind. > > Was it this message? > > --9067-- WARNING: unhandled syscall: 266 > --9067-- Do not panic. You may be able to fix this easily. > --9067-- Read the file README_MISSING_SYSCALL_OR_IOCTL. > > If so then that isn't an assertion, it's just a warning and valgrind > will happily carry on return ENOSYS to the application code. Yes, it was this message. I must have been confused. However, the program did immediately crash after this point. It was probably our own assertion because timer_create returned an error. Clearly more investigation on my part is necessary. Bob ====================================== Bob Friesenhahn bfr...@si... http://www.simplesystems.org/users/bfriesen |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:51:38
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> On Sat, 12 Jun 2004, Tom Hughes wrote:
>
> > What was the assertion? I found that I just got a warning about
> > system call 266 not being implemented (that's clock_getres) and it
> > then fell back to the old technique that was used with 2.4 kernels
> > that didn't have the timer system calls.
>
> Unfortunately I did not record the exact assertion message and don't
> have an unmodified valgrind immediately available. However, the
> assertion was from valgrind and was due to support for timer_create
> not being implemented. It said not to "panic" since it is easy to add
> system calls to valgrind.
Was it this message?
--9067-- WARNING: unhandled syscall: 266
--9067-- Do not panic. You may be able to fix this easily.
--9067-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
If so then that isn't an assertion, it's just a warning and valgrind
will happily carry on return ENOSYS to the application code.
> In Linux 2.6.3 timer_create is system call number 259:
Indeed, but librt calls clock_getres to test whether the kernel has
timer support as it is part of the same group of calls. If that fails
with ENOSYS then it uses a different method to implement timer_create
without using the system call.
At least that is how FC2 is behaving for me with a 2.6.5 kernel
and 2.3.3 glibc.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Bob F. <bfr...@si...> - 2004-06-12 16:40:39
|
On Sat, 12 Jun 2004, Tom Hughes wrote: >> >> Surely something must be done in valgrind. Prior to my updates, >> valgrind simply asserted since the timer_* system calls were not >> supported. What must be done to keep valgrind from asserting while >> allowing librt to emulate the real thing? > > What was the assertion? I found that I just got a warning about > system call 266 not being implemented (that's clock_getres) and it > then fell back to the old technique that was used with 2.4 kernels > that didn't have the timer system calls. Unfortunately I did not record the exact assertion message and don't have an unmodified valgrind immediately available. However, the assertion was from valgrind and was due to support for timer_create not being implemented. It said not to "panic" since it is easy to add system calls to valgrind. In Linux 2.6.3 timer_create is system call number 259: #define __NR_timer_create 259 #define __NR_timer_settime (__NR_timer_create+1) #define __NR_timer_gettime (__NR_timer_create+2) #define __NR_timer_getoverrun (__NR_timer_create+3) #define __NR_timer_delete (__NR_timer_create+4) #define __NR_clock_settime (__NR_timer_create+5) #define __NR_clock_gettime (__NR_timer_create+6) #define __NR_clock_getres (__NR_timer_create+7) #define __NR_clock_nanosleep (__NR_timer_create+8) Bob ====================================== Bob Friesenhahn bfr...@si... http://www.simplesystems.org/users/bfriesen |
|
From: Bob F. <bfr...@si...> - 2004-06-12 16:32:07
|
On Sat, 12 Jun 2004, Tom Hughes wrote: > In message <Pin...@sc...> > Bob Friesenhahn <bfr...@si...> wrote: > >> I am still working on properly supporting the timer_* APIs. > > I've been looking at them well following your previous posts. My first > problem was that the librt.so on FC2 wouldn't work until I added support > for NPTL style cleanup handlers to valgrind so I couldn't get as far as > trying to create a timer. I've committed a fix for that now, but I'm > curious as to hw you got it to work. The timer_create option which works with valgrind is notification via signal delivery. The synchronous notification by thread does not work. From what you have discovered, it should be possible for valgrind to convert the SIGEV_THREAD request into a SIGEV_SIGNAL notification. Timer signals are then dispatched to a thread by a valgrind-installed signal handler. The function is roughly similar to what librt is apparently doing. Naturally this would be a bit of work. Perhaps some librt code can be re-used. >> For the timer_delete POST operation I need a way to declare that the >> timer handle is no longer valid. How should that be done? > > Unless you're going to add full scale tracking for timer handles in > the same way that file handles are tracked then you can't. The memory > that holds the handle is still well defined so you shouldn't try and > mark it as undefined, not that you can as it is a scalar argument. Ok. Bob ====================================== Bob Friesenhahn bfr...@si... http://www.simplesystems.org/users/bfriesen |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:30:28
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> On Sat, 12 Jun 2004, Tom Hughes wrote:
>
> > Under valgrind the thread handle is not a pointer, it is a small
> > unique integer, hance the attempt to access a low address.
> >
> > In fact we are better off not implementing the timer system calls
> > for now as librt will take ENOSYS as a trigger to fall back to the
> > old way of doing things with a thread that blocks with a futex for
> > the required length of time and then runs the handler function.
>
> Surely something must be done in valgrind. Prior to my updates,
> valgrind simply asserted since the timer_* system calls were not
> supported. What must be done to keep valgrind from asserting while
> allowing librt to emulate the real thing?
What was the assertion? I found that I just got a warning about
system call 266 not being implemented (that's clock_getres) and it
then fell back to the old technique that was used with 2.4 kernels
that didn't have the timer system calls.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Bob F. <bfr...@si...> - 2004-06-12 16:21:41
|
On Sat, 12 Jun 2004, Tom Hughes wrote: >> >> This crash does not occur without valgrind, however, it is quite >> possible that the related librt/application code is indeed faulty >> since the timer notify method the code is using (SIGEV_THREAD) has not >> been observed (by me) to be working in this kernel. > > I've worked out what is causing this now, and I'm not sure what we > can do about it... > > The basic problem is that the glibc timer_create() implementation > in librt does something tryly horrible. It creates a helper thread > with pthread_create() and then casts the returned thread handle to > a struct pthread and tries to look into it. Pretty gross. > Under valgrind the thread handle is not a pointer, it is a small > unique integer, hance the attempt to access a low address. > > In fact we are better off not implementing the timer system calls > for now as librt will take ENOSYS as a trigger to fall back to the > old way of doing things with a thread that blocks with a futex for > the required length of time and then runs the handler function. Surely something must be done in valgrind. Prior to my updates, valgrind simply asserted since the timer_* system calls were not supported. What must be done to keep valgrind from asserting while allowing librt to emulate the real thing? Bob ====================================== Bob Friesenhahn bfr...@si... http://www.simplesystems.org/users/bfriesen |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:14:26
|
Nightly build on standard ( Red Hat 7.2 ) started at 2004-06-12 03:00:02 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow rcrl: valgrind ./rcrl readline1: valgrind ./readline1 resolv: valgrind ./resolv seg_override: valgrind ./seg_override semlimit: valgrind ./semlimit sha1_test: valgrind ./sha1_test shortpush: valgrind ./shortpush shorts: valgrind ./shorts smc1: valgrind ./smc1 susphello: valgrind ./susphello syscall-restart1: valgrind ./syscall-restart1 syscall-restart2: valgrind ./syscall-restart2 system: valgrind ./system yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 158 tests, 1 stderr failure, 0 stdout failures ================= memcheck/tests/badfree-2trace (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:14:26
|
Nightly build on audi ( Red Hat 9 ) started at 2004-06-12 03:15:02 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert rcrl: valgrind ./rcrl readline1: valgrind ./readline1 resolv: valgrind ./resolv seg_override: valgrind ./seg_override semlimit: valgrind ./semlimit sha1_test: valgrind ./sha1_test shortpush: valgrind ./shortpush shorts: valgrind ./shorts smc1: valgrind ./smc1 susphello: valgrind ./susphello syscall-restart1: valgrind ./syscall-restart1 syscall-restart2: valgrind ./syscall-restart2 system: valgrind ./system yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 158 tests, 0 stderr failures, 0 stdout failures ================= |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:14:26
|
Nightly build on ginetta ( Red Hat 8.0 ) started at 2004-06-12 03:10:03 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow seg_override: valgrind ./seg_override semlimit: valgrind ./semlimit sha1_test: valgrind ./sha1_test shortpush: valgrind ./shortpush shorts: valgrind ./shorts smc1: valgrind ./smc1 susphello: valgrind ./susphello syscall-restart1: valgrind ./syscall-restart1 syscall-restart2: valgrind ./syscall-restart2 system: valgrind ./system yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 158 tests, 4 stderr failures, 0 stdout failures ================= helgrind/tests/deadlock (stderr) helgrind/tests/race (stderr) helgrind/tests/race2 (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:14:26
|
Nightly build on alvis ( Red Hat 7.3 ) started at 2004-06-12 03:05:01 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow sha1_test: valgrind ./sha1_test shortpush: valgrind ./shortpush shorts: valgrind ./shorts smc1: valgrind ./smc1 susphello: valgrind ./susphello syscall-restart1: valgrind ./syscall-restart1 syscall-restart2: valgrind ./syscall-restart2 system: valgrind ./system yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 158 tests, 5 stderr failures, 1 stdout failure ================= memcheck/tests/badfree-2trace (stderr) memcheck/tests/badjump (stderr) memcheck/tests/brk (stderr) memcheck/tests/error_counts (stdout) memcheck/tests/new_nothrow (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:10:20
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> On Fri, 4 Jun 2004, Tom Hughes wrote:
>
> >> The application code executed is:
> >>
> >> struct sigevent event;
> >> memset( &event, 0, sizeof( struct sigevent ) );
> >> event.sigev_notify = SIGEV_THREAD;
> >> event.sigev_notify_function = &timer_thread_handler;
> >> event.sigev_value.sival_ptr = this;
> >> timer_create( CLOCK_REALTIME, &event, &timer_id );
> >>
> >> where timer_thread_handler is a function, and timer_id is part of the
> >> enclosing C++ class.
> >
> > If timer_create is really a system call then how is that function
> > getting invoked - does the kernel invoke it asynchronously like a
> > signal handler? If so then addding support for that system is going
> > to be non-trivial and won't be as simple as adding a wrapper for
> > the call to vg_syscalls.c as you will have to teach valgrind how
> > to catch and emulate the callback.
>
> I agree that SIGEV_THREAD support requires some sort of participation
> from the thread library. However as I mentioned before, the timer
> callback thread doesn't ever get invoked with this kernel & threads
> implementation. To make matters more complicated, we are using the
> LFS threads implementation. I do know that signal-based notification
> does work.
I've looked at the librt code for timer_create now and it turns
our that for a SIGEV_THREAD event it actually installs it's own
signal handler then calls the system call for a SIGEV_SIGNAL event
and lets the signal handler trigger the running of the function.
So there shouldn't be much complication to the system call definition
as the system call only handles signal events.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Tom H. <to...@co...> - 2004-06-12 16:10:18
|
Nightly build on dunsmere ( Fedora Core 2 ) started at 2004-06-11 03:20:01 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow rcrl: valgrind ./rcrl readline1: valgrind ./readline1 resolv: valgrind ./resolv seg_override: valgrind ./seg_override semlimit: valgrind ./semlimit sha1_test: valgrind ./sha1_test shortpush: valgrind ./shortpush shorts: valgrind ./shorts smc1: valgrind ./smc1 susphello: valgrind ./susphello syscall-restart1: valgrind ./syscall-restart1 syscall-restart2: valgrind ./syscall-restart2 system: valgrind ./system yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 158 tests, 0 stderr failures, 1 stdout failure ================= none/tests/exec-sigmask (stdout) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:10:17
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> I am still working on properly supporting the timer_* APIs.
I've been looking at them well following your previous posts. My first
problem was that the librt.so on FC2 wouldn't work until I added support
for NPTL style cleanup handlers to valgrind so I couldn't get as far as
trying to create a timer. I've committed a fix for that now, but I'm
curious as to hw you got it to work.
> A point of confusion I have is how to track the timer_t argument.
> The timer_t type is just a 'void *' handle at the function call level.
You shouldn't really be worrying about what the underlying type is
as your code shouldn't be relying on that in any way.
> In the following code, I am pretty sure that the timer_create POST
> wrapper is correct but I am not sure what the syntax should be in
> timer_settime to properly check that the timer_t (void *) is
> initialized by timer_create. Can someone please provide me with
> guidance?
Scalar arguments to system calls are not currently check at all by
valgrind - that's a bug really but it's how it is at the moment so
you don't need to do anything in the timer_settime call for the
timer ID argument.
> For the timer_delete POST operation I need a way to declare that the
> timer handle is no longer valid. How should that be done?
Unless you're going to add full scale tracking for timer handles in
the same way that file handles are tracked then you can't. The memory
that holds the handle is still well defined so you shouldn't try and
mark it as undefined, not that you can as it is a scalar argument.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Tom H. <th...@cy...> - 2004-06-12 16:10:16
|
In message <Pin...@sc...>
Bob Friesenhahn <bfr...@si...> wrote:
> As a followup, if I create a patch containing my updates and apply it
> to the released 2.1.1 sources, valgrind gets a lot further through
> execution of the program. This implies that the abort I encountered
> with the CVS version is peculiar to the CVS version:
>
> --24414-- sys_wait_results: got PX_SetSigmask for TID 2
> ==24414==
> ==24414== Invalid read of size 4
> ==24414== at 0x3C074AA9: (within /lib/librt-2.3.3.so)
> ==24414== by 0x3C8A200B: pthread_once (vg_libpthread.c:1730)
> ==24414== by 0x3C074228: timer_create (in /lib/librt-2.3.3.so)
> ==24414== by 0x808A323: CTimeBox::CreateTimer() (TimeBox.cc:74)
> ==24414== by 0x808B209: CTimeBox::CTimeBox(char*) (TimeBox.cc:126)
> ==24414== by 0x809241B: InitializeFunct() (basefuncts.cc:548)
> ==24414== by 0x809F2EE: main (guiMain.cc:218)
> ==24414== Address 0x4A is not stack'd, malloc'd or free'd
> ==24414==
> ==24414== Process terminating with default action of signal 11 (SIGSEGV): dumping core
> ==24414== Access not within mapped region at address 0x4A
> ==24414== at 0x3C074AA9: (within /lib/librt-2.3.3.so)
> ==24414== by 0x3C8A200B: pthread_once (vg_libpthread.c:1730)
> ==24414== by 0x3C074228: timer_create (in /lib/librt-2.3.3.so)
> ==24414== by 0x808A323: CTimeBox::CreateTimer() (TimeBox.cc:74)
> ==24414== by 0x808B209: CTimeBox::CTimeBox(char*) (TimeBox.cc:126)
> ==24414== by 0x809241B: InitializeFunct() (basefuncts.cc:548)
> ==24414== by 0x809F2EE: main (guiMain.cc:218)
>
> This crash does not occur without valgrind, however, it is quite
> possible that the related librt/application code is indeed faulty
> since the timer notify method the code is using (SIGEV_THREAD) has not
> been observed (by me) to be working in this kernel.
I've worked out what is causing this now, and I'm not sure what we
can do about it...
The basic problem is that the glibc timer_create() implementation
in librt does something tryly horrible. It creates a helper thread
with pthread_create() and then casts the returned thread handle to
a struct pthread and tries to look into it.
Under valgrind the thread handle is not a pointer, it is a small
unique integer, hance the attempt to access a low address.
In fact we are better off not implementing the timer system calls
for now as librt will take ENOSYS as a trigger to fall back to the
old way of doing things with a thread that blocks with a futex for
the required length of time and then runs the handler function.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Bob F. <bfr...@si...> - 2004-06-12 14:35:33
|
I would like to get timer_* support completed properly so that I can post a completed patch. Unfortunately, even with Tom Hughes latest fixes for NPTL, I am encountering a problem when requesting thread-based notification (SIGEV_THREAD). Signal based notification works fine. Either there is a residual problem with librt, or valgrind itself is causing the problem. ==409== Invalid read of size 4 ==409== at 0x3C03101E: (within /lib/librt-2.3.3.so) ==409== by 0x3C1223ED: pthread_once (vg_libpthread.c:1709) ==409== by 0x3C0304C8: timer_create (in /lib/librt-2.3.3.so) ==409== by 0x804F76B: Request::MessageTimedEvent::create(int) (MessageTimedEvent.cc:201) ==409== Address 0x4A is not stack'd, malloc'd or (recently) free'd ==409== ==409== Process terminating with default action of signal 11 (SIGSEGV) ==409== Access not within mapped region at address 0x4A ==409== at 0x3C03101E: (within /lib/librt-2.3.3.so) ==409== by 0x3C1223ED: pthread_once (vg_libpthread.c:1709) ==409== by 0x3C0304C8: timer_create (in /lib/librt-2.3.3.so) ==409== by 0x804F76B: Request::MessageTimedEvent::create(int) (MessageTimedEvent.cc:201) ====================================== Bob Friesenhahn bfr...@si... http://www.simplesystems.org/users/bfriesen |
|
From: Tom H. <th...@cy...> - 2004-06-12 12:59:01
|
CVS commit by thughes:
It appears that NPTL uses a new system for dealing with cleanup
handlers when a thread is cancelled which has the side effect that
programs linked with librt fail on Fedora Core 2 due to librt having
been built against the NPTL header instead of the old pthread headers.
This change extends valgrind's libpthread.so to handle both the old
and new style cleanup handlers in a similar way to NPTL and seems to
be sufficient to get programs linked with librt working again.
A corecheck/tests/pth_cancel1.c 1.1 [POSSIBLY UNSAFE: printf] [no copyright]
A corecheck/tests/pth_cancel1.stderr.exp 1.1
A corecheck/tests/pth_cancel1.stdout.exp 1.1
A corecheck/tests/pth_cancel1.vgtest 1.1
M +4 -1 corecheck/tests/Makefile.am 1.19
M +25 -2 coregrind/vg_include.h 1.192
M +281 -117 coregrind/vg_libpthread.c 1.154 [POSSIBLY UNSAFE: printf]
M +21 -6 coregrind/vg_scheduler.c 1.149
--- valgrind/corecheck/tests/Makefile.am #1.18:1.19
@@ -19,4 +19,5 @@
fdleak_socketpair.stderr.exp fdleak_socketpair.vgtest \
pth_atfork1.stderr.exp pth_atfork1.stdout.exp pth_atfork1.vgtest \
+ pth_cancel1.stderr.exp pth_cancel1.stdout.exp pth_cancel1.vgtest \
pth_cancel2.stderr.exp pth_cancel2.vgtest \
pth_cvsimple.stderr.exp pth_cvsimple.stdout.exp pth_cvsimple.vgtest \
@@ -34,5 +35,5 @@
fdleak_fcntl fdleak_ipv4 fdleak_open fdleak_pipe \
fdleak_socketpair sigkill res_search \
- pth_atfork1 pth_cancel2 pth_cvsimple pth_empty \
+ pth_atfork1 pth_cancel1 pth_cancel2 pth_cvsimple pth_empty \
pth_exit pth_mutexspeed pth_once \
as_mmap as_shm \
@@ -63,4 +64,6 @@
pth_atfork1_SOURCES = pth_atfork1.c
pth_atfork1_LDADD = -lpthread
+pth_cancel1_SOURCES = pth_cancel1.c
+pth_cancel1_LDADD = -lpthread
pth_cancel2_SOURCES = pth_cancel2.c
pth_cancel2_LDADD = -lpthread
--- valgrind/coregrind/vg_include.h #1.191:1.192
@@ -706,9 +706,32 @@ typedef
ThreadStatus;
+typedef
+ enum CleanupType {
+ VgCt_None, /* this cleanup entry is not initialised */
+ VgCt_Function, /* an old-style function pointer cleanup */
+ VgCt_Longjmp /* a new-style longjmp based cleanup */
+ }
+ CleanupType;
+
+/* A thread unwind buffer */
+typedef
+ struct {
+ jmp_buf jb;
+ } ThreadUnwindBuf;
+
/* An entry in a threads's cleanup stack. */
typedef
struct {
+ CleanupType type;
+ union {
+ struct {
void (*fn)(void*);
void* arg;
+ } function;
+ struct {
+ ThreadUnwindBuf *ub;
+ int ctype;
+ } longjmp;
+ } data;
}
CleanupEntry;
--- valgrind/coregrind/vg_libpthread.c #1.153:1.154
@@ -200,4 +200,9 @@ static void
init_thread_specific_state ( void );
+static void
+set_ret_val ( void* );
+static void *
+get_ret_val ( void );
+
/* ---------------------------------------------------------------------
Helpers. We have to be pretty self-sufficient.
@@ -676,15 +681,4 @@ void thread_exit_wrapper ( void* ret_val
void** specifics_ptr;
- /* Run this thread's cleanup handlers. */
- while (1) {
- VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
- VG_USERREQ__CLEANUP_POP,
- &cu, 0, 0, 0);
- if (res == -1) break; /* stack empty */
- my_assert(res == 0);
- if (0) printf("running exit cleanup handler");
- cu.fn ( cu.arg );
- }
-
/* Run this thread's key finalizers. Really this should be run
PTHREAD_DESTRUCTOR_ITERATIONS times. */
@@ -695,7 +689,8 @@ void thread_exit_wrapper ( void* ret_val
if (res == 0) {
/* valid key */
- if (cu.fn && cu.arg)
- cu.fn /* destructor for key */
- ( cu.arg /* specific for key for this thread */ );
+ my_assert(cu.type == VgCt_Function);
+ if (cu.data.function.fn && cu.data.function.arg)
+ cu.data.function.fn /* destructor for key */
+ ( cu.data.function.arg /* specific for key for this thread */ );
continue;
}
@@ -783,4 +778,5 @@ void thread_wrapper ( NewThreadInfo* inf
void* arg;
void* ret_val;
+ ThreadUnwindBuf ub;
attr__detachstate = info->attr__detachstate;
@@ -837,4 +833,15 @@ void thread_wrapper ( NewThreadInfo* inf
my_free(info);
+
+ if (setjmp(ub.jb) == 0) {
+ CleanupEntry cu;
+ int res;
+
+ cu.type = VgCt_Longjmp;
+ cu.data.longjmp.ub = &ub;
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_PUSH,
+ &cu, 0, 0, 0);
+
/* The root function might not return. But if it does we simply
move along to thread_exit_wrapper. All other ways out for the
@@ -842,4 +849,9 @@ void thread_wrapper ( NewThreadInfo* inf
too. */
ret_val = root_fn(arg);
+ }
+ else {
+ ret_val = get_ret_val();
+ }
+
thread_exit_wrapper(ret_val);
/* NOTREACHED */
@@ -848,4 +860,210 @@ void thread_wrapper ( NewThreadInfo* inf
/* ---------------------------------------------------
+ CLEANUP STACKS
+ ------------------------------------------------ */
+
+void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
+ void (*__routine) (void *),
+ void *__arg)
+{
+ int res;
+ CleanupEntry cu;
+ ensure_valgrind("_pthread_cleanup_push");
+ cu.type = VgCt_Function;
+ cu.data.function.fn = __routine;
+ cu.data.function.arg = __arg;
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_PUSH,
+ &cu, 0, 0, 0);
+ my_assert(res == 0);
+}
+
+
+void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer,
+ void (*__routine) (void *),
+ void *__arg)
+{
+ /* As _pthread_cleanup_push, but first save the thread's original
+ cancellation type in __buffer and set it to Deferred. */
+ int orig_ctype;
+ ensure_valgrind("_pthread_cleanup_push_defer");
+ /* Set to Deferred, and put the old cancellation type in res. */
+ my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
+ my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS);
+ my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int));
+ VALGRIND_MAGIC_SEQUENCE(orig_ctype, (-1) /* default */,
+ VG_USERREQ__SET_CANCELTYPE,
+ PTHREAD_CANCEL_DEFERRED, 0, 0, 0);
+ my_assert(orig_ctype != -1);
+ *((int*)(__buffer)) = orig_ctype;
+ /* Now push the cleanup. */
+ _pthread_cleanup_push(NULL, __routine, __arg);
+}
+
+
+void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
+ int __execute)
+{
+ int res;
+ CleanupEntry cu;
+ ensure_valgrind("_pthread_cleanup_push");
+ cu.type = VgCt_None; /* paranoia */
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_POP,
+ &cu, 0, 0, 0);
+ my_assert(cu.type == VgCt_Function);
+ if (res == 0) {
+ /* pop succeeded */
+ if (__execute) {
+ cu.data.function.fn ( cu.data.function.arg );
+ }
+ return;
+ }
+ if (res == -1) {
+ /* stack underflow */
+ return;
+ }
+ barf("_pthread_cleanup_pop");
+}
+
+
+void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer,
+ int __execute)
+{
+ int orig_ctype, fake_ctype;
+ /* As _pthread_cleanup_pop, but after popping/running the handler,
+ restore the thread's original cancellation type from the first
+ word of __buffer. */
+ _pthread_cleanup_pop(NULL, __execute);
+ orig_ctype = *((int*)(__buffer));
+ my_assert(orig_ctype == PTHREAD_CANCEL_DEFERRED
+ || orig_ctype == PTHREAD_CANCEL_ASYNCHRONOUS);
+ my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
+ my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS);
+ my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int));
+ VALGRIND_MAGIC_SEQUENCE(fake_ctype, (-1) /* default */,
+ VG_USERREQ__SET_CANCELTYPE,
+ orig_ctype, 0, 0, 0);
+ my_assert(fake_ctype == PTHREAD_CANCEL_DEFERRED);
+}
+
+
+__attribute ((regparm (1)))
+void __pthread_register_cancel (ThreadUnwindBuf *ub)
+{
+ int res;
+ CleanupEntry cu;
+ ensure_valgrind("__pthread_register_cancel");
+ cu.type = VgCt_Longjmp;
+ cu.data.longjmp.ub = ub;
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_PUSH,
+ &cu, 0, 0, 0);
+ my_assert(res == 0);
+}
+
+
+__attribute ((regparm (1)))
+void __pthread_register_cancel_defer (ThreadUnwindBuf *ub)
+{
+ /* As __pthread_register cancel, but save the thread's original
+ cancellation type and set it to Deferred. */
+ int res;
+ CleanupEntry cu;
+ ensure_valgrind("__pthread_register_cancel_defer");
+ cu.type = VgCt_Longjmp;
+ cu.data.longjmp.ub = ub;
+ /* Set to Deferred, and save the old cancellation type. */
+ my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
+ my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS);
+ my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int));
+ VALGRIND_MAGIC_SEQUENCE(cu.data.longjmp.ctype, (-1) /* default */,
+ VG_USERREQ__SET_CANCELTYPE,
+ PTHREAD_CANCEL_DEFERRED, 0, 0, 0);
+ my_assert(cu.data.longjmp.ctype != -1);
+ /* Now push the cleanup. */
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_PUSH,
+ &cu, 0, 0, 0);
+ my_assert(res == 0);
+}
+
+
+__attribute ((regparm (1)))
+void __pthread_unregister_cancel (ThreadUnwindBuf *ub)
+{
+ int res;
+ CleanupEntry cu;
+ ensure_valgrind("__pthread_unregister_cancel");
+ cu.type = VgCt_None; /* paranoia */
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_POP,
+ &cu, 0, 0, 0);
+ my_assert(cu.type == VgCt_Longjmp);
+ my_assert(cu.data.longjmp.ub == ub);
+ return;
+}
+
+
+__attribute ((regparm (1)))
+void __pthread_unregister_restore (ThreadUnwindBuf *ub)
+{
+ int res;
+ CleanupEntry cu;
+ int fake_ctype;
+ /* As __pthread_unregister_cancel, but after popping/running the
+ handler, restore the thread's original cancellation type. */
+ ensure_valgrind("__pthread_unregister_cancel_restore");
+ cu.type = VgCt_None; /* paranoia */
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_POP,
+ &cu, 0, 0, 0);
+ my_assert(cu.type == VgCt_Longjmp);
+ my_assert(cu.data.longjmp.ub == ub);
+ /* Restore the original cancellation type. */
+ my_assert(cu.data.longjmp.ctype == PTHREAD_CANCEL_DEFERRED
+ || cu.data.longjmp.ctype == PTHREAD_CANCEL_ASYNCHRONOUS);
+ my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
+ my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS);
+ VALGRIND_MAGIC_SEQUENCE(fake_ctype, (-1) /* default */,
+ VG_USERREQ__SET_CANCELTYPE,
+ cu.data.longjmp.ctype, 0, 0, 0);
+ my_assert(fake_ctype == PTHREAD_CANCEL_DEFERRED);
+ return;
+}
+
+__attribute ((regparm (1)))
+__attribute ((__noreturn__))
+void __pthread_unwind (ThreadUnwindBuf *ub)
+{
+ int res;
+ CleanupEntry cu;
+ while (1) {
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__CLEANUP_POP,
+ &cu, 0, 0, 0);
+ my_assert(res == 0);
+ if (cu.type == VgCt_Longjmp) break;
+ if (0) printf("running cleanup handler");
+ my_assert(cu.type == VgCt_Function);
+ cu.data.function.fn ( cu.data.function.arg );
+ }
+ my_assert(cu.type == VgCt_Longjmp);
+ my_assert(ub == NULL || ub == cu.data.longjmp.ub);
+ longjmp(cu.data.longjmp.ub->jb, 1);
+ /* NOTREACHED */
+}
+
+
+__attribute ((regparm (1)))
+__attribute ((__noreturn__))
+void __pthread_unwind_next (ThreadUnwindBuf *ub)
+{
+ __pthread_unwind(NULL);
+ /* NOTREACHED */
+}
+
+
+/* ---------------------------------------------------
THREADs
------------------------------------------------ */
@@ -958,6 +1176,6 @@ void pthread_exit(void *retval)
{
ensure_valgrind("pthread_exit");
- /* Simple! */
- thread_exit_wrapper(retval);
+ set_ret_val(retval);
+ __pthread_unwind(NULL);
}
@@ -995,92 +1213,4 @@ int pthread_detach(pthread_t th)
/* ---------------------------------------------------
- CLEANUP STACKS
- ------------------------------------------------ */
-
-void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
- void (*__routine) (void *),
- void *__arg)
-{
- int res;
- CleanupEntry cu;
- ensure_valgrind("_pthread_cleanup_push");
- cu.fn = __routine;
- cu.arg = __arg;
- VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
- VG_USERREQ__CLEANUP_PUSH,
- &cu, 0, 0, 0);
- my_assert(res == 0);
-}
-
-
-void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer,
- void (*__routine) (void *),
- void *__arg)
-{
- /* As _pthread_cleanup_push, but first save the thread's original
- cancellation type in __buffer and set it to Deferred. */
- int orig_ctype;
- ensure_valgrind("_pthread_cleanup_push_defer");
- /* Set to Deferred, and put the old cancellation type in res. */
- my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
- my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS);
- my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int));
- VALGRIND_MAGIC_SEQUENCE(orig_ctype, (-1) /* default */,
- VG_USERREQ__SET_CANCELTYPE,
- PTHREAD_CANCEL_DEFERRED, 0, 0, 0);
- my_assert(orig_ctype != -1);
- *((int*)(__buffer)) = orig_ctype;
- /* Now push the cleanup. */
- _pthread_cleanup_push(NULL, __routine, __arg);
-}
-
-
-void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
- int __execute)
-{
- int res;
- CleanupEntry cu;
- ensure_valgrind("_pthread_cleanup_push");
- cu.fn = cu.arg = NULL; /* paranoia */
- VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
- VG_USERREQ__CLEANUP_POP,
- &cu, 0, 0, 0);
- if (res == 0) {
- /* pop succeeded */
- if (__execute) {
- cu.fn ( cu.arg );
- }
- return;
- }
- if (res == -1) {
- /* stack underflow */
- return;
- }
- barf("_pthread_cleanup_pop");
-}
-
-
-void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer,
- int __execute)
-{
- int orig_ctype, fake_ctype;
- /* As _pthread_cleanup_pop, but after popping/running the handler,
- restore the thread's original cancellation type from the first
- word of __buffer. */
- _pthread_cleanup_pop(NULL, __execute);
- orig_ctype = *((int*)(__buffer));
- my_assert(orig_ctype == PTHREAD_CANCEL_DEFERRED
- || orig_ctype == PTHREAD_CANCEL_ASYNCHRONOUS);
- my_assert(-1 != PTHREAD_CANCEL_DEFERRED);
- my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS);
- my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int));
- VALGRIND_MAGIC_SEQUENCE(fake_ctype, (-1) /* default */,
- VG_USERREQ__SET_CANCELTYPE,
- orig_ctype, 0, 0, 0);
- my_assert(fake_ctype == PTHREAD_CANCEL_DEFERRED);
-}
-
-
-/* ---------------------------------------------------
MUTEX ATTRIBUTES
------------------------------------------------ */
@@ -1407,5 +1537,5 @@ int pthread_cancel(pthread_t thread)
VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
VG_USERREQ__SET_CANCELPEND,
- thread, &thread_exit_wrapper, 0, 0);
+ thread, &pthread_exit, 0, 0);
my_assert(res != -1);
return res;
@@ -1836,4 +1966,5 @@ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MA
typedef
struct {
+ void *ret_val;
int *errno_ptr;
int *h_errno_ptr;
@@ -1853,4 +1984,11 @@ static int global_init_done
static pthread_mutex_t global_init_done_mx = PTHREAD_MUTEX_INITIALIZER;
+static
+void cleanup_root(void *arg)
+{
+ thread_exit_wrapper(get_ret_val());
+ /* NOTREACHED */
+}
+
static void
init_global_thread_specific_state ( void )
@@ -1883,4 +2021,7 @@ init_global_thread_specific_state ( void
global_init_done = 1;
+ /* Install a cleanup routine to handle the root thread exiting */
+ _pthread_cleanup_push(NULL, cleanup_root, NULL);
+
/* Unlock and return. */
res = __pthread_mutex_unlock(&global_init_done_mx);
@@ -1894,4 +2035,7 @@ init_thread_specific_state ( void )
int i;
+ /* No return value yet */
+ thread_specific_state[tid].ret_val = NULL;
+
/* Initialise the errno and resolver state pointers. */
thread_specific_state[tid].errno_ptr = NULL;
@@ -1912,4 +2056,24 @@ init_thread_specific_state ( void )
}
+static void
+set_ret_val ( void* ret_val )
+{
+ int tid;
+ VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */,
+ VG_USERREQ__PTHREAD_GET_THREADID,
+ 0, 0, 0, 0);
+ thread_specific_state[tid].ret_val = ret_val;
+}
+
+static void *
+get_ret_val ( void )
+{
+ int tid;
+ VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */,
+ VG_USERREQ__PTHREAD_GET_THREADID,
+ 0, 0, 0, 0);
+ return thread_specific_state[tid].ret_val;
+}
+
int* __errno_location ( void )
{
--- valgrind/coregrind/vg_scheduler.c #1.148:1.149
@@ -1473,7 +1473,21 @@ void do__cleanup_push ( ThreadId tid, Cl
sp = VG_(threads)[tid].custack_used;
if (VG_(clo_trace_sched)) {
+ switch (cu->type) {
+ case VgCt_Function:
VG_(sprintf)(msg_buf,
"cleanup_push (fn %p, arg %p) -> slot %d",
- cu->fn, cu->arg, sp);
+ cu->data.function.fn, cu->data.function.arg, sp);
+ break;
+ case VgCt_Longjmp:
+ VG_(sprintf)(msg_buf,
+ "cleanup_push (ub %p) -> slot %d",
+ cu->data.longjmp.ub, sp);
+ break;
+ default:
+ VG_(sprintf)(msg_buf,
+ "cleanup_push (unknown type) -> slot %d",
+ sp);
+ break;
+ }
print_sched_event(tid, msg_buf);
}
@@ -2655,7 +2669,8 @@ void do__get_key_destr_and_spec ( Thread
(Addr)cu, sizeof(CleanupEntry) );
- cu->fn = vg_thread_keys[key].destructor;
+ cu->type = VgCt_Function;
+ cu->data.function.fn = vg_thread_keys[key].destructor;
if (VG_(threads)[tid].specifics_ptr == NULL) {
- cu->arg = NULL;
+ cu->data.function.arg = NULL;
} else {
VG_TRACK( pre_mem_read, Vg_CorePThread, tid,
@@ -2663,5 +2678,5 @@ void do__get_key_destr_and_spec ( Thread
(Addr)(&VG_(threads)[tid].specifics_ptr[key]),
sizeof(void*) );
- cu->arg = VG_(threads)[tid].specifics_ptr[key];
+ cu->data.function.arg = VG_(threads)[tid].specifics_ptr[key];
}
|