Android Q The libc source as below: __attribute__((constructor(1))) static void __libc_preinit() { // The linker has initialized its copy of the global stack_chk_guard, and filled in the main // thread's TLS slot with that value. Initialize the local global stack guard with its value. __stack_chk_guard = reinterpret_cast<uintptr_t>(__get_tls()[TLS_SLOT_STACK_GUARD]);
__libc_preinit_impl(); } __attribute__((noinline)) static void __libc_preinit_impl() { // Register libc.so's copy of the TLS generation variable so the linker can // update it when it loads or unloads a shared object. TlsModules& tls_modules = __libc_shared_globals()->tls_modules; tls_modules.generation_libc_so = &__libc_tls_generation_copy; __libc_tls_generation_copy = tls_modules.generation; __libc_init_globals(); __libc_init_common(); // Hooks for various libraries to let them know that we're starting up. TestInitImpl(); } static void TestInitImpl() { printf("%s enter\n", __func__); void * handle = dlopen("liblog.so", RTLD_NOW ); -----------This is most important call, If call dlopen success, and then malloc trace is not available now; If Not success, the malloc trace is okay; printf("handle:%p\n", handle); } The test main as below: #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc, char ** argv) { char * p = (char *)malloc(2048); p[2049] = 5; printf("p=%p p[2049]=%d malloc=%p \n", p, p[2049], malloc); (void) argc; (void) argv; return 0; } The valgrind output as below: localhost:/system/bin # ./valgrind --undef-value-errors=no --trace-malloc=yes ./test64 MallocInitImpl enter handle:0xcf2625b55fe1209 ==7131== Memcheck, a memory error detector ==7131== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7131== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==7131== Command: ./test64 ==7131== linker: Warning: "/system_Q_EA3/lib64/valgrind/vgpreload_core-arm64-linux.so" has unsupported flags DT_FLAGS_1=0x421 (ignoring unsupported flags) WARNING: linker: Warning: "/system_Q_EA3/lib64/valgrind/vgpreload_core-arm64-linux.so" has unsupported flags DT_FLAGS_1=0x421 (ignoring unsupported flags) linker: Warning: "/system_Q_EA3/lib64/valgrind/vgpreload_memcheck-arm64-linux.so" has unsupported flags DT_FLAGS_1=0x421 (ignoring unsupported flags) WARNING: linker: Warning: "/system_Q_EA3/lib64/valgrind/vgpreload_memcheck-arm64-linux.so" has unsupported flags DT_FLAGS_1=0x421 (ignoring unsupported flags) --7131-- malloc(48) = 0x60AA040 --7131-- malloc(1024) = 0x60AA0B0-----------------------------before call dlopen in libc module , these text show me malloc trace is okay. MallocInitImpl enter --7131-- free(0x0) handle:0x25bc73725878d53 -----------------------after print these text (it mean dlopen success in libc) , malloc trace is failure; p=0x6813000 p[2049]=5 malloc=0x5d0f32c----------------------these text mean main alloc some memory ; ==7131== ==7131== HEAP SUMMARY: ==7131== in use at exit: 1,072 bytes in 2 blocks ==7131== total heap usage: 2 allocs, 0 frees, 1,072 bytes allocated ==7131== ==7131== LEAK SUMMARY: ==7131== definitely lost: 0 bytes in 0 blocks ==7131== indirectly lost: 0 bytes in 0 blocks ==7131== possibly lost: 0 bytes in 0 blocks ==7131== still reachable: 1,072 bytes in 2 blocks ==7131== suppressed: 0 bytes in 0 blocks ==7131== Rerun with --leak-check=full to see details of leaked memory ==7131== ==7131== For counts of detected and suppressed errors, rerun with: -v ==7131== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -----邮件原件----- 发件人: John Reiser [mailto:jrei...@bitwagon.com] 发送时间: 2019年4月23日 23:19 收件人: valgrind-users@lists.sourceforge.net 主题: Re: [Valgrind-users] Some question about linker dlopen with valgrind >> On the Android OS, there is a question about the linker program >> with vaglrind memcheck. Which version of Android? >> >> The 1^st experiment, the libc module *do*call the dlopen >> function to load some shared object, before the linker call the >> pre_init functions ( before transfer the cpu control to the main ), >> and then the valgrind *can not*trace malloc leak; >> >> The second experiment, the libc module *do not*call the >> dlopen function to load some shared object, before the linker call >> the pre_init functions ( before transfer the cpu control to the main >> ), and then the valgrind *can* trace malloc leak; >> >> I want to know why , and how to make valgrind can trace memory >> leak, while the libc module call the dlopen function to load some so, >> before the linker call the pre-init functions. According to https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcobks/index.html the order of execution is: 1. linker resolves and fetches all DT_NEEDED modules (shared libraries), and performs all relocations for the entire process image 2. linker calls DT_PREINIT_ARRAY functions of the main program, in order (only a main program may have DT_PREINIT_ARRAY; a shared library MUST NOT) 3. in dependency order (topological bottom-up) of all loaded modules (main program and shared libraries): linker calls DT_INIT and then DT_INIT_ARRAY (in order) for the module 4. linker transfers control to the ElfXX_Ehdr.e_entry address of the main program It is undefined what happens if a DT_PREINIT_ARRAY, DT_INIT_ARRAY, or DT_INIT function calls dlopen, particularly if the newly-loaded module depends on any other modules, whether or not those modules have been loaded already. (The dependent module might not be initialized yet.) _______________________________________________ Valgrind-users mailing list Valgrind-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-users _______________________________________________ Valgrind-users mailing list Valgrind-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-users