From: Philippe Waroquiers Date: Sun, 13 Jan 2013 15:01:21 +0000 (+0000) Subject: no recording of execontext for track origin in brk/signal stack when track-origin=no X-Git-Tag: svn/VALGRIND_3_9_0~455 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=36cb2b241cf2b62041240ff88dad8ff0c94c97df;p=thirdparty%2Fvalgrind.git no recording of execontext for track origin in brk/signal stack when track-origin=no git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13226 --- diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 21c36f3c84..1197c9c2a7 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -1622,10 +1622,16 @@ void make_mem_undefined_w_tid_and_okind ( Addr a, SizeT len, } static -void make_mem_undefined_w_tid ( Addr a, SizeT len, ThreadId tid ) { +void mc_new_mem_w_tid_make_ECU ( Addr a, SizeT len, ThreadId tid ) +{ make_mem_undefined_w_tid_and_okind ( a, len, tid, MC_OKIND_UNKNOWN ); } +static +void mc_new_mem_w_tid_no_ECU ( Addr a, SizeT len, ThreadId tid ) +{ + MC_(make_mem_undefined_w_otag) ( a, len, MC_OKIND_UNKNOWN ); +} void MC_(make_mem_defined) ( Addr a, SizeT len ) { @@ -6155,6 +6161,7 @@ static void mc_post_clo_init ( void ) VG_(track_new_mem_stack_160_w_ECU) ( mc_new_mem_stack_160_w_ECU ); # endif VG_(track_new_mem_stack_w_ECU) ( mc_new_mem_stack_w_ECU ); + VG_(track_new_mem_stack_signal) ( mc_new_mem_w_tid_make_ECU ); } else { /* Not doing origin tracking */ # ifdef PERF_FAST_STACK @@ -6169,8 +6176,64 @@ static void mc_post_clo_init ( void ) VG_(track_new_mem_stack_160) ( mc_new_mem_stack_160 ); # endif VG_(track_new_mem_stack) ( mc_new_mem_stack ); + VG_(track_new_mem_stack_signal) ( mc_new_mem_w_tid_no_ECU ); } + // We assume that brk()/sbrk() does not initialise new memory. Is this + // accurate? John Reiser says: + // + // 0) sbrk() can *decrease* process address space. No zero fill is done + // for a decrease, not even the fragment on the high end of the last page + // that is beyond the new highest address. For maximum safety and + // portability, then the bytes in the last page that reside above [the + // new] sbrk(0) should be considered to be uninitialized, but in practice + // it is exceedingly likely that they will retain their previous + // contents. + // + // 1) If an increase is large enough to require new whole pages, then + // those new whole pages (like all new pages) are zero-filled by the + // operating system. So if sbrk(0) already is page aligned, then + // sbrk(PAGE_SIZE) *does* zero-fill the new memory. + // + // 2) Any increase that lies within an existing allocated page is not + // changed. So if (x = sbrk(0)) is not page aligned, then + // sbrk(PAGE_SIZE) yields ((PAGE_SIZE -1) & -x) bytes which keep their + // existing contents, and an additional PAGE_SIZE bytes which are zeroed. + // ((PAGE_SIZE -1) & x) of them are "covered" by the sbrk(), and the rest + // of them come along for the ride because the operating system deals + // only in whole pages. Again, for maximum safety and portability, then + // anything that lives above [the new] sbrk(0) should be considered + // uninitialized, but in practice will retain previous contents [zero in + // this case.]" + // + // In short: + // + // A key property of sbrk/brk is that new whole pages that are supplied + // by the operating system *do* get initialized to zero. + // + // As for the portability of all this: + // + // sbrk and brk are not POSIX. However, any system that is a derivative + // of *nix has sbrk and brk because there are too many softwares (such as + // the Bourne shell) which rely on the traditional memory map (.text, + // .data+.bss, stack) and the existence of sbrk/brk. + // + // So we should arguably observe all this. However: + // - The current inaccuracy has caused maybe one complaint in seven years(?) + // - Relying on the zeroed-ness of whole brk'd pages is pretty grotty... I + // doubt most programmers know the above information. + // So I'm not terribly unhappy with marking it as undefined. --njn. + // + // [More: I think most of what John said only applies to sbrk(). It seems + // that brk() always deals in whole pages. And since this event deals + // directly with brk(), not with sbrk(), perhaps it would be reasonable to + // just mark all memory it allocates as defined.] + // + if (MC_(clo_mc_level) == 3) + VG_(track_new_mem_brk) ( mc_new_mem_w_tid_make_ECU ); + else + VG_(track_new_mem_brk) ( mc_new_mem_w_tid_no_ECU ); + /* This origin tracking cache is huge (~100M), so only initialise if we need it. */ if (MC_(clo_mc_level) >= 3) { @@ -6404,58 +6467,6 @@ static void mc_pre_clo_init(void) VG_(needs_xml_output) (); VG_(track_new_mem_startup) ( mc_new_mem_startup ); - VG_(track_new_mem_stack_signal)( make_mem_undefined_w_tid ); - // We assume that brk()/sbrk() does not initialise new memory. Is this - // accurate? John Reiser says: - // - // 0) sbrk() can *decrease* process address space. No zero fill is done - // for a decrease, not even the fragment on the high end of the last page - // that is beyond the new highest address. For maximum safety and - // portability, then the bytes in the last page that reside above [the - // new] sbrk(0) should be considered to be uninitialized, but in practice - // it is exceedingly likely that they will retain their previous - // contents. - // - // 1) If an increase is large enough to require new whole pages, then - // those new whole pages (like all new pages) are zero-filled by the - // operating system. So if sbrk(0) already is page aligned, then - // sbrk(PAGE_SIZE) *does* zero-fill the new memory. - // - // 2) Any increase that lies within an existing allocated page is not - // changed. So if (x = sbrk(0)) is not page aligned, then - // sbrk(PAGE_SIZE) yields ((PAGE_SIZE -1) & -x) bytes which keep their - // existing contents, and an additional PAGE_SIZE bytes which are zeroed. - // ((PAGE_SIZE -1) & x) of them are "covered" by the sbrk(), and the rest - // of them come along for the ride because the operating system deals - // only in whole pages. Again, for maximum safety and portability, then - // anything that lives above [the new] sbrk(0) should be considered - // uninitialized, but in practice will retain previous contents [zero in - // this case.]" - // - // In short: - // - // A key property of sbrk/brk is that new whole pages that are supplied - // by the operating system *do* get initialized to zero. - // - // As for the portability of all this: - // - // sbrk and brk are not POSIX. However, any system that is a derivative - // of *nix has sbrk and brk because there are too many softwares (such as - // the Bourne shell) which rely on the traditional memory map (.text, - // .data+.bss, stack) and the existence of sbrk/brk. - // - // So we should arguably observe all this. However: - // - The current inaccuracy has caused maybe one complaint in seven years(?) - // - Relying on the zeroed-ness of whole brk'd pages is pretty grotty... I - // doubt most programmers know the above information. - // So I'm not terribly unhappy with marking it as undefined. --njn. - // - // [More: I think most of what John said only applies to sbrk(). It seems - // that brk() always deals in whole pages. And since this event deals - // directly with brk(), not with sbrk(), perhaps it would be reasonable to - // just mark all memory it allocates as defined.] - // - VG_(track_new_mem_brk) ( make_mem_undefined_w_tid ); // Handling of mmap and mprotect isn't simple (well, it is simple, // but the justification isn't.) See comments above, just prior to