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
(11) |
2
(13) |
3
(7) |
|
4
(9) |
5
(23) |
6
(19) |
7
(18) |
8
(2) |
9
(7) |
10
(21) |
|
11
(13) |
12
|
13
(8) |
14
(17) |
15
(19) |
16
(25) |
17
(43) |
|
18
(22) |
19
(12) |
20
(19) |
21
(12) |
22
(9) |
23
(12) |
24
(5) |
|
25
(16) |
26
(25) |
27
(24) |
28
(19) |
29
(26) |
30
(25) |
31
(6) |
|
From: Jeremy F. <je...@go...> - 2004-07-15 23:33:38
|
On Thu, 2004-07-15 at 23:44 +0100, Tom Hughes wrote: > Somebody did manage to reach that code however, although I'm not > quite sure how. See bug 80932 where I was also trying to work out > what that bit in the SEGV handler was for. Hm. The code should probably check to see if the tool defines init_shadow_page, and just pass it through like a normal SIGSEGV if not. But the client could only get here using --pointercheck=no anyway, so it means that all of Valgrind is vulnerable to wild pointers. J |
|
From: Jeremy F. <je...@go...> - 2004-07-15 23:27:05
|
On Thu, 2004-07-15 at 23:20 +0100, Nicholas Nethercote wrote: > Hi, > > I'm looking at how new shadow memory pages are allocated when necessary. > It's weird, there seem to be two mechanisms for this. > > First, every tool that uses shadow memory (memcheck, addrcheck, helgrind) > is very careful to call their respective ENSURE_MAPPABLE macros before > accessing shadow memory, which checks if there is a shadow page for the > address and allocates a new one if not. > > That would seem to be enough. But in vg_signals.c, there's a bit in the > SEGV handler with this comment: > > /* If there's a fault within the shadow memory range, and it > is a permissions fault, then it means that the client is > using some memory which had not previously been used. > This catches those faults, makes the memory accessible, > and calls the tool to initialize that page. > */ > > This calls VG_(init_shadow_range)(), which calls the init_shadow_page > trackable event, telling the tool to make itself a shadow page. But none > of the tools actually provide the necessary init_shadow_page callback. > > This 2nd mechanism is simply not being used; I tried removing it and the > entire regression test suite ran fine. > > So I see two options: > > 1. Just rely on the currently used ENSURE_MAPPABLE macros in the tools. > This would allow a couple of functions to be removed or simplified, saving > 50 lines of code. > > 2. Just rely on the SEGV handling bit. This would require adding the > init_shadow_page callback to each of the tools. The advantage with this > option is that it might make things a bit faster, since we wouldn't have > to do ENSURE_MAPPABLE (which is a comparison like "x == y[z >> 16]") for > every shadow memory access. (But it might make no discernible difference, > since this is just arithmetic which might be swamped by the associated > memory accesses. In which case option (1) is clearly better.) > > Any opinions? Jeremy, do you know why both these mechanisms are present? Yup, I put them there. The SIGSEGV mechanism is a result of a discussion we had ages ago about direct-mapping the shadow memory from the client address - basically so that there's a simple addr*scale+offset to map from a client address to a shadow address. The theory was that this computation is simple enough to do inline, so a number of the shadow memory accesses wouldn't require calls to helpers. It would also be, in theory, faster because it removes a memory reference indirecting through the page. There are a couple of problems in practice. The direct-mapped approach also needs a bounds check to make sure that the pointer is actually a user-address-space pointer - if it isn't the computed shadow pointer could end up in the middle of the Valgrind address space. This bounds check approximately doubles the size of the address calculation, and probably undermines any performance improvement. Which leads the other problem: I never actually measured a clear performance improvement. I'm not really sure why. It wasn't because of the overhead of the SIGSEGV handler, since the fault rate dropped a lot once the working set was established. But I was never really sure of what it did to cache access patterns, and the address calculation often ended up being quite fiddly. So, no, nothing is using this at the moment. It looks like it should be a useful mechanism, but it isn't clear that any of the existing tools can easily use it. On the other hand, there's no huge performance hit, so if the code turns out to be simpler with direct mapping, it might be the way to go (ie, it isn't worth changing existing tools, but it might make sense for new ones). J |
|
From: Tom H. <th...@cy...> - 2004-07-15 23:13:48
|
CVS commit by thughes:
Implement support for the async I/O system calls in 2.6 kernels. This
requires padding of the address space around calls to io_setup in order
to constrain the kernel's choice of address for the I/O context.
Based on patch from Scott Smith <sco...@ge...> with various
enhancements, this fixes bug #83060.
M +3 -0 vg_include.h 1.202
M +56 -0 vg_memory.c 1.60
M +141 -0 vg_syscalls.c 1.110
--- valgrind/coregrind/vg_include.h #1.201:1.202
@@ -1605,4 +1605,7 @@ extern Bool VG_(seg_contains)(const
extern Bool VG_(seg_overlaps)(const Segment *s, Addr ptr, UInt size);
+extern void VG_(pad_address_space)(void);
+extern void VG_(unpad_address_space)(void);
+
extern __attribute__((regparm(1)))
void VG_(unknown_esp_update) ( Addr new_ESP );
--- valgrind/coregrind/vg_memory.c #1.59:1.60
@@ -546,4 +546,60 @@ Addr VG_(find_map_space)(Addr addr, UInt
}
+void VG_(pad_address_space)(void)
+{
+ Addr addr = VG_(client_base);
+ Segment *s = VG_(SkipNode_First)(&sk_segments);
+ UInt args[6];
+ Addr ret;
+
+ args[2] = 0;
+ args[3] = VKI_MAP_FIXED | VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS;
+ args[4] = -1;
+ args[5] = 0;
+
+ while (s && addr < VG_(valgrind_end)) {
+ if (addr < s->addr) {
+ args[0] = (UInt)addr;
+ args[1] = s->addr - addr;
+
+ ret = VG_(do_syscall)(__NR_mmap, (UInt)args);
+ }
+
+ addr = s->addr + s->len;
+ s = VG_(SkipNode_Next)(&sk_segments, s);
+ }
+
+ if (addr < VG_(valgrind_end)) {
+ args[0] = (UInt)addr;
+ args[1] = VG_(valgrind_end) - addr;
+
+ ret = VG_(do_syscall)(__NR_mmap, (UInt)args);
+ }
+
+ return;
+}
+
+void VG_(unpad_address_space)(void)
+{
+ Addr addr = VG_(client_base);
+ Segment *s = VG_(SkipNode_First)(&sk_segments);
+ Int ret;
+
+ while (s && addr < VG_(valgrind_end)) {
+ if (addr < s->addr) {
+ ret = VG_(do_syscall)(__NR_munmap, (UInt)addr, s->addr - addr);
+ }
+
+ addr = s->addr + s->len;
+ s = VG_(SkipNode_Next)(&sk_segments, s);
+ }
+
+ if (addr < VG_(valgrind_end)) {
+ ret = VG_(do_syscall)(__NR_munmap, (UInt)addr, VG_(valgrind_end) - addr);
+ }
+
+ return;
+}
+
Segment *VG_(find_segment)(Addr a)
{
--- valgrind/coregrind/vg_syscalls.c #1.109:1.110
@@ -5359,4 +5359,138 @@ PREALIAS(rt_sigpending, sigpending);
POSTALIAS(rt_sigpending, sigpending);
+PRE(io_setup)
+{
+ UInt size;
+ Addr addr;
+
+ /* long io_setup (unsigned nr_events, aio_context_t *ctxp); */
+ MAYBE_PRINTF("io_setup ( %ul, %p )\n",arg1,arg2);
+ SYSCALL_TRACK( pre_mem_write, tid, "io_setup(ctxp)",
+ arg2, sizeof(vki_aio_context_t) );
+
+ size = PGROUNDUP(sizeof(vki_aio_ring) + arg1 * sizeof(vki_io_event));
+ addr = VG_(find_map_space)(0, size, True);
+ VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_EXEC, SF_FIXED);
+
+ VG_(pad_address_space)();
+ res = VG_(do_syscall)(SYSNO, arg1, arg2);
+ VG_(unpad_address_space)();
+
+ if (res == 0) {
+ vki_aio_ring *r = *(vki_aio_ring **)arg2;
+
+ vg_assert(addr == (Addr)r);
+ vg_assert(valid_client_addr(addr, size, tid, "io_setup"));
+
+ VG_TRACK( new_mem_mmap, addr, size, True, True, False );
+ VG_TRACK( post_mem_write, arg2, sizeof(vki_aio_context_t) );
+ }
+ else {
+ VG_(unmap_range)(addr, size);
+ }
+}
+
+PRE(io_destroy)
+{
+ Segment *s = VG_(find_segment)(arg1);
+ vki_aio_ring *r = *(vki_aio_ring **)arg1;
+ UInt size = PGROUNDUP(sizeof(vki_aio_ring) + r->nr * sizeof(vki_io_event));
+
+ /* long io_destroy (aio_context_t ctx); */
+ MAYBE_PRINTF("io_destroy ( %ul )\n",arg1);
+
+ res = VG_(do_syscall)(SYSNO, arg1);
+
+ if (res == 0 && s != NULL && VG_(seg_contains)(s, arg1, size)) {
+ VG_TRACK( die_mem_munmap, arg1, size );
+ VG_(unmap_range)(arg1, size);
+ }
+}
+
+PRE(io_getevents)
+{
+ /* long io_getevents (aio_context_t ctx_id, long min_nr, long nr,
+ struct io_event *events, struct timespec *timeout); */
+ MAYBE_PRINTF("io_getevents ( %ul, %l, %l, %p, %p )\n",arg1,arg2,arg3,arg4,arg5);
+ if (arg3 > 0)
+ SYSCALL_TRACK( pre_mem_write, tid, "io_getevents(events)",
+ arg4, sizeof(vki_io_event)*arg3 );
+ if (arg5 != (UInt)NULL)
+ SYSCALL_TRACK( pre_mem_read, tid, "io_getevents(timeout)",
+ arg5, sizeof(struct timespec));
+}
+
+POST(io_getevents)
+{
+ int i;
+
+ if (res > 0) {
+ VG_TRACK( post_mem_write, arg4, sizeof(vki_io_event)*res );
+ for (i = 0; i < res; i++) {
+ const vki_io_event *vev = ((vki_io_event *)arg4) + i;
+ const vki_iocb *cb = (vki_iocb *)(UInt)vev->obj;
+
+ switch (cb->aio_lio_opcode) {
+ case VKI_IOCB_CMD_PREAD:
+ if (vev->result > 0)
+ VG_TRACK( post_mem_write, cb->aio_buf, vev->result );
+ break;
+
+ case VKI_IOCB_CMD_PWRITE:
+ break;
+
+ default:
+ VG_(message)(Vg_DebugMsg,"Warning: unhandled io_getevents opcode: %u\n",cb->aio_lio_opcode);
+ break;
+ }
+ }
+ }
+}
+
+PRE(io_submit)
+{
+ int i;
+
+ /* long io_submit (aio_context_t ctx_id, long nr, struct iocb **iocbpp); */
+ MAYBE_PRINTF("io_submit( %ul, %l, %p )\n",arg1,arg2,arg3);
+ SYSCALL_TRACK( pre_mem_read, tid, "io_submit(iocbpp)",
+ arg3, sizeof(vki_iocb *)*arg2 );
+ for (i = 0; i < arg2; i++) {
+ vki_iocb *cb = ((vki_iocb **)arg3)[i];
+ SYSCALL_TRACK( pre_mem_read, tid, "io_submit(iocb)",
+ (UInt)cb, sizeof(vki_iocb) );
+ switch (cb->aio_lio_opcode) {
+ case VKI_IOCB_CMD_PREAD:
+ SYSCALL_TRACK( pre_mem_write, tid, "io_submit(PREAD)",
+ cb->aio_buf, cb->aio_nbytes );
+ break;
+
+ case VKI_IOCB_CMD_PWRITE:
+ SYSCALL_TRACK( pre_mem_read, tid, "io_submit(PWRITE)",
+ cb->aio_buf, cb->aio_nbytes );
+ break;
+
+ default:
+ VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",cb->aio_lio_opcode);
+ break;
+ }
+ }
+}
+
+PRE(io_cancel)
+{
+ /* long io_cancel (aio_context_t ctx_id, struct iocb *iocb,
+ struct io_event *result); */
+ MAYBE_PRINTF("io_cancel( %ul, %p, %p )\n",arg1,arg2,arg3);
+ SYSCALL_TRACK( pre_mem_read, tid, "io_cancel(iocb)",
+ arg2, sizeof(vki_iocb) );
+ SYSCALL_TRACK( pre_mem_write, tid, "io_cancel(result)",
+ arg3, sizeof(vki_io_event) );
+}
+
+POST(io_cancel)
+{
+ VG_TRACK( post_mem_write, arg3, sizeof(vki_io_event) );
+}
#undef SYSNO
@@ -5415,4 +5549,7 @@ static const struct sys_info special_sys
SYSB_(mremap, False),
+ SYSB_(io_setup, False),
+ SYSB_(io_destroy, False),
+
#if SIGNAL_SIMULATION
SYSBA(sigaltstack, False),
@@ -5627,4 +5764,8 @@ static const struct sys_info sys_info[]
SYSBA(getitimer, True), /* not blocking, but must run in LWP context */
+ SYSBA(io_getevents, True),
+ SYSB_(io_submit, False),
+ SYSBA(io_cancel, False),
+
#if !SIGNAL_SIMULATION
SYSBA(sigaltstack, False),
|
|
From: Tom H. <th...@cy...> - 2004-07-15 22:44:06
|
In message <Pin...@he...>
Nicholas Nethercote <nj...@ca...> wrote:
> That would seem to be enough. But in vg_signals.c, there's a bit in the
> SEGV handler with this comment:
>
> /* If there's a fault within the shadow memory range, and it
> is a permissions fault, then it means that the client is
> using some memory which had not previously been used.
> This catches those faults, makes the memory accessible,
> and calls the tool to initialize that page.
> */
>
> This calls VG_(init_shadow_range)(), which calls the init_shadow_page
> trackable event, telling the tool to make itself a shadow page. But none
> of the tools actually provide the necessary init_shadow_page callback.
Somebody did manage to reach that code however, although I'm not
quite sure how. See bug 80932 where I was also trying to work out
what that bit in the SEGV handler was for.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 22:20:17
|
Hi,
I'm looking at how new shadow memory pages are allocated when necessary.
It's weird, there seem to be two mechanisms for this.
First, every tool that uses shadow memory (memcheck, addrcheck, helgrind)
is very careful to call their respective ENSURE_MAPPABLE macros before
accessing shadow memory, which checks if there is a shadow page for the
address and allocates a new one if not.
That would seem to be enough. But in vg_signals.c, there's a bit in the
SEGV handler with this comment:
/* If there's a fault within the shadow memory range, and it
is a permissions fault, then it means that the client is
using some memory which had not previously been used.
This catches those faults, makes the memory accessible,
and calls the tool to initialize that page.
*/
This calls VG_(init_shadow_range)(), which calls the init_shadow_page
trackable event, telling the tool to make itself a shadow page. But none
of the tools actually provide the necessary init_shadow_page callback.
This 2nd mechanism is simply not being used; I tried removing it and the
entire regression test suite ran fine.
So I see two options:
1. Just rely on the currently used ENSURE_MAPPABLE macros in the tools.
This would allow a couple of functions to be removed or simplified, saving
50 lines of code.
2. Just rely on the SEGV handling bit. This would require adding the
init_shadow_page callback to each of the tools. The advantage with this
option is that it might make things a bit faster, since we wouldn't have
to do ENSURE_MAPPABLE (which is a comparison like "x == y[z >> 16]") for
every shadow memory access. (But it might make no discernible difference,
since this is just arithmetic which might be swamped by the associated
memory accesses. In which case option (1) is clearly better.)
Any opinions? Jeremy, do you know why both these mechanisms are present?
Thanks.
N
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 16:29:59
|
On Wed, 14 Jul 2004, Tom Hughes wrote: >> That's what I was afraid of. Hmm. Would it be better to abort with a >> warning if new/new[] failed? And maybe have an option that lets them >> return NULL? Silently doing the wrong thing (not throwing an >> exception) is bad. > > Aborting is probably better, yes. That's what I've done. A better scheme can be implemented if necessary. N |
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 16:28:42
|
CVS commit by nethercote:
If new/new[] fails and should throw an exception, abort instead, since we can't
throw exceptions.
M +27 -7 vg_replace_malloc.c.base 1.3
--- valgrind/coregrind/vg_replace_malloc.c.base #1.2:1.3
@@ -64,4 +64,6 @@
ret VG_INTERCEPT(soname:libc.so.6, ##name) args
+extern void _exit(int);
+
/*------------------------------------------------------------*/
/*--- Replacing malloc() et al ---*/
@@ -107,15 +109,35 @@
return v; \
}
+
+#define ALLOC2(fff, vgfff) \
+LIBALIAS(void *, fff, (Int n)) \
+{ \
+ void* v; \
+ \
+ MALLOC_TRACE(#fff "(%d)", n ); \
+ MAYBE_SLOPPIFY(n); \
+ if (!init_done) init(); \
+ \
+ v = (void*)VALGRIND_NON_SIMD_CALL1( info.sk_##vgfff, n ); \
+ MALLOC_TRACE(" = %p", v ); \
+ if (NULL == v) { \
+ VALGRIND_PRINTF_BACKTRACE( \
+ "new/new[] failed and should throw an exception, but Valgrind\n" \
+ " cannot throw exceptions and so is aborting instead. Sorry."); \
+ _exit(1); \
+ } \
+ return v; \
+}
ALLOC( malloc, malloc );
-ALLOC( __builtin_new, __builtin_new );
-ALLOC( _Znwj, __builtin_new );
+ALLOC2(__builtin_new, __builtin_new );
+ALLOC2(_Znwj, __builtin_new );
// operator new(unsigned, std::nothrow_t const&)
ALLOC( _ZnwjRKSt9nothrow_t, __builtin_new );
-ALLOC( __builtin_vec_new, __builtin_vec_new );
-ALLOC( _Znaj, __builtin_vec_new );
+ALLOC2(__builtin_vec_new, __builtin_vec_new );
+ALLOC2(_Znaj, __builtin_vec_new );
-// operator new[](unsigned, std::nothrow_t const&
+// operator new[](unsigned, std::nothrow_t const&)
ALLOC( _ZnajRKSt9nothrow_t, __builtin_vec_new );
@@ -246,6 +268,4 @@
/* Bomb out if we get any of these. */
-extern void _exit(int);
-
static void panic(const char *str)
{
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 14:58:54
|
CVS commit by nethercote:
This commit fixes things so that the client stack can be easily placed
anywhere, even below the client executable, just by changing a single
assignment to VG_(clstk_end). I haven't actually moved the stack, though.
M +14 -10 vg_main.c 1.170 [POSSIBLY UNSAFE: printf]
M +3 -1 vg_signals.c 1.72
--- valgrind/coregrind/vg_main.c #1.169:1.170
@@ -511,5 +511,4 @@ static void layout_remaining_space(float
/* 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;
VG_(shadow_base) = VG_(client_end) + REDZONE_SIZE;
@@ -941,6 +940,5 @@ static char *copy_str(char **tab, const
if (0)
- printf("copied %p \"%s\" len %d\n",
- orig, orig, cp-orig);
+ printf("copied %p \"%s\" len %d\n", orig, orig, cp-orig);
*tab = cp;
@@ -1050,6 +1048,11 @@ static Addr setup_client_stack(char **or
VKI_BYTES_PER_PAGE; /* page for trampoline code */
+ // decide where stack goes!
+ VG_(clstk_end) = VG_(client_end);
+
+ VG_(client_trampoline_code) = VG_(clstk_end) - VKI_BYTES_PER_PAGE;
+
/* cl_esp is the client's stack pointer */
- cl_esp = VG_(client_end) - stacksize;
+ cl_esp = VG_(clstk_end) - stacksize;
cl_esp = ROUNDDN(cl_esp, 16); /* make stack 16 byte aligned */
@@ -1058,5 +1061,4 @@ static Addr setup_client_stack(char **or
VG_(clstk_base) = PGROUNDDN(cl_esp);
- VG_(clstk_end) = VG_(client_end);
if (0)
@@ -1070,5 +1072,5 @@ static Addr setup_client_stack(char **or
/* allocate a stack - mmap enough space for the stack */
- res = mmap((void *)PGROUNDDN(cl_esp), VG_(client_end) - PGROUNDDN(cl_esp),
+ res = mmap((void *)PGROUNDDN(cl_esp), VG_(clstk_end) - PGROUNDDN(cl_esp),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
@@ -1193,4 +1195,8 @@ static Addr setup_client_stack(char **or
vg_assert(auxv->a_type == AT_NULL);
+ /* --- trampoline page --- */
+ VG_(memcpy)( (void *)VG_(client_trampoline_code),
+ &VG_(trampoline_code_start), VG_(trampoline_code_length) );
+
vg_assert((strtab-stringbase) == stringsize);
@@ -2886,9 +2892,7 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Initialize our trampoline page (which is also sysinfo stuff)
- // p: setup_client_stack() [for 'esp_at_startup']
+ // Protect client trampoline page (which is also sysinfo stuff)
+ // p: segment stuff [otherwise get seg faults...]
//--------------------------------------------------------------
- VG_(memcpy)( (void *)VG_(client_trampoline_code),
- &VG_(trampoline_code_start), VG_(trampoline_code_length) );
VG_(mprotect)( (void *)VG_(client_trampoline_code),
VG_(trampoline_code_length), VKI_PROT_READ|VKI_PROT_EXEC );
--- valgrind/coregrind/vg_signals.c #1.71:1.72
@@ -2117,4 +2117,6 @@ void vg_sync_signalhandler ( Int sigNo,
if (seg != NULL)
seg = VG_(next_segment)(seg);
+ else
+ seg = VG_(first_segment)();
if (VG_(clo_trace_signals)) {
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 14:30:58
|
On Thu, 15 Jul 2004, Nicholas Nethercote wrote: > Actually, it's just below the trampoline page... Ok, I've worked it out. Turns out that last diff worked so long as the stack was above the client's executable. The attached diff has a fix so that it can handle the stack being below the client's executable. N |
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 13:55:51
|
On Thu, 15 Jul 2004, Nicholas Nethercote wrote: > ==12099== Process terminating with default action of signal 11 (SIGSEGV): > dumping core > ==12099== Access not within mapped region at address 0x7FFDFDC > ==12099== at 0x1B8F50B9: __GI___fxstat64 (in /lib/ld-2.3.2.so) > ==12099== by 0x1B8E9990: _dl_map_object_from_fd (in /lib/ld-2.3.2.so) > ==12099== by 0x1B8E863A: _dl_map_object_internal (in /lib/ld-2.3.2.so) > ==12099== by 0x1B8E6427: dl_main (in /lib/ld-2.3.2.so) > > I don't understand why but I guess it's something to do with the trampoline > page. The address 0x7FFDFDC seems random, right in the middle of nowhere. Actually, it's just below the trampoline page... > I don't really understand what the trampoline page does so I'm a bit > stuck. N |
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 13:48:36
|
On Wed, 14 Jul 2004, Nicholas Nethercote wrote: > I tried the attached patch (against HEAD, not my patched version) to move the > stack to 0x8000000, below the main executable. Valgrind segfaults very > shortly after, within setup_client_stack, during the stack copying -- at the > first call to copy_str(). Ok, the attached patch fixes that problem -- I wasn't moving the trampoline page along with the stack. However, with this patch, running 'date' it seg faults after 473 basic blocks: ==12099== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==12099== Access not within mapped region at address 0x7FFDFDC ==12099== at 0x1B8F50B9: __GI___fxstat64 (in /lib/ld-2.3.2.so) ==12099== by 0x1B8E9990: _dl_map_object_from_fd (in /lib/ld-2.3.2.so) ==12099== by 0x1B8E863A: _dl_map_object_internal (in /lib/ld-2.3.2.so) ==12099== by 0x1B8E6427: dl_main (in /lib/ld-2.3.2.so) I don't understand why but I guess it's something to do with the trampoline page. The address 0x7FFDFDC seems random, right in the middle of nowhere. I don't really understand what the trampoline page does so I'm a bit stuck. N |
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 12:59:53
|
CVS commit by nethercote:
Merged Valgrind's heap and stack. This has two main advantages:
1. It simplifies various things a bit.
2. Valgrind/tools will run out of memory later than currently in many
circumstances. This is good news esp. for Calltree.
Some things were going in V's 128MB heap, and some were going in V's 128MB map
segment. Now all these things are going into a single 256MB map segment.
stage2 has been moved down to 0xb0000000, the start of the 256MB map segment.
The .so files needed by it are placed at 0xb1000000 (that's the map_base).
This required some bootstrapping at startup for memory -- we need to allocate
memory to create the segments skip-list which lets us allocate memory...
solution was to make the first superblock allocated a special static one.
That's pretty simple and enough to get things going.
Removed vg_glibc.c which wasn't doing anything anyway.
Removed VG_(brk) and associated stuff, made all the things that were calling it
call VG_(mmap)() instead.
Removed VG_(valgrind_mmap_end) which was no longer needed.
Rejigged the startup order a bit as necessary.
Moved an important comment from ume.c to vg_main.c where it should be.
M +1 -2 Makefile.am 1.75
M +1 -1 stage1.c 1.13
M +0 -42 ume.c 1.11
M +0 -4 vg_include.h 1.201
M +97 -88 vg_main.c 1.169
M +31 -8 vg_malloc2.c 1.27
M +1 -1 vg_memory.c 1.59
M +4 -56 vg_mylibc.c 1.81
R vg_glibc.c 1.2
--- valgrind/coregrind/Makefile.am #1.74:1.75
@@ -53,5 +53,4 @@
vg_execontext.c \
vg_from_ucode.c \
- vg_glibc.c \
vg_hashtable.c \
vg_helpers.S \
@@ -82,5 +81,5 @@
stage2_DEPENDENCIES = $(srcdir)/valgrind.vs x86/stage2.lds
stage2_LDFLAGS=-Wl,--export-dynamic -Wl,-e,_ume_entry -g \
- -Wl,-defsym,kickstart_base=0xb8000000 \
+ -Wl,-defsym,kickstart_base=0xb0000000 \
-Wl,-T,x86/stage2.lds \
-Wl,-version-script $(srcdir)/valgrind.vs
--- valgrind/coregrind/stage1.c #1.12:1.13
@@ -180,5 +180,5 @@ static void hoops(void)
- something else?
*/
- info.map_base = 0xb0000000;
+ info.map_base = 0xb1000000;
info.argv = NULL;
--- valgrind/coregrind/ume.c #1.10:1.11
@@ -29,46 +29,4 @@
*/
-/*
- User-mode exec
-
- This bootstraps Valgrind. This code decides on the layout of the
- client and Valgrind address spaces, loads valgrind.so and the
- skin.so into the valgrind part, loads the client executable (and the
- dynamic linker, if necessary) into the client part, and calls into
- Valgrind proper.
-
- The code is careful not to allow spurious mappings to appear in the
- wrong parts of the address space. In particular, to make sure
- dlopen puts things in the right place, it will pad out the forbidden
- chunks of address space so that dlopen is forced to put things where
- we want them.
-
- The memory map it creates is:
-
- CLIENT_BASE +-------------------------+
- | client address space |
- : :
- : :
- | client stack |
- client_end +-------------------------+
- | redzone |
- shadow_base +-------------------------+
- | |
- : shadow memory for skins :
- | (may be 0 sized) |
- shadow_end +-------------------------+
- : gap (may be 0 sized) :
- valgrind_base +-------------------------+
- | valgrind .so files |
- | and mappings |
- valgrind_mmap_end -
- | kickstart executable |
- - -
- | valgrind heap vvvvvvvvv|
- valgrind_end - -
- | valgrind stack ^^^^^^^^^|
- +-------------------------+
- : kernel :
- */
#define _GNU_SOURCE
--- valgrind/coregrind/vg_include.h #1.200:1.201
@@ -1134,7 +1134,4 @@ __attribute__ ((__noreturn__))
extern void VG_(core_panic) ( Char* str );
-/* VG_(brk) not public so skins cannot screw with curr_dataseg_end */
-extern void* VG_(brk) ( void* end_data_segment );
-
/* Skins use VG_(strdup)() which doesn't expose ArenaId */
extern Char* VG_(arena_strdup) ( ArenaId aid, const Char* s);
@@ -1439,5 +1436,4 @@ extern Addr VG_(shadow_base); /* skin's
extern Addr VG_(shadow_end);
extern Addr VG_(valgrind_base); /* valgrind's address range */
-extern Addr VG_(valgrind_mmap_end);
extern Addr VG_(valgrind_end);
--- valgrind/coregrind/vg_main.c #1.168:1.169
@@ -75,7 +75,4 @@
#endif /* AT_SECURE */
-/* Amount to reserve for Valgrind's internal mappings */
-#define VALGRIND_MAPSIZE (128*1024*1024)
-
/* redzone gap between client address space and shadow */
#define REDZONE_SIZE (1 * 1024*1024)
@@ -112,5 +109,4 @@ Addr VG_(shadow_end);
Addr VG_(valgrind_base); /* valgrind's address range */
-Addr VG_(valgrind_mmap_end); /* valgrind's mmaps are between valgrind_base and here */
Addr VG_(valgrind_end);
@@ -493,6 +489,5 @@ static void layout_client_space(Addr arg
{
VG_(client_base) = CLIENT_BASE;
- VG_(valgrind_mmap_end) = (addr_t)&kickstart_base; /* end of V's mmaps */
- VG_(valgrind_base) = VG_(valgrind_mmap_end) - VALGRIND_MAPSIZE;
+ VG_(valgrind_base) = (addr_t)&kickstart_base;
VG_(valgrind_end) = ROUNDUP(argc_addr, 0x10000); /* stack */
@@ -531,5 +526,4 @@ static void layout_remaining_space(float
"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),
@@ -538,6 +532,5 @@ static void layout_remaining_space(float
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_base), SEGSIZE(valgrind_base, valgrind_end),
VG_(valgrind_end)
);
@@ -2640,4 +2633,51 @@ void VG_(do_sanity_checks) ( Bool force_
/*====================================================================*/
+/*
+ This code decides on the layout of the client and Valgrind address
+ spaces, loads valgrind.so and the skin.so into the valgrind part,
+ loads the client executable (and the dynamic linker, if necessary)
+ into the client part, and calls into Valgrind proper.
+
+ The code is careful not to allow spurious mappings to appear in the
+ wrong parts of the address space. In particular, to make sure
+ dlopen puts things in the right place, it will pad out the forbidden
+ chunks of address space so that dlopen is forced to put things where
+ we want them.
+
+ The memory map it creates is:
+
+ CLIENT_BASE +-------------------------+
+ | client address space |
+ : :
+ : :
+ | client stack |
+ client_end +-------------------------+
+ | redzone |
+ shadow_base +-------------------------+
+ | |
+ : shadow memory for skins :
+ | (may be 0 sized) |
+ shadow_end +-------------------------+
+ : gap (may be 0 sized) :
+ valgrind_base +-------------------------+
+ | kickstart executable |
+ | valgrind heap vvvvvvvvv| (barely used)
+ - -
+ | valgrind .so files |
+ | and mappings |
+ - -
+ | valgrind stack ^^^^^^^^^|
+ valgrind_end +-------------------------+
+ : kernel :
+
+ Nb: Before we can do general allocations with VG_(arena_malloc)() and
+ VG_(mmap)(), we need to build the segment skip-list, so we know where
+ we can put things. However, building that structure requires
+ allocating memory. So we need to a bootstrapping process. It's done
+ by making VG_(arena_malloc)() have a special static superblock that's
+ used for the first 1MB's worth of allocations. This is enough to
+ build the segment skip-list.
+*/
+
static int prmap(void *start, void *end, const char *perm, off_t off,
int maj, int min, int ino) {
@@ -2690,5 +2730,5 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
// Check we were launched by stage1
- // p: n/a [must be first step]
+ // p: n/a
//--------------------------------------------------------------
scan_auxv();
@@ -2737,5 +2777,5 @@ int main(int argc, char **argv)
//==============================================================
// Can use VG_(malloc)() and VG_(arena_malloc)() only after load_tool()
- // -- redzone size is now set.
+ // -- redzone size is now set. This is checked by vg_malloc2.c.
//==============================================================
@@ -2786,10 +2826,4 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Read /proc/self/maps into a buffer
- // p: all memory layout, environment setup [so memory maps are right]
- //--------------------------------------------------------------
- VG_(read_procselfmaps)();
-
- //--------------------------------------------------------------
// atfork
// p: n/a
@@ -2805,12 +2839,27 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Setup tool
- // p: VG_(read_procselfmaps)() [so if sk_pre_clo_init calls
- // VG_(malloc), any mmap'd superblocks aren't erroneously
- // identified later as being owned by the client]
- // XXX: is that necessary, now that we look for V's segments separately?
- // XXX: alternatively, if sk_pre_clo_init does use VG_(malloc)(), is it
- // wrong to ignore any segments that might add in parse_procselfmaps?
+ // Read /proc/self/maps into a buffer
+ // p: all memory layout, environment setup [so memory maps are right]
+ //--------------------------------------------------------------
+ VG_(read_procselfmaps)();
+
+ //--------------------------------------------------------------
+ // Build segment map (Valgrind segments only)
+ // p: read proc/self/maps
+ // p: sk_pre_clo_init() [to setup new_mem_startup tracker]
+ //--------------------------------------------------------------
+ VG_(parse_procselfmaps) ( build_valgrind_map_callback );
+
+ //==============================================================
+ // Can use VG_(arena_malloc)() with non-CORE arena after segments set up
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // Init tool: pre_clo_init, process cmd line, post_clo_init
// p: setup_client_stack() [for 'VG_(client_arg[cv]']
+ // p: load_tool() [for 'tool']
+ // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
+ // p: parse_procselfmaps [so VG segments are setup so tool can
+ // call VG_(malloc)]
//--------------------------------------------------------------
(*toolinfo->sk_pre_clo_init)();
@@ -2818,20 +2867,34 @@ int main(int argc, char **argv)
VG_(sanity_check_needs)();
- //--------------------------------------------------------------
// If --tool and --help/--help-debug was given, now give the core+tool
// help message
- // p: pre_clo_init()
- //--------------------------------------------------------------
if (need_help) {
usage(/*--help-debug?*/2 == need_help);
}
+ process_cmd_line_options(client_auxv, tool);
+
+ SK_(post_clo_init)();
//--------------------------------------------------------------
- // Process Valgrind's + tool's command-line options
- // p: load_tool() [for 'tool']
- // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
- // p: sk_pre_clo_init [to set 'command_line_options' need]
+ // Build segment map (all segments)
+ // p: setup_client_stack() [for 'esp_at_startup']
+ // p: init tool [for 'new_mem_startup']
//--------------------------------------------------------------
- process_cmd_line_options(client_auxv, tool);
+ esp_at_startup___global_arg = esp_at_startup;
+ VG_(parse_procselfmaps) ( build_segment_map_callback ); /* everything */
+ esp_at_startup___global_arg = 0;
+
+ //--------------------------------------------------------------
+ // Initialize our trampoline page (which is also sysinfo stuff)
+ // p: setup_client_stack() [for 'esp_at_startup']
+ //--------------------------------------------------------------
+ VG_(memcpy)( (void *)VG_(client_trampoline_code),
+ &VG_(trampoline_code_start), VG_(trampoline_code_length) );
+ VG_(mprotect)( (void *)VG_(client_trampoline_code),
+ VG_(trampoline_code_length), VKI_PROT_READ|VKI_PROT_EXEC );
+
+ //==============================================================
+ // Can use VG_(map)() after segments set up
+ //==============================================================
//--------------------------------------------------------------
@@ -2848,10 +2911,4 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Setup tool, post command-line processing
- // p: process_cmd_line_options [tool assumes it]
- //--------------------------------------------------------------
- SK_(post_clo_init)();
-
- //--------------------------------------------------------------
// Set up baseBlock
// p: {pre,post}_clo_init() [for tool helper registration]
@@ -2908,50 +2965,4 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Reserve Valgrind's kickstart, heap and stack
- // p: XXX ???
- //--------------------------------------------------------------
- VG_(map_segment)(VG_(valgrind_mmap_end),
- VG_(valgrind_end)-VG_(valgrind_mmap_end),
- VKI_PROT_NONE, SF_VALGRIND|SF_FIXED);
-
- //--------------------------------------------------------------
- // Identify Valgrind's segments
- // p: read proc/self/maps
- // p: VG_(map_segment) [XXX ???]
- // p: sk_pre_clo_init() [to setup new_mem_startup tracker]
- //--------------------------------------------------------------
- VG_(parse_procselfmaps) ( build_valgrind_map_callback );
-
- // XXX: I can't see why these two need to be separate; could they be
- // folded together? If not, need a comment explaining why.
- //
- // XXX: can we merge reading and parsing of /proc/self/maps?
- //
- // XXX: can we dynamically allocate the /proc/self/maps buffer? (or mmap
- // it?) Or does that disturb its contents...
-
- //--------------------------------------------------------------
- // Build segment map (all segments)
- // p: setup_client_stack() [for 'esp_at_startup']
- //--------------------------------------------------------------
- esp_at_startup___global_arg = esp_at_startup;
- VG_(parse_procselfmaps) ( build_segment_map_callback ); /* everything */
- esp_at_startup___global_arg = 0;
-
- //==============================================================
- // Can only use VG_(map)() after VG_(map_segment)() [XXX ???]
- //==============================================================
-
- //--------------------------------------------------------------
- // Build segment map (all segments)
- // p: setup_client_stack() [for 'esp_at_startup']
- //--------------------------------------------------------------
- /* Initialize our trampoline page (which is also sysinfo stuff) */
- VG_(memcpy)( (void *)VG_(client_trampoline_code),
- &VG_(trampoline_code_start), VG_(trampoline_code_length) );
- VG_(mprotect)( (void *)VG_(client_trampoline_code),
- VG_(trampoline_code_length), VKI_PROT_READ|VKI_PROT_EXEC );
-
- //--------------------------------------------------------------
// Read suppression file
// p: process_cmd_line_options() [for VG_(clo_suppressions)]
--- valgrind/coregrind/vg_malloc2.c #1.26:1.27
@@ -188,4 +188,6 @@ void* align_upwards ( void* p, Int align
/*------------------------------------------------------------*/
+#define CORE_ARENA_MIN_SZW 262144
+
/* The arena structures themselves. */
static Arena vg_arena[VG_N_ARENAS];
@@ -247,8 +249,14 @@ static
void ensure_mm_init ( void )
{
- Int client_rz_szW;
+ static Int client_rz_szW;
static Bool init_done = False;
- if (init_done) return;
+ if (init_done) {
+ // Make sure the client arena's redzone size never changes. Could
+ // happen if VG_(arena_malloc) was called too early, ie. before the
+ // tool was loaded.
+ vg_assert(client_rz_szW == VG_(vg_malloc_redzone_szB)/4);
+ return;
+ }
/* Use checked red zones (of various sizes) for our internal stuff,
@@ -259,5 +267,5 @@ void ensure_mm_init ( void )
zone words are unchanged. */
- arena_init ( &vg_arena[VG_AR_CORE], "core", 2, True, 262144, False );
+ arena_init ( &vg_arena[VG_AR_CORE], "core", 2, True, CORE_ARENA_MIN_SZW, False );
arena_init ( &vg_arena[VG_AR_TOOL], "tool", 2, True, 262144, False );
@@ -317,8 +325,14 @@ Bool VG_(is_inside_segment_mmapd_by_low_
/*------------------------------------------------------------*/
+// If not enough memory available, either aborts (for non-client memory)
+// or returns 0 (for client memory).
static
Superblock* newSuperblock ( Arena* a, Int cszW )
{
+ static Bool called_before = False;
+ static Word bootstrap_superblock[CORE_ARENA_MIN_SZW];
+ Int cszB;
Superblock* sb;
+
cszW += 2; /* Take into account sb->next and sb->n_words fields */
if (cszW < a->min_sblockW) cszW = a->min_sblockW;
@@ -325,8 +339,18 @@ Superblock* newSuperblock ( Arena* a, In
while ((cszW % VKI_WORDS_PER_PAGE) > 0) cszW++;
- if (a->clientmem) {
+ cszB = cszW * sizeof(Word);
+
+ if (!called_before) {
+ // First time we're called -- use the special static bootstrap
+ // superblock (see comment at top of main() for details).
+ called_before = True;
+ vg_assert(a == &vg_arena[VG_AR_CORE]);
+ vg_assert(CORE_ARENA_MIN_SZW*sizeof(Word) >= cszB);
+ sb = (Superblock*)bootstrap_superblock;
+
+ } else if (a->clientmem) {
// client allocation -- return 0 to client if it fails
sb = (Superblock *)
- VG_(client_alloc)(0, cszW * sizeof(Word),
+ VG_(client_alloc)(0, cszB,
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, 0);
if (NULL == sb) {
@@ -335,9 +359,8 @@ Superblock* newSuperblock ( Arena* a, In
} else {
// non-client allocation -- abort if it fails
- sb = VG_(get_memory_from_mmap) ( cszW * sizeof(Word),
- "newSuperblock" );
+ sb = VG_(get_memory_from_mmap) ( cszB, "newSuperblock" );
}
sb->n_payload_words = cszW - 2;
- a->bytes_mmaped += cszW * sizeof(Word);
+ a->bytes_mmaped += cszB;
if (0)
VG_(message)(Vg_DebugMsg, "newSuperblock, %d payload words",
--- valgrind/coregrind/vg_memory.c #1.58:1.59
@@ -494,5 +494,5 @@ Addr VG_(find_map_space)(Addr addr, UInt
Segment *s;
Addr ret;
- Addr limit = (for_client ? VG_(client_end) : VG_(valgrind_mmap_end));
+ Addr limit = (for_client ? VG_(client_end) : VG_(valgrind_end));
if (addr == 0)
--- valgrind/coregrind/vg_mylibc.c #1.80:1.81
@@ -373,52 +373,4 @@ Int VG_(nanosleep)( const struct vki_tim
}
-extern Char _end;
-Char *VG_(curbrk) = NULL;
-extern void *__curbrk; /* in glibc */
-
-void* VG_(brk) ( void* end_data_segment )
-{
- Addr end;
- Addr brkpage;
- Addr endpage;
-
- if (VG_(curbrk) == NULL) {
- VG_(curbrk) = &_end;
- __curbrk = (void *)VG_(curbrk);
- }
-
- end = (Addr)end_data_segment;
- brkpage = PGROUNDUP(VG_(curbrk));
- endpage = PGROUNDUP(end);
-
- if (0 && VG_(curbrk) != __curbrk)
- VG_(printf)("__curbrk changed unexpectedly: VG_(curbrk)=%p, __curbrk=%p\n",
- VG_(curbrk), __curbrk);
-
- if (0)
- VG_(printf)("brk(end_data_segment=%p); brkpage=%p endpage=%p end=%p curbrk=%p &_end=%p\n",
- end_data_segment, brkpage, endpage, end, VG_(curbrk), &_end);
-
- if (endpage < (Addr)&_end) {
- __curbrk = (void *)VG_(curbrk);
- return (void *)VG_(curbrk);
- }
-
- if (brkpage != endpage) {
- if (brkpage > endpage) {
- Int res = munmap_inner((void *)brkpage, brkpage-endpage);
- vg_assert(0 == res);
- } else {
- Addr res = mmap_inner((void *)brkpage, endpage-brkpage,
- VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
- VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, -1, 0);
- vg_assert((Addr)-1 != res);
- }
- }
- VG_(curbrk) = (Char *)__curbrk = end_data_segment;
-
- return end_data_segment;
-}
-
/* ---------------------------------------------------------------------
@@ -1676,14 +1628,10 @@ void* VG_(get_memory_from_mmap) ( Int nB
static UInt tot_alloc = 0;
void* p;
- Char *b = VG_(brk)(0);
-
- p = (void *)PGROUNDUP(b);
- b = VG_(brk)(p + PGROUNDUP(nBytes));
-
- if (b != (p + PGROUNDUP(nBytes)))
- p = (void *)-1;
+ p = VG_(mmap)(0, nBytes,
+ VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
+ VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 0, -1, 0);
if (p != ((void*)(-1))) {
- vg_assert(p >= (void *)VG_(valgrind_mmap_end) && p < (void *)VG_(valgrind_end));
+ vg_assert(p >= (void*)VG_(valgrind_base) && p < (void*)VG_(valgrind_end));
tot_alloc += (UInt)nBytes;
if (0)
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 12:55:44
|
On Wed, 14 Jul 2004, Nicholas Nethercote wrote: >> Looks reasonable to me. It would be really nice to fix the constant >> address for info.map_base in stage1. Hm, with this arrangement, info. >> mapbase for stage2 is essentially where the brk used to be - after the >> main executable. Stage1 can work out where it is just by looking at >> stage2's ELF mappings. > > How do you do that? Do the mappings say how big the executable is? What > about stage2's stack? It has one, it's small, but system malloc() is called > a few times at startup. s/stack/heap I see the info->exe_end is set in ume.c, ume.h describes it as the "highest (allowed) address", but what does this actually mean? What about space for stage2's data? N |
|
From: <js...@ac...> - 2004-07-15 02:58:40
|
Nightly build on nemesis ( SuSE 9.1 ) started at 2004-07-15 03:50:00 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow memcheck/tests/overlap (stderr) memcheck/tests/pth_once (stderr) memcheck/tests/pushfpopf (stderr) memcheck/tests/realloc1 (stderr) memcheck/tests/realloc2 (stderr) memcheck/tests/realloc3 (stderr) memcheck/tests/sigaltstack (stderr) memcheck/tests/signal2 (stderr) memcheck/tests/supp1 (stderr) memcheck/tests/supp2 (stderr) memcheck/tests/suppfree (stderr) memcheck/tests/threadederrno (stderr) memcheck/tests/toobig-allocs (stderr) memcheck/tests/trivialleak (stderr) memcheck/tests/tronical (stderr) memcheck/tests/weirdioctl (stderr) memcheck/tests/writev (stderr) memcheck/tests/zeropage (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <to...@co...> - 2004-07-15 02:25:07
|
Nightly build on dunsmere ( Fedora Core 2 ) started at 2004-07-15 03:20:02 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow 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 ---------------------------------------- == 173 tests, 7 stderr failures, 1 stdout failure ================= corecheck/tests/fdleak_cmsg (stderr) corecheck/tests/fdleak_fcntl (stderr) corecheck/tests/fdleak_ipv4 (stderr) corecheck/tests/fdleak_socketpair (stderr) memcheck/tests/buflen_check (stderr) memcheck/tests/execve (stderr) memcheck/tests/writev (stderr) none/tests/exec-sigmask (stdout) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-07-15 02:19:50
|
Nightly build on audi ( Red Hat 9 ) started at 2004-07-15 03:15:03 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow 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 ---------------------------------------- == 173 tests, 8 stderr failures, 0 stdout failures ================= corecheck/tests/fdleak_cmsg (stderr) corecheck/tests/fdleak_fcntl (stderr) corecheck/tests/fdleak_ipv4 (stderr) corecheck/tests/fdleak_socketpair (stderr) corecheck/tests/pth_cancel2 (stderr) memcheck/tests/buflen_check (stderr) memcheck/tests/execve (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-07-15 02:13:17
|
Nightly build on ginetta ( Red Hat 8.0 ) started at 2004-07-15 03:10:02 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow sem: valgrind ./sem 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 ---------------------------------------- == 173 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-07-15 02:08:14
|
Nightly build on alvis ( Red Hat 7.3 ) started at 2004-07-15 03:05:02 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow 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 ---------------------------------------- == 173 tests, 7 stderr failures, 1 stdout failure ================= addrcheck/tests/toobig-allocs (stderr) 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/toobig-allocs (stderr) memcheck/tests/writev (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2004-07-15 02:06:47
|
Nightly build on standard ( Red Hat 7.2 ) started at 2004-07-15 03:00:03 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow resolv: valgrind ./resolv rlimit_nofile: valgrind ./rlimit_nofile seg_override: valgrind ./seg_override sem: valgrind ./sem 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 ---------------------------------------- == 173 tests, 1 stderr failure, 0 stdout failures ================= memcheck/tests/badfree-2trace (stderr) make: *** [regtest] Error 1 |