On Sun, Jan 20, 2013 at 02:19:55PM +0200, Mikolaj Golub wrote: > Hi, > > Some time ago I noticed that valgrind started to complain about > "Mismatched free() / delete / delete []" for valid new/delete > combinations. > > For example, the following test program > > int main() > { > char* buf = new char[10]; > delete [] buf; > > return 0; > } > > produced a warning: > > ==38718== Mismatched free() / delete / delete [] > ==38718== at 0x100416E: free (vg_replace_malloc.c:473) > ==38718== by 0x4007BE: main (test.cpp:5) > ==38718== Address 0x2400040 is 0 bytes inside a block of size 10 alloc'd > ==38718== at 0x10047D7: operator new[](unsigned long) > (vg_replace_malloc.c:382) > ==38718== by 0x40079D: main (test.cpp:4) > > For some time I hoped that "someone" would fix the problem but seeing > that after several upgrades it was still there I decided it is time to > do some investigations. > > Running the valgrind with "--trace-redir=yes -v" showed that valgrind > activates redirections for new/delete symbols in libstdc++: > > --6729-- Reading syms from /usr/lib/libstdc++.so.6 (0x1209000) > ... > --6729-- ------ ACTIVE ------ > ... > --6729-- 0x01260770 (operator new[](unsig) R-> (1001.0) 0x010041b0 > operator new[](unsigned long, std::nothrow_t const&) > --6729-- 0x01260780 (operator new(unsigne) R-> (1001.0) 0x01004270 > operator new(unsigned long, std::nothrow_t const&) > --6729-- 0x012608a0 (operator delete[](vo) R-> (1005.0) 0x01003e40 > operator delete[](void*, std::nothrow_t const&) > --6729-- 0x012608b0 (operator delete(void) R-> (1005.0) 0x01003fa0 > operator delete(void*, std::nothrow_t const&) > --6729-- 0x012dea90 (operator new[](unsig) R-> (1003.0) 0x01004770 > operator new[](unsigned long) > --6729-- 0x012deab0 (operator new(unsigne) R-> (1003.0) 0x01004860 > operator new(unsigned long) > --6729-- 0x012deca0 (operator delete[](vo) R-> (1005.0) 0x01003ef0 > operator delete[](void*) > --6729-- 0x012e2b80 (operator delete(void) R-> (1005.0) 0x01004050 > operator delete(void*) > > But "delete" redirection is not triggered, while "new" is: > > --6729-- REDIR: 0x12dea90 (operator new[](unsigned long)) redirected to > 0x1004770 (operator new[](unsigned long)) > --6729-- REDIR: 0x19dd9a0 (free) redirected to 0x1004100 (free) > ==6729== Mismatched free() / delete / delete [] > ==6729== at 0x100416E: free (vg_replace_malloc.c:473) > ==6729== by 0x400715: main (test.cpp:5) > ==6729== Address 0x1ed7040 is 0 bytes inside a block of size 10 alloc'd > ==6729== at 0x10047D7: operator new[](unsigned long) > (vg_replace_malloc.c:382) > ==6729== by 0x400701: main (test.cpp:4) > > A little research revealed that in this case the delete operator from > libsupc++ is called and valgrind does not provide redirections for the > symbols in libsupc++. > > When I added the redirections for libsupc++ to valgrind's > vg_replace_malloc.c: > > #define VG_Z_LIBSUPCXX_SONAME libsupcZpZpZa // libsupc++* > > FREE(VG_Z_LIBSUPCXX_SONAME, _ZdlPv, __builtin_delete ); > FREE(VG_Z_LIBSUPCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); > FREE(VG_Z_LIBSUPCXX_SONAME, _ZdaPv, __builtin_vec_delete ); > FREE(VG_Z_LIBSUPCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); > > the issue was fixed: > > --99254-- Reading syms from /usr/lib/libstdc++.so.6 > ... > --99254-- ------ ACTIVE ------ > ... > --99254-- 0x012627c0 (operator new[](unsig) R-> (1001.0) 0x01004ce0 > operator new[](unsigned long, std::nothrow_t const&) > --99254-- 0x012627d0 (operator new(unsigne) R-> (1001.0) 0x01004860 > operator new(unsigned long, std::nothrow_t const&) > --99254-- 0x012628d0 (operator delete[](vo) R-> (1005.0) 0x01005b00 > operator delete[](void*, std::nothrow_t const&) > --99254-- 0x012628e0 (operator delete(void) R-> (1005.0) 0x01005500 > operator delete(void*, std::nothrow_t const&) > --99254-- 0x012c27e0 (operator new[](unsig) R-> (1003.0) 0x01004a80 > operator new[](unsigned long) > --99254-- 0x012c2800 (operator new(unsigne) R-> (1003.0) 0x01004430 > operator new(unsigned long) > --99254-- 0x012c29a0 (operator delete[](vo) R-> (1005.0) 0x01005800 > operator delete[](void*) > --99254-- 0x012c3e40 (operator delete(void) R-> (1005.0) 0x01005200 > operator delete(void*) > ... > --99254-- Reading syms from /usr/lib/libsupc++.so.1 > ... > --99254-- ------ ACTIVE ------ > ... > --99254-- 0x01cae1f0 (operator delete[](vo) R-> (1005.0) 0x01005a00 > operator delete[](void*, std::nothrow_t const&) > --99254-- 0x01cae200 (operator delete[](vo) R-> (1005.0) 0x01005700 > operator delete[](void*) > --99254-- 0x01cae210 (operator delete(void) R-> (1005.0) 0x01005400 > operator delete(void*, std::nothrow_t const&) > --99254-- 0x01cb73d0 (operator delete(void) R-> (1005.0) 0x01005100 > operator delete(void*) > ... > --99254-- REDIR: 0x12c27e0 (operator new[](unsigned long)) redirected to > 0x1004a80 (operator new[](unsigned long)) > --99254-- REDIR: 0x1cae200 (operator delete[](void*)) redirected to 0x1005700 > (operator delete[](void*)) > > Now the question is: is it ok that now we have "new" operators being > still called via libstdc++ while "delete" operators being called > directly from libsupc++? > > If it is ok, is the proposed solution with adding redirects for > libsupc++ is a right way to fix the valgrind? >
Ok, I think it is a good idea to add to valgrind replacements for libsupc++ in any case, as it is possible to explicitly link in libsupc++, if one does not need full libstdc++ features. I reported with the patch to valgrind-freebsd: https://bitbucket.org/stass/valgrind-freebsd/issue/7/add-replacements-for-libsupc -- Mikolaj Golub _______________________________________________ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to "freebsd-stable-unsubscr...@freebsd.org"