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: Nicholas N. <nj...@ca...> - 2004-06-27 21:26:43
|
Hi, I've trawled through Valgrind's memory allocation functions, and refactored and simplified things a bit. I haven't really made any progress on the goal of having just client and Valgrind areas; that looks (surprise surprise) harder than I first thought. Patch is attached, diff'd against current HEAD. ChangeLog is below. I'd be interested to hear comments, esp. from Jeremy. Thanks. N Changed replacement malloc() so that it returns 0 if it fails, rather than aborting with an assertion failure. This is consistent with the non-replacement malloc() used by eg. Nulgrind. Removed the 'place-holder' behaviour of VG_(mmap). Previously, VG_(mmap) would add a segment mapping to the segment skip-list, and then often the caller of VG_(mmap) would do another one for the same segment, just to change the SF_* flags. Now VG_(mmap) gets passed the appropriate SF_* flags so it can do it directly. This simplifies things, and allows VG_(client_alloc) and VG_(client_free) to be removed. In vg_syscalls.c, inlined mprotect_segment and munmap_segment because it's more concise and easier to understand that way. Strengthened checking in VG_(mmap), POST(mmap), POST(mmap2) -- now if the result is not in the right place, it aborts rather than unmapping and continuing. This is because if it's not in the right place, something bad has gone wrong. Partly reordered main(), so that some related things are together more, and fixed up some of the comments describing ordering dependencies there. Removed an unnecessary VG_(unmap_range)() call from do_brk(). Added a lot of checking for calls to mmap() and munmap() which were assumed to be succeeding. |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 21:08:41
|
On Sun, 27 Jun 2004, Nicholas Nethercote wrote: > do__apply_in_new_thread() allocates a new thread stack if the old one isn't > big enough, via VG_(mmap)(). > > cleanup_after_thread_exited() doesn't free the stack, although it looks like > the place where that should be happening. > > It's possible that the stacks are intended to be kept around so that if the > thread is reused later the stack can be reused too. But in that case, when > do__apply_in_new_thread() allocates the new one, the old one should be freed. > > So I think there's a leak here. Does that sound right? Hmm, it looks like Tom's commit earlier today for the thread attribute stuff fixed this. Sorry for the noise. N |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 20:55:14
|
Hi, do__apply_in_new_thread() allocates a new thread stack if the old one isn't big enough, via VG_(mmap)(). cleanup_after_thread_exited() doesn't free the stack, although it looks like the place where that should be happening. It's possible that the stacks are intended to be kept around so that if the thread is reused later the stack can be reused too. But in that case, when do__apply_in_new_thread() allocates the new one, the old one should be freed. So I think there's a leak here. Does that sound right? Thanks. N |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 20:15:17
|
Hi,
According to several man pages I can find, mremap has four arguments:
void * mremap(void *old_address, size_t old_size , size_t new_size,
unsigned long flags);
According to Valgrind, it has five:
/* void* mremap(void * old_address, size_t old_size,
size_t new_size, unsigned long flags, void * new_address); */
MAYBE_PRINTF("mremap ( %p, %d, %d, 0x%x, %p )\n",
arg1, arg2, arg3, arg4, arg5);
Ahem.
I suspect that mremap() is totally bogus, but it hasn't been noticed
because it doesn't get used much.
N
|
|
From: Jeremy F. <je...@go...> - 2004-06-27 19:54:21
|
On Sun, 2004-06-27 at 12:32 +0100, Tom Hughes wrote: > I've now heard from the person who wrote that and apparently what they > were talking about is the fact that several routines in valgrind use > nested functions themselves, which causes gcc to mark those object as > needing an executable stack which in turn stops things like NX support > from kicking in. > > Does anybody have any particular objections to removing the use of > nested functions in valgrind? I haven't looked at it in any detail > yet and I know that at least some of them make use of stack variables > from the parent function which makes removing them non-trivial but > it could be done. I'd object. It makes the code a lot cleaner in a lot of places, and in general I think nested functions are a good idea. NX is basically useless, particularly for Valgrind, so I don't think there's any reason to inconvenience ourselves over it. J |
|
From: Jeremy F. <je...@go...> - 2004-06-27 19:51:46
|
On Sun, 2004-06-27 at 17:02 +0100, Nicholas Nethercote wrote: > Hi, > > Currently, for tools replacing malloc (eg. Memcheck), if a malloc call > fails, Valgrind aborts. (Actually, an assertion failure occurs.) > > I figure that client calls to malloc should fail and return 0 like the > system malloc in this case. That's what happens with tools that don't > replace the system malloc (eg. Nulgrind). Does anyone object to this > proposed behaviour? No - and we also need to deal properly with all the other allocation failures as well. J |
|
From: Bob F. <bfr...@si...> - 2004-06-27 18:35:30
|
On Sun, 27 Jun 2004, Nicholas Nethercote wrote: > Hi, > > Currently, for tools replacing malloc (eg. Memcheck), if a malloc call fails, > Valgrind aborts. (Actually, an assertion failure occurs.) > > I figure that client calls to malloc should fail and return 0 like the system > malloc in this case. That's what happens with tools that don't replace the > system malloc (eg. Nulgrind). Does anyone object to this proposed behaviour? Software exists (including software I maintain) which is capable of carrying on with an alternative algorithm (e.g. disk-based) when certain large malloc requests fail so I second the motion that malloc should return zero. It would be wise to log that malloc did fail, along with the requested allocation size. Bob ====================================== Bob Friesenhahn bfr...@si... http://www.simplesystems.org/users/bfriesen |
|
From: Tom H. <th...@cy...> - 2004-06-27 18:10:45
|
In message <Pin...@he...>
Nicholas Nethercote <nj...@ca...> wrote:
> On Sun, 27 Jun 2004, Tom Hughes wrote:
>
> > Removed all uses of nested functions as they only work with gcc and
> > cause the stack to be marked as executable in order for them to work.
>
> Should probably bump the major version number too, since there are some
> core/tool interface changes...
Done.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Tom H. <th...@cy...> - 2004-06-27 18:10:26
|
CVS commit by thughes:
Bumped the core interface major version number to reflect changes
made to the interface when removing nested functions.
M +1 -1 vg_skin.h.base 1.24
--- valgrind/include/vg_skin.h.base #1.23:1.24
@@ -127,5 +127,5 @@
will abort. The minor version indicates binary-compatible changes.
*/
-#define VG_CORE_INTERFACE_MAJOR_VERSION 5
+#define VG_CORE_INTERFACE_MAJOR_VERSION 6
#define VG_CORE_INTERFACE_MINOR_VERSION 0
|
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 17:55:47
|
On Sun, 27 Jun 2004, Tom Hughes wrote: > Removed all uses of nested functions as they only work with gcc and > cause the stack to be marked as executable in order for them to work. Should probably bump the major version number too, since there are some core/tool interface changes... N |
|
From: Julian S. <js...@ac...> - 2004-06-27 17:50:00
|
> I've done the deed. Some things I fixed using static data and some > by adding extra parameters that are passed to callback routines. Cool! > > Probably a good thing to do. Another reason is Icc uses a completely > > different C/C++ front end from gcc/g++ and so produces a whole > > different set of warnings. Ideally V should compile cleanly with > > both compilers. > > Don't we use lots of other gcc extensions though, like attributes and > inline assembler. Yes we do, but icc can manage lots of the gcc extensions. Nested fns is one of the few extensions it can't do. J |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 17:49:24
|
On Sun, 27 Jun 2004, Tom Hughes wrote: > Don't we use lots of other gcc extensions though, like attributes and > inline assembler. Apparently icc supports a lot of the extensions, precisely for gcc compatibility. N |
|
From: Tom H. <th...@cy...> - 2004-06-27 17:39:06
|
In message <200...@ac...>
Julian Seward <js...@ac...> wrote:
> It's the only thing, I think, that prevents building with Icc. At some
> point in the past I did exactly this nested fn removal, and the result
> works with Icc. It's an hour's work or so, not a big deal. It'll
> make you a Hero(tm) with the Icc people, who have asked more than once
> to make valgrind icc-compilable.
I've done the deed. Some things I fixed using static data and some
by adding extra parameters that are passed to callback routines.
I also added a line to each of the assembly source files to declare
them as not needing an executable stack otherwise valgrind and one of
the skins still wind up being marked as needed an executable stack.
> Probably a good thing to do. Another reason is Icc uses a completely
> different C/C++ front end from gcc/g++ and so produces a whole
> different set of warnings. Ideally V should compile cleanly with
> both compilers.
Don't we use lots of other gcc extensions though, like attributes and
inline assembler.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Tom H. <th...@cy...> - 2004-06-27 17:37:34
|
CVS commit by thughes:
Removed all uses of nested functions as they only work with gcc and
cause the stack to be marked as executable in order for them to work.
All assembler files have also had a declaration added so that the
object they generate will be marked as not needing an executable stack.
M +6 -5 coregrind/stage1.c 1.12 [POSSIBLY UNSAFE: printf]
M +53 -44 coregrind/ume.c 1.10
M +7 -0 coregrind/vg_cpuid.S 1.2
M +3 -1 coregrind/vg_dispatch.S 1.17
M +8 -4 coregrind/vg_hashtable.c 1.9
M +4 -1 coregrind/vg_helpers.S 1.33
M +47 -43 coregrind/vg_main.c 1.166 [POSSIBLY UNSAFE: printf]
M +11 -7 coregrind/vg_mylibc.c 1.75
M +4 -3 coregrind/vg_scheduler.c 1.154
M +36 -31 coregrind/vg_symtypes.c 1.6 [POSSIBLY UNSAFE: printf]
M +4 -1 coregrind/vg_syscall.S 1.13
M +18 -9 coregrind/vg_transtab.c 1.28
M +3 -0 coregrind/x86/ume_entry.S 1.3
M +55 -55 helgrind/hg_main.c 1.77
M +11 -7 include/vg_skin.h.base 1.23
M +4 -6 massif/ms_main.c 1.11
M +41 -26 memcheck/mac_malloc_wrappers.c 1.12
M +26 -22 memcheck/mac_needs.c 1.28
M +1 -1 memcheck/mac_shared.h 1.19
M +9 -7 memcheck/mc_clientreqs.c 1.21
M +3 -1 memcheck/mc_helpers.S 1.9
--- valgrind/coregrind/stage1.c #1.11:1.12
@@ -157,4 +157,10 @@ static void *fix_auxv(void *v_init_esp,
}
+static int prmap(void *start, void *end, const char *perm, off_t off, int maj, int min, int ino) {
+ printf("mapping %10p-%10p %s %02x:%02x %d\n",
+ start, end, perm, maj, min, ino);
+ return 1;
+}
+
static void hoops(void)
{
@@ -194,9 +200,4 @@ static void hoops(void)
if (0) {
- int prmap(void *start, void *end, const char *perm, off_t off, int maj, int min, int ino) {
- printf("mapping %10p-%10p %s %02x:%02x %d\n",
- start, end, perm, maj, min, ino);
- return 1;
- }
printf("---------- launch stage 2 ----------\n");
printf("eip=%p esp=%p\n", (void *)info.init_eip, esp);
--- valgrind/coregrind/ume.c #1.9:1.10
@@ -145,23 +145,25 @@ void foreach_map(int (*fn)(void *start,
}
-/* pad all the empty spaces in a range of address space to stop
- interlopers */
-void as_pad(void *start, void *end)
-{
- char buf[1024];
- char *addr;
+static char *fillgap_addr;
+static char *fillgap_end;
- int fillgap(void *segstart, void *segend, const char *perm, off_t off,
+static int fillgap(void *segstart, void *segend, const char *perm, off_t off,
int maj, int min, int ino) {
- if (segstart >= end)
+ if ((char *)segstart >= fillgap_end)
return 0;
- if ((char *)segstart > addr)
- mmap(addr, (char *)segstart-addr, PROT_NONE, MAP_FIXED|MAP_PRIVATE,
- padfile, 0);
- addr = segend;
+ if ((char *)segstart > fillgap_addr)
+ mmap(fillgap_addr, (char *)segstart-fillgap_addr, PROT_NONE,
+ MAP_FIXED|MAP_PRIVATE, padfile, 0);
+ fillgap_addr = segend;
return 1;
- }
+}
+
+/* pad all the empty spaces in a range of address space to stop
+ interlopers */
+void as_pad(void *start, void *end)
+{
+ char buf[1024];
if (padfile == -1) {
@@ -177,18 +179,18 @@ void as_pad(void *start, void *end)
}
- addr = start;
+ fillgap_addr = start;
+ fillgap_end = end;
foreach_map(fillgap);
- if (addr < (char *)end)
- mmap(addr, (char *)end-addr, PROT_NONE, MAP_FIXED|MAP_PRIVATE,
- padfile, 0);
+ if (fillgap_addr < fillgap_end)
+ mmap(fillgap_addr, fillgap_end-fillgap_addr, PROT_NONE,
+ MAP_FIXED|MAP_PRIVATE, padfile, 0);
}
-/* remove padding from a range of address space - padding is always a
- mapping of padfile*/
-void as_unpad(void *start, void *end)
-{
- int killpad(void *segstart, void *segend, const char *perm, off_t off,
+static void *killpad_start;
+static void *killpad_end;
+
+static int killpad(void *segstart, void *segend, const char *perm, off_t off,
int maj, int min, int ino) {
void *b, *e;
@@ -197,14 +199,14 @@ void as_unpad(void *start, void *end)
return 1;
- if (segend <= start || segstart >= end)
+ if (segend <= killpad_start || segstart >= killpad_end)
return 1;
- if (segstart <= start)
- b = start;
+ if (segstart <= killpad_start)
+ b = killpad_start;
else
b = segstart;
- if (segend >= end)
- e = end;
+ if (segend >= killpad_end)
+ e = killpad_end;
else
e = segend;
@@ -213,9 +215,16 @@ void as_unpad(void *start, void *end)
return 1;
- }
+}
+/* remove padding from a range of address space - padding is always a
+ mapping of padfile*/
+void as_unpad(void *start, void *end)
+{
if (padfile == -1) /* no padfile, no padding */
return;
+ killpad_start = start;
+ killpad_end = end;
+
foreach_map(killpad);
}
--- valgrind/coregrind/vg_cpuid.S #1.1:1.2
@@ -76,2 +76,9 @@
popl %ebp
ret
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+##--------------------------------------------------------------------##
+##--- end vg_cpuid.S ---##
+##--------------------------------------------------------------------##
--- valgrind/coregrind/vg_dispatch.S #1.16:1.17
@@ -223,5 +223,7 @@
.byte 0
.text
-
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
##--------------------------------------------------------------------##
--- valgrind/coregrind/vg_hashtable.c #1.8:1.9
@@ -134,5 +134,7 @@ VgHashNode** VG_(HT_to_array) ( VgHashTa
/* Return the first VgHashNode satisfying the predicate p. */
-VgHashNode* VG_(HT_first_match) ( VgHashTable table, Bool (*p) ( VgHashNode* ))
+VgHashNode* VG_(HT_first_match) ( VgHashTable table,
+ Bool (*p) ( VgHashNode*, void* ),
+ void* d )
{
UInt i;
@@ -141,5 +143,5 @@ VgHashNode* VG_(HT_first_match) ( VgHash
for (i = 0; i < VG_N_CHAINS; i++)
for (node = table[i]; node != NULL; node = node->next)
- if ( p(node) )
+ if ( p(node, d) )
return node;
@@ -147,5 +149,7 @@ VgHashNode* VG_(HT_first_match) ( VgHash
}
-void VG_(HT_apply_to_all_nodes)( VgHashTable table, void (*f)(VgHashNode*) )
+void VG_(HT_apply_to_all_nodes)( VgHashTable table,
+ void (*f)(VgHashNode*, void*),
+ void* d )
{
UInt i;
@@ -154,5 +158,5 @@ void VG_(HT_apply_to_all_nodes)( VgHashT
for (i = 0; i < VG_N_CHAINS; i++) {
for (node = table[i]; node != NULL; node = node->next) {
- f(node);
+ f(node, d);
}
}
--- valgrind/coregrind/vg_helpers.S #1.32:1.33
@@ -724,5 +724,8 @@
1: ud2
jmp 1b
-
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
##--------------------------------------------------------------------##
##--- end vg_helpers.S ---##
--- valgrind/coregrind/vg_main.c #1.165:1.166
@@ -765,8 +765,11 @@ static void get_command_line( int argc,
/* Scan a colon-separated list, and call a function on each element.
The string must be mutable, because we insert a temporary '\0', but
- the string will end up unmodified. (*func) should return 1 if it
+ the string will end up unmodified. (*func) should return True if it
doesn't need to see any more.
+
+ This routine will return True if (*func) returns True and False if
+ it reaches the end of the list without that happening.
*/
-static void scan_colsep(char *colsep, int (*func)(const char *))
+static Bool scan_colsep(char *colsep, Bool (*func)(const char *))
{
char *cp, *entry;
@@ -775,5 +778,5 @@ static void scan_colsep(char *colsep, in
if (colsep == NULL ||
*colsep == '\0')
- return;
+ return False;
entry = cp = colsep;
@@ -787,5 +790,5 @@ static void scan_colsep(char *colsep, in
*cp = '\0';
if ((*func)(entry))
- end = 1;
+ return True;
*cp = save;
entry = cp+1;
@@ -793,4 +796,13 @@ static void scan_colsep(char *colsep, in
cp++;
} while(!end);
+
+ return False;
+}
+
+static Bool contains(const char *p) {
+ if (VG_STREQ(p, VG_(libdir))) {
+ return True;
+ }
+ return False;
}
@@ -856,20 +868,9 @@ static char **fix_environment(char **ori
for (cpp = ret; cpp && *cpp; cpp++) {
if (memcmp(*cpp, ld_library_path, ld_library_path_len) == 0) {
- int done = 0;
- int contains(const char *p) {
- if (VG_STREQ(p, VG_(libdir))) {
- done = 1;
- return 1;
- }
- return 0;
- }
-
/* If the LD_LIBRARY_PATH already contains libdir, then don't
bother adding it again, even if it isn't the first (it
seems that the Java runtime will keep reexecing itself
unless its paths are at the front of LD_LIBRARY_PATH) */
- scan_colsep(*cpp + ld_library_path_len, contains);
-
- if (!done) {
+ if (!scan_colsep(*cpp + ld_library_path_len, contains)) {
int len = strlen(*cpp) + vgliblen*2 + 16;
char *cp = malloc(len);
@@ -1203,14 +1204,8 @@ static Addr setup_client_stack(char **or
/*====================================================================*/
-static const char* find_executable(const char* exec)
-{
- vg_assert(NULL != exec);
- if (strchr(exec, '/') == NULL) {
- /* no '/' - we need to search the path */
- char *path = getenv("PATH");
- int pathlen = path ? strlen(path) : 0;
+static const char* executable_name;
- int match_exe(const char *entry) {
- char buf[pathlen + strlen(entry) + 3];
+static Bool match_executable(const char *entry) {
+ char buf[strlen(entry) + strlen(executable_name) + 2];
/* empty PATH element means . */
@@ -1218,16 +1213,24 @@ static const char* find_executable(const
entry = ".";
- snprintf(buf, sizeof(buf), "%s/%s", entry, exec);
+ snprintf(buf, sizeof(buf), "%s/%s", entry, executable_name);
if (access(buf, R_OK|X_OK) == 0) {
- exec = strdup(buf);
- vg_assert(NULL != exec);
- return 1;
- }
- return 0;
+ executable_name = strdup(buf);
+ vg_assert(NULL != executable_name);
+ return True;
}
- scan_colsep(path, match_exe);
+ return False;
+}
+
+static const char* find_executable(const char* exec)
+{
+ vg_assert(NULL != exec);
+ executable_name = exec;
+ if (strchr(executable_name, '/') == NULL) {
+ /* no '/' - we need to search the path */
+ char *path = getenv("PATH");
+ scan_colsep(path, match_executable);
}
- return exec;
+ return executable_name;
}
@@ -2628,4 +2631,11 @@ void VG_(do_sanity_checks) ( Bool force_
/*====================================================================*/
+static int prmap(void *start, void *end, const char *perm, off_t off,
+ int maj, int min, int ino) {
+ printf("mapping %10p-%10p %s %02x:%02x %d\n",
+ start, end, perm, maj, min, ino);
+ return True;
+}
+
int main(int argc, char **argv)
{
@@ -2676,10 +2686,4 @@ int main(int argc, char **argv)
if (0) {
- int prmap(void *start, void *end, const char *perm, off_t off,
- int maj, int min, int ino) {
- printf("mapping %10p-%10p %s %02x:%02x %d\n",
- start, end, perm, maj, min, ino);
- return True;
- }
printf("========== main() ==========\n");
foreach_map(prmap);
--- valgrind/coregrind/vg_mylibc.c #1.74:1.75
@@ -731,15 +731,19 @@ UInt VG_(printf) ( const char *format, .
}
-
/* A general replacement for sprintf(). */
+
+static Char *vg_sprintf_ptr;
+
+static void add_to_vg_sprintf_buf ( Char c )
+{
+ *vg_sprintf_ptr++ = c;
+}
+
UInt VG_(sprintf) ( Char* buf, Char *format, ... )
{
Int ret;
va_list vargs;
- Char *ptr = buf;
- static void add_to_vg_sprintf_buf ( Char c )
- {
- *ptr++ = c;
- }
+
+ vg_sprintf_ptr = buf;
va_start(vargs,format);
--- valgrind/coregrind/vg_scheduler.c #1.153:1.154
@@ -166,5 +166,6 @@ Bool VG_(is_valid_or_empty_tid) ( Thread
*/
ThreadId VG_(first_matching_thread_stack)
- ( Bool (*p) ( Addr stack_min, Addr stack_max ))
+ ( Bool (*p) ( Addr stack_min, Addr stack_max, void* d ),
+ void* d )
{
ThreadId tid, tid_to_skip;
@@ -177,5 +178,5 @@ ThreadId VG_(first_matching_thread_stack
tid = vg_tid_currently_in_baseBlock;
if ( p ( VG_(baseBlock)[VGOFF_(m_esp)],
- VG_(threads)[tid].stack_highest_word) )
+ VG_(threads)[tid].stack_highest_word, d ) )
return tid;
else
@@ -187,5 +188,5 @@ ThreadId VG_(first_matching_thread_stack
if (tid == tid_to_skip) continue;
if ( p ( VG_(threads)[tid].m_esp,
- VG_(threads)[tid].stack_highest_word) )
+ VG_(threads)[tid].stack_highest_word, d ) )
return tid;
}
--- valgrind/coregrind/vg_symtypes.c #1.5:1.6
@@ -662,4 +662,31 @@ static inline Bool is_followable(SymType
}
+/* Result buffer */
+static Char *describe_addr_buf;
+static UInt describe_addr_bufidx;
+static UInt describe_addr_bufsz;
+
+/* Add a character to the result buffer */
+static void describe_addr_addbuf(Char c) {
+ if ((describe_addr_bufidx+1) >= describe_addr_bufsz) {
+ Char *n;
+
+ if (describe_addr_bufsz == 0)
+ describe_addr_bufsz = 8;
+ else
+ describe_addr_bufsz *= 2;
+
+ /* use tool malloc so that the skin client can free it */
+ n = VG_(malloc)(describe_addr_bufsz);
+ if (describe_addr_buf != NULL && describe_addr_bufidx != 0)
+ VG_(memcpy)(n, describe_addr_buf, describe_addr_bufidx);
+ if (describe_addr_buf != NULL)
+ VG_(free)(describe_addr_buf);
+ describe_addr_buf = n;
+ }
+ describe_addr_buf[describe_addr_bufidx++] = c;
+ describe_addr_buf[describe_addr_bufidx] = '\0';
+}
+
#define MAX_PLY 7 /* max depth we go */
#define MAX_ELEMENTS 5000 /* max number of array elements we scan */
@@ -674,32 +701,10 @@ Char *VG_(describe_addr)(ThreadId tid, A
Variable *keeplist; /* container variables */
Variable *found; /* the chain we found */
- Char *buf = NULL; /* the result */
- UInt bufsz = 0;
- UInt bufidx = 0;
Int created=0, freed=0;
Int numvars = MAX_VARS;
- /* add a character to the result buffer */
- void addbuf(Char c) {
- if ((bufidx+1) >= bufsz) {
- Char *n;
-
- if (bufsz == 0)
- bufsz = 8;
- else
- bufsz *= 2;
-
- /* use tool malloc so that the skin client can free it */
- n = VG_(malloc)(bufsz);
- if (buf != NULL && bufidx != 0)
- VG_(memcpy)(n, buf, bufidx);
- if (buf != NULL)
- VG_(free)(buf);
- buf = n;
- }
- buf[bufidx++] = c;
- buf[bufidx] = '\0';
- }
-
+ describe_addr_buf = NULL;
+ describe_addr_bufidx = 0;
+ describe_addr_bufsz = 0;
clear_visited();
@@ -1014,5 +1019,5 @@ Char *VG_(describe_addr)(ThreadId tid, A
found->container = found->container->container;
} else {
- bprintf(addbuf, "&(");
+ bprintf(describe_addr_addbuf, "&(");
ptr = False;
}
@@ -1026,11 +1031,11 @@ Char *VG_(describe_addr)(ThreadId tid, A
*ep++ = '\0';
- bprintf(addbuf, sp);
+ bprintf(describe_addr_addbuf, sp);
if (addr != found->valuep)
- bprintf(addbuf, "+%d", addr - found->valuep);
+ bprintf(describe_addr_addbuf, "+%d", addr - found->valuep);
if (VG_(get_filename_linenum)(eip, file, sizeof(file), &line))
- bprintf(addbuf, " at %s:%d", file, line, addr);
+ bprintf(describe_addr_addbuf, " at %s:%d", file, line, addr);
}
}
@@ -1044,7 +1049,7 @@ Char *VG_(describe_addr)(ThreadId tid, A
if (debug)
- VG_(printf)("returning buf=%s\n", buf);
+ VG_(printf)("returning buf=%s\n", describe_addr_buf);
- return buf;
+ return describe_addr_buf;
}
#endif /* TEST */
--- valgrind/coregrind/vg_syscall.S #1.12:1.13
@@ -118,5 +118,8 @@
movl $__NR_rt_sigreturn, %eax
int $0x80
-
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
##--------------------------------------------------------------------##
##--- end vg_syscall.S ---##
--- valgrind/coregrind/vg_transtab.c #1.27:1.28
@@ -166,17 +166,26 @@ void unchain_tce(TCEntry *tce)
/* Unchain any jumps pointing to a sector we're about to free */
+static Addr sector_base;
+static Addr sector_len;
+
static
-void unchain_sector(Int s, Addr base, UInt len)
-{
- void unchain_site(Addr a) {
+void unchain_site_for_sector(Addr a) {
Addr jmp = VG_(get_jmp_dest)(a);
- if (jmp >= base && jmp < (base+len))
+ if (jmp >= sector_base && jmp < (sector_base+sector_len))
VG_(unchain_jumpsite)(a);
- }
- void _unchain_tce(TCEntry *tce) {
- for_each_jumpsite(tce, unchain_site);
- }
+}
- for_each_tc(s, _unchain_tce);
+static
+void unchain_tce_for_sector(TCEntry *tce) {
+ for_each_jumpsite(tce, unchain_site_for_sector);
+}
+
+static
+void unchain_sector(Int s, Addr base, UInt len)
+{
+ sector_base = base;
+ sector_len = len;
+
+ for_each_tc(s, unchain_tce_for_sector);
}
--- valgrind/coregrind/x86/ume_entry.S #1.2:1.3
@@ -37,2 +37,5 @@
.globl ume_exec_esp
ume_exec_esp: .long 0
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
--- valgrind/helgrind/hg_main.c #1.76:1.77
@@ -1405,8 +1405,6 @@ static void find_mutex_range(Addr start,
#define MARK_DONE (graph_mark+1)
-static Bool check_cycle(const Mutex *start, const LockSet* lockset)
+static Bool check_cycle_inner(const Mutex *mutex, const LockSet *ls)
{
- Bool check_cycle_inner(const Mutex *mutex, const LockSet *ls)
- {
static const Bool debug = False;
Int i;
@@ -1435,5 +1433,8 @@ static Bool check_cycle(const Mutex *sta
return False;
- }
+}
+
+static Bool check_cycle(const Mutex *start, const LockSet* lockset)
+{
graph_mark += 2; /* clear all marks */
@@ -1582,4 +1583,10 @@ static void set_mutex_state(Mutex *mutex
/*------------------------------------------------------------*/
+/* only clean up dead mutexes */
+static
+Bool cleanmx(Mutex *mx) {
+ return mx->state == MxDead;
+}
+
static
void set_address_range_state ( Addr a, UInt len /* in bytes */,
@@ -1588,10 +1595,4 @@ void set_address_range_state ( Addr a, U
Addr end;
- /* only clean up dead mutexes */
- Bool cleanmx(Mutex *mx) {
- return mx->state == MxDead;
- }
-
-
# if DEBUG_MAKE_ACCESSES
VG_(printf)("make_access: 0x%x, %u, status=%u\n", a, len, status);
@@ -1871,4 +1872,14 @@ void* SK_(calloc) ( Int nmemb, Int size
}
+static ThreadId deadmx_tid;
+
+static
+Bool deadmx(Mutex *mx) {
+ if (mx->state != MxDead)
+ set_mutex_state(mx, MxDead, deadmx_tid);
+
+ return False;
+}
+
static
void die_and_free_mem ( ThreadId tid, HG_Chunk* hc,
@@ -1878,11 +1889,4 @@ void die_and_free_mem ( ThreadId tid, HG
Addr end = start + hc->size;
- Bool deadmx(Mutex *mx) {
- if (mx->state != MxDead)
- set_mutex_state(mx, MxDead, tid);
-
- return False;
- }
-
/* Remove hc from the malloclist using prev_chunks_next_ptr to
avoid repeating the hash table lookup. Can't remove until at least
@@ -1909,4 +1913,5 @@ void die_and_free_mem ( ThreadId tid, HG
/* mark all mutexes in range dead */
+ deadmx_tid = tid;
find_mutex_range(start, end, deadmx);
}
@@ -2379,4 +2384,13 @@ void clear_HelgrindError ( HelgrindError
putting the result in ai. */
+/* Callback for searching malloc'd and free'd lists */
+static Bool addr_is_in_block(VgHashNode *node, void *ap)
+{
+ HG_Chunk* hc2 = (HG_Chunk*)node;
+ Addr a = *(Addr *)ap;
+
+ return (hc2->data <= a && a < hc2->data + hc2->size);
+}
+
static void describe_addr ( Addr a, AddrInfo* ai )
{
@@ -2384,18 +2398,4 @@ static void describe_addr ( Addr a, Addr
Int i;
- /* Nested functions, yeah. Need the lexical scoping of 'a'. */
-
- /* Closure for searching thread stacks */
- Bool addr_is_in_bounds(Addr stack_min, Addr stack_max)
- {
- return (stack_min <= a && a <= stack_max);
- }
- /* Closure for searching malloc'd and free'd lists */
- Bool addr_is_in_block(VgHashNode *node)
- {
- HG_Chunk* hc2 = (HG_Chunk*)node;
- return (hc2->data <= a && a < hc2->data + hc2->size);
- }
-
/* Search for it in segments */
{
@@ -2432,5 +2432,5 @@ static void describe_addr ( Addr a, Addr
/* Search for a currently malloc'd block which might bracket it. */
- hc = (HG_Chunk*)VG_(HT_first_match)(hg_malloc_list, addr_is_in_block);
+ hc = (HG_Chunk*)VG_(HT_first_match)(hg_malloc_list, addr_is_in_block, &a);
if (NULL != hc) {
ai->akind = Mallocd;
--- valgrind/include/vg_skin.h.base #1.22:1.23
@@ -361,5 +361,6 @@
VG_INVALID_THREADID if none match. */
extern ThreadId VG_(first_matching_thread_stack)
- ( Bool (*p) ( Addr stack_min, Addr stack_max ));
+ ( Bool (*p) ( Addr stack_min, Addr stack_max, void* d ),
+ void* d );
@@ -1714,12 +1715,15 @@
/* Returns first node that matches predicate `p', or NULL if none do.
- Extra arguments can be implicitly passed to `p' using nested functions;
- see memcheck/mc_errcontext.c for an example. */
+ Extra arguments can be implicitly passed to `p' using `d' which is an
+ opaque pointer passed to `p' each time it is called. */
extern VgHashNode* VG_(HT_first_match) ( VgHashTable t,
- Bool (*p)(VgHashNode*) );
+ Bool (*p)(VgHashNode*, void*),
+ void* d );
-/* Applies a function f() once to each node. Again, nested functions
- can be very useful. */
-extern void VG_(HT_apply_to_all_nodes)( VgHashTable t, void (*f)(VgHashNode*) );
+/* Applies a function f() once to each node. Again, `d' can be used
+ to pass extra information to the function. */
+extern void VG_(HT_apply_to_all_nodes)( VgHashTable t,
+ void (*f)(VgHashNode*, void*),
+ void* d );
/* Destroy a table. */
--- valgrind/massif/ms_main.c #1.10:1.11
@@ -857,8 +857,7 @@ static UInt curr_census = 0;
// Must return False so that all stacks are traversed
-static UInt count_stack_size_counter;
-static Bool count_stack_size( Addr stack_min, Addr stack_max )
+static Bool count_stack_size( Addr stack_min, Addr stack_max, void *cp )
{
- count_stack_size_counter += (stack_max - stack_min);
+ *(UInt *)cp += (stack_max - stack_min);
return False;
}
@@ -1080,8 +1079,7 @@ static void hp_census(void)
// Stack(s) ---------------------------------------------------------
if (clo_stacks) {
- count_stack_size_counter = sigstacks_space;
+ census->stacks_space = sigstacks_space;
// slightly abusing this function
- VG_(first_matching_thread_stack)( count_stack_size );
- census->stacks_space = count_stack_size_counter;
+ VG_(first_matching_thread_stack)( count_stack_size, &census->stacks_space );
i++;
}
--- valgrind/memcheck/mac_malloc_wrappers.c #1.11:1.12
@@ -117,5 +117,6 @@ static void add_to_freed_queue ( MAC_Chu
/* Return the first shadow chunk satisfying the predicate p. */
-MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk) ( Bool (*p)(MAC_Chunk*) )
+MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk) ( Bool (*p)(MAC_Chunk*, void*),
+ void* d )
{
MAC_Chunk* mc;
@@ -124,5 +125,5 @@ MAC_Chunk* MAC_(first_matching_freed_MAC
them around for a while... */
for (mc = freed_list_start; mc != NULL; mc = mc->next)
- if (p(mc))
+ if (p(mc, d))
return mc;
@@ -440,12 +441,8 @@ void MAC_(create_mempool)(Addr pool, UIn
}
-void MAC_(destroy_mempool)(Addr pool)
+static void destroy_mempool_nuke_chunk(VgHashNode *node, void *d)
{
- MAC_Mempool* mp;
- MAC_Mempool** prev_next;
-
- void nuke_chunk(VgHashNode *node)
- {
MAC_Chunk *mc = (MAC_Chunk *)node;
+ MAC_Mempool *mp = (MAC_Mempool *)d;
/* Note: ban redzones again -- just in case user de-banned them
@@ -454,7 +451,13 @@ void MAC_(destroy_mempool)(Addr pool)
MAC_(die_mem_heap)(mc->data, mc->size );
MAC_(ban_mem_heap)(mc->data+mc->size, mp->rzB );
- }
+}
- mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list), (UInt)pool,
+void MAC_(destroy_mempool)(Addr pool)
+{
+ MAC_Mempool* mp;
+ MAC_Mempool** prev_next;
+
+ mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list),
+ (UInt)pool,
(VgHashNode***)&prev_next );
@@ -467,5 +470,5 @@ void MAC_(destroy_mempool)(Addr pool)
*prev_next = mp->next;
- VG_(HT_apply_to_all_nodes)(mp->chunks, nuke_chunk);
+ VG_(HT_apply_to_all_nodes)(mp->chunks, destroy_mempool_nuke_chunk, mp);
VG_(HT_destruct)(mp->chunks);
@@ -521,24 +524,36 @@ void MAC_(mempool_free)(Addr pool, Addr
}
+typedef
+ struct {
+ UInt nblocks;
+ UInt nbytes;
+ }
+ MallocStats;
+
+static void malloc_stats_count_chunk(VgHashNode* node, void* d) {
+ MAC_Chunk* mc = (MAC_Chunk*)node;
+ MallocStats *ms = (MallocStats *)d;
+
+ ms->nblocks ++;
+ ms->nbytes += mc->size;
+}
+
void MAC_(print_malloc_stats) ( void )
{
- UInt nblocks = 0, nbytes = 0;
+ MallocStats ms;
- /* Mmm... more lexical scoping */
- void count_one_chunk(VgHashNode* node) {
- MAC_Chunk* mc = (MAC_Chunk*)node;
- nblocks ++;
- nbytes += mc->size;
- }
+ ms.nblocks = 0;
+ ms.nbytes = 0;
+ /* Mmm... more lexical scoping */
if (VG_(clo_verbosity) == 0)
return;
/* Count memory still in use. */
- VG_(HT_apply_to_all_nodes)(MAC_(malloc_list), count_one_chunk);
+ VG_(HT_apply_to_all_nodes)(MAC_(malloc_list), malloc_stats_count_chunk, &ms);
VG_(message)(Vg_UserMsg,
"malloc/free: in use at exit: %d bytes in %d blocks.",
- nbytes, nblocks);
+ ms.nbytes, ms.nblocks);
VG_(message)(Vg_UserMsg,
"malloc/free: %d allocs, %d frees, %u bytes allocated.",
--- valgrind/memcheck/mac_needs.c #1.27:1.28
@@ -345,4 +345,26 @@ void MAC_(pp_shared_SkinError) ( Error*
Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
+/* Callback for searching thread stacks */
+static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
+{
+ Addr a = *(Addr *)ap;
+
+ return (stack_min <= a && a <= stack_max);
+}
+
+/* Callback for searching free'd list */
+static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
+{
+ Addr a = *(Addr *)ap;
+
+ return VG_(addr_is_in_block)( a, mc->data, mc->size );
+}
+
+/* Callback for searching malloc'd lists */
+static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
+{
+ return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
+}
+
/* Describe an address as best you can, for error messages,
putting the result in ai. */
@@ -352,22 +374,4 @@ static void describe_addr ( Addr a, Addr
ThreadId tid;
- /* Nested functions, yeah. Need the lexical scoping of 'a'. */
-
- /* Closure for searching thread stacks */
- Bool addr_is_in_bounds(Addr stack_min, Addr stack_max)
- {
- return (stack_min <= a && a <= stack_max);
- }
- /* Closure for searching free'd list */
- Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc)
- {
- return VG_(addr_is_in_block)( a, mc->data, mc->size );
- }
- /* Closure for searching malloc'd lists */
- Bool addr_is_in_HashNode(VgHashNode* sh_ch)
- {
- return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch );
- }
-
/* Perhaps it's a user-def'd block ? (only check if requested, though) */
if (NULL != MAC_(describe_addr_supp)) {
@@ -376,5 +380,5 @@ static void describe_addr ( Addr a, Addr
}
/* Perhaps it's on a thread's stack? */
- tid = VG_(first_matching_thread_stack)(addr_is_in_bounds);
+ tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
if (tid != VG_INVALID_THREADID) {
ai->akind = Stack;
@@ -383,5 +387,5 @@ static void describe_addr ( Addr a, Addr
}
/* Search for a recently freed block which might bracket it. */
- sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk);
+ sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
if (NULL != sc) {
ai->akind = Freed;
@@ -392,5 +396,5 @@ static void describe_addr ( Addr a, Addr
}
/* Search for a currently malloc'd block which might bracket it. */
- sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode);
+ sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
if (NULL != sc) {
ai->akind = Mallocd;
--- valgrind/memcheck/mac_shared.h #1.18:1.19
@@ -342,5 +342,5 @@ extern void MAC_(record_illegal_mempool_
extern void MAC_(pp_shared_SkinError) ( Error* err);
-extern MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk)( Bool (*p)(MAC_Chunk*) );
+extern MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk)( Bool (*p)(MAC_Chunk*, void*), void* d );
extern void MAC_(common_pre_clo_init) ( void );
--- valgrind/memcheck/mc_clientreqs.c #1.20:1.21
@@ -125,4 +125,12 @@ void MC_(show_client_block_stats) ( void
}
+static Bool find_addr(VgHashNode* sh_ch, void* ap)
+{
+ MAC_Chunk *m = (MAC_Chunk*)sh_ch;
+ Addr a = *(Addr*)ap;
+
+ return VG_(addr_is_in_block)(a, m->data, m->size);
+}
+
Bool MC_(client_perm_maybe_describe)( Addr a, AddrInfo* ai )
{
@@ -145,11 +153,5 @@ Bool MC_(client_perm_maybe_describe)( Ad
MAC_Chunk *mc;
- Bool find_addr(VgHashNode* sh_ch)
- {
- MAC_Chunk *m = (MAC_Chunk*)sh_ch;
- return VG_(addr_is_in_block)(a, m->data, m->size);
- }
-
- mc = (MAC_Chunk*)VG_(HT_first_match)(mp->chunks, find_addr);
+ mc = (MAC_Chunk*)VG_(HT_first_match)(mp->chunks, find_addr, &a);
if(mc != NULL) {
ai->akind = UserG;
--- valgrind/memcheck/mc_helpers.S #1.8:1.9
@@ -59,7 +59,9 @@
popal
ret
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
##--------------------------------------------------------------------##
##--- end mc_helpers.S ---##
##--------------------------------------------------------------------##
-
|
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 16:02:11
|
Hi, Currently, for tools replacing malloc (eg. Memcheck), if a malloc call fails, Valgrind aborts. (Actually, an assertion failure occurs.) I figure that client calls to malloc should fail and return 0 like the system malloc in this case. That's what happens with tools that don't replace the system malloc (eg. Nulgrind). Does anyone object to this proposed behaviour? N |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 13:56:10
|
On Sun, 27 Jun 2004, Julian Seward wrote:
>> Changed (client-heap-size : client-map-seg-size) ratio from 3:1 to 1:2.
>> As a result, can now mmap much more memory (eg. for Memcheck, 850MB up from
>> 250MB, for Nulgrind 1750MB up from 700MB).
>
> That's good. However, is tht 850MB all in one lump, or in a lot
> of small pieces? Memcheck gives quite a large overhead per
> allocation (100+ bytes?), and I wonder if that has any influence
> on the optimal settings? For stuff like KDE and OpenOffice the
> average allocation size is small (50-100 bytes) so perhaps
> it's worth adjusting the parameters optimally for that?
The 850MB would be all in one lump if it wasn't for stupid
/lib/tls/libc.so sitting fixed at 0x42000000. As it is, the biggest map I
can create are (before and after my change):
before after
------ -----
Memcheck 266MB 614MB
Addrcheck 625MB 1444MB
Nulgrind 703MB 1757MB
But I don't see how that's related to KDE having small allocation sizes...
N
|
|
From: Tom H. <th...@cy...> - 2004-06-27 13:29:58
|
In message <Pin...@ba...>
Darius Ivanauskas <da...@ge...> wrote:
> I just wonder why in the coregrind/vg_libpthread.c and
> coregrind/arch/x86-linux/vg_libpthread.c, in the function
> pthread_rwlock_unlock(...) there are dublicated line:
>
> rwl = rw_remap ( orig );
> rwl = rw_remap ( orig );
It's just a bug. It shouldn't any ill effects, but I've removed the
duplicate call anyway. Note that the arch/x86-linux version isn't
actually used at the moment.
> And another question:
>
> I looked at the vg_libpthread.c implementation for semaphores - they have
> se_unmap(...) function for clear out place in the se_remap_* array. I dont
> know if i'm right but it seems that it should work only for the last
> (se_remap_used) member released. Otherwise you are getting hole in the
> array - and the last member which is now in the position [se_remap_used+1]
> gets inaccessible. It is nevermind if im right or wrong, i just want to
> ask are you going to implement similar mechanism of reusing rw_remap_*
> entries because when test program allocates rw_locks dynamically i'm
> getting "VG_N_RWLOCKS is too low." very soon :(
The se_unmap function no longer exists as the semaphore mapping scheme
was changed a while ago to remove the limit on the number of semaphores.
It sounds like a similar rework of rwlocks might be helpful to you?
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Tom H. <th...@cy...> - 2004-06-27 13:26:49
|
CVS commit by thughes:
Removed duplicate call to rw_remap.
M +0 -1 vg_libpthread.c 1.157
--- valgrind/coregrind/vg_libpthread.c #1.156:1.157
@@ -3161,5 +3161,4 @@ int pthread_rwlock_unlock ( pthread_rwlo
if (0) printf ("pthread_rwlock_unlock\n");
rwl = rw_remap ( orig );
- rwl = rw_remap ( orig );
res = __pthread_mutex_lock(&rwl->mx);
my_assert(res == 0);
|
|
From: Julian S. <js...@ac...> - 2004-06-27 12:54:16
|
> Changed (client-heap-size : client-map-seg-size) ratio from 3:1 to 1:2. > As a result, can now mmap much more memory (eg. for Memcheck, 850MB up from > 250MB, for Nulgrind 1750MB up from 700MB). That's good. However, is tht 850MB all in one lump, or in a lot of small pieces? Memcheck gives quite a large overhead per allocation (100+ bytes?), and I wonder if that has any influence on the optimal settings? For stuff like KDE and OpenOffice the average allocation size is small (50-100 bytes) so perhaps it's worth adjusting the parameters optimally for that? J |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 12:38:24
|
CVS commit by nethercote:
typo
M +1 -1 vg_errcontext.c 1.54
--- valgrind/coregrind/vg_errcontext.c #1.53:1.54
@@ -239,5 +239,5 @@ static void gen_suppression(Error* err)
} else {
VG_(printf)(" ???:??? "
- "# unknown, suppression will not work, sorry)\n");
+ "# unknown, suppression will not work, sorry\n");
}
i++;
|
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 12:32:54
|
On Sun, 27 Jun 2004, Tom Hughes wrote: > I thought this was something to do with prelinking as it doesn't > seem to happen on my FC2 box where prelinking is turned off, but > it doesn't happen on an FC1 box with prelinking on either. > > It does happen on my RH9 box at work where I think libc is prelinked > although there is no daily cronjob to update prelinking like there > is in Fedora. > > Looking at libc with objdump -p shows that the virtual addresses > for each section are set to those high numbers on RH9 but are set > to zero on the FC boxes. I see, mine is a RH9 box. Thanks for the info. N |
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 12:30:20
|
CVS commit by nethercote:
Printing slightly more informative message when mmap fails.
M +3 -1 vg_symtab2.c 1.80
--- valgrind/coregrind/vg_symtab2.c #1.79:1.80
@@ -1189,5 +1189,7 @@ Bool vg_read_lib_symbols ( SegInfo* si )
if (oimage == ((Addr)(-1))) {
VG_(message)(Vg_UserMsg,
- "mmap failed on %s", si->filename );
+ "warning: mmap failed on %s", si->filename );
+ VG_(message)(Vg_UserMsg,
+ " no symbols or debug info loaded" );
return False;
}
|
|
From: Nicholas N. <nj...@ca...> - 2004-06-27 12:30:02
|
CVS commit by nethercote:
Changed (client-heap-size : client-map-seg-size) ratio from 3:1 to 1:2.
As a result, can now mmap much more memory (eg. for Memcheck, 850MB up from
250MB, for Nulgrind 1750MB up from 700MB). The heap is smaller, but that
doesn't matter much, since programs use brk() directly only rarely, and
malloc() falls back on mmap() if brk() fails anyway.
Also changed the debug info printing for memory layout slightly.
M +31 -16 vg_main.c 1.165
--- valgrind/coregrind/vg_main.c #1.164:1.165
@@ -84,5 +84,6 @@
#define CLIENT_SIZE_MULTIPLE (1 * 1024*1024)
-#define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
+/* Proportion of client space for its heap (rest is for mmaps + stack) */
+#define CLIENT_HEAP_PROPORTION 0.333
/*====================================================================*/
@@ -496,13 +497,4 @@ static void layout_client_space(Addr arg
VG_(valgrind_end) = ROUNDUP(argc_addr, 0x10000); /* stack */
- if (0)
- printf("client base: %x\n"
- "valgrind base--end: %x--%x (%x)\n"
- "valgrind mmap end: %x\n\n",
- VG_(client_base),
- VG_(valgrind_base), VG_(valgrind_end),
- VG_(valgrind_end) - VG_(valgrind_base),
- VG_(valgrind_mmap_end));
-
as_pad((void *)VG_(client_base), (void *)VG_(valgrind_base));
}
@@ -518,4 +510,7 @@ static void layout_remaining_space(float
VG_(client_end) = VG_(client_base) + client_size;
VG_(client_mapbase) = PGROUNDDN((client_size/4)*3); /* where !FIXED mmap goes */
+
+ /* where !FIXED mmap goes */
+ VG_(client_mapbase) = PGROUNDDN((addr_t)(client_size * CLIENT_HEAP_PROPORTION));
VG_(client_trampoline_code) = VG_(client_end) - VKI_BYTES_PER_PAGE;
@@ -523,11 +518,27 @@ static void layout_remaining_space(float
VG_(shadow_end) = VG_(shadow_base) + shadow_size;
+#define SEGSIZE(a,b) ((VG_(b) - VG_(a))/(1024*1024))
+
if (0)
- printf("client base--end: %x--%x (%x)\n"
- "client mapbase: %x\n"
- "shadow base--end: %x--%x (%x)\n\n",
- VG_(client_base), VG_(client_end), client_size,
- VG_(client_mapbase),
- VG_(shadow_base), VG_(shadow_end), shadow_size);
+ VG_(printf)(
+ "client_base %8x (%dMB)\n"
+ "client_mapbase %8x (%dMB)\n"
+ "client_end %8x (%dMB)\n"
+ "shadow_base %8x (%dMB)\n"
+ "shadow_end %8x (%dMB)\n"
+ "valgrind_base %8x (%dMB)\n"
+ "valgrind_mmap_end %8x (%dMB)\n"
+ "valgrind_end %8x\n",
+ VG_(client_base), SEGSIZE(client_base, client_mapbase),
+ VG_(client_mapbase), SEGSIZE(client_mapbase, client_end),
+ VG_(client_end), SEGSIZE(client_end, shadow_base),
+ VG_(shadow_base), SEGSIZE(shadow_base, shadow_end),
+ VG_(shadow_end), SEGSIZE(shadow_end, valgrind_base),
+ VG_(valgrind_base), SEGSIZE(valgrind_base, valgrind_mmap_end),
+ VG_(valgrind_mmap_end), SEGSIZE(valgrind_mmap_end, valgrind_end),
+ VG_(valgrind_end)
+ );
+
+#undef SEGSIZE
// Ban redzone
@@ -574,4 +585,6 @@ static char* get_file_clo(char* dir)
}
+#define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
+
static Int count_args(char* s)
{
@@ -610,4 +623,6 @@ static char** copy_args( char* s, char**
}
+#undef ISSPACE
+
// Augment command line with arguments from environment and .valgrindrc
// files.
|
|
From: Julian S. <js...@ac...> - 2004-06-27 12:14:12
|
On Sunday 27 June 2004 12:39, Nicholas Nethercote wrote: > On Sun, 27 Jun 2004, Tom Hughes wrote: > > Does anybody have any particular objections to removing the use of > > nested functions in valgrind? I haven't looked at it in any detail > > yet and I know that at least some of them make use of stack variables > > from the parent function which makes removing them non-trivial but > > it could be done. [...] > > Another advantage of removing the nested functions is that the practice is > one of the things that prevents Valgrind from being compiled with the > Intel C compiler. It's the only thing, I think, that prevents building with Icc. At some point in the past I did exactly this nested fn removal, and the result works with Icc. It's an hour's work or so, not a big deal. It'll make you a Hero(tm) with the Icc people, who have asked more than once to make valgrind icc-compilable. Probably a good thing to do. Another reason is Icc uses a completely different C/C++ front end from gcc/g++ and so produces a whole different set of warnings. Ideally V should compile cleanly with both compilers. J |
|
From: Tom H. <th...@cy...> - 2004-06-27 12:07:33
|
In message <Pin...@he...>
Nicholas Nethercote <nj...@ca...> wrote:
> On my machine, it seems that /lib/tls/libc.so is always put at address
> 0x42000000. All other .so files seem to move around and get put near the
> base of the mmap-segment. Here's an example -- with Memcheck, here the
> mmap-segment starts at 0x1b8e4000, and all the other .so files are put
> around there, but /lib/tlc/libc.so isn't:
I thought this was something to do with prelinking as it doesn't
seem to happen on my FC2 box where prelinking is turned off, but
it doesn't happen on an FC1 box with prelinking on either.
It does happen on my RH9 box at work where I think libc is prelinked
although there is no daily cronjob to update prelinking like there
is in Fedora.
Looking at libc with objdump -p shows that the virtual addresses
for each section are set to those high numbers on RH9 but are set
to zero on the FC boxes.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|