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

Reply via email to