Re: 答复: Some question about linker dlopen with valgrind

John Reiser <[email protected]>
Newsgroups gmane.comp.debugging.valgrind
Message-ID <[email protected]>
On 4/24/2019 0128 UTC, Wuweijia wrote:
> Android Q
> 
> The libc  source  as below:

The purpose of a test case is to reproduce the problem.  What you wrote fails badly.
It does not compile, under ANY compiler: functions are used before they are declared.
It does not have the necessary #include statements.
It is not written in C language.  'reinterpret_cast' is C++.
It is not standard C++.  __has_builtin() (from Android #include) is only in the 'clang' dialect.
It uses symbols that start with underscore ('_') without understanding what it is doing.
They're written with a leading underscore to warn you that you should not touch them.

You should have said:
    git clone https://android.googlesource.com/platform/bionic/
    git clone https://android.googlesource.com/platform/system/core

===== test-libc.cpp
#include <dlfcn.h>
#include <stdio.h>
#include <stdint.h>
#include <private/bionic_ssp.h>
#include <private/__get_tls.h>
#include <private/bionic_asm_tls.h>
#include <private/bionic_globals.h>
#include <bionic/libc_init_common.h>


static void TestInitImpl() {
         printf("%s enter\n", __func__);
//-----------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;
         void * handle = dlopen("liblog.so",  RTLD_NOW );
         printf("handle:%p\n", handle);
}

__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();
}

__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();
}
=====

export ADIR=$PWD  # after "git clone" above
# -I list: Android source is crap.
test-libc.so: test-libc.cpp
	clang++ -shared -fPIC -g -nostdinc \
	  -I$(ADIR)/bionic/libc/include \
	  -I$(ADIR)/bionic/libc \
	  -I$(ADIR)/bionic/libc/async_safe/include \
	  -I$(ADIR)/core/liblog/include \
	  -I/usr/lib/gcc/x86_64-redhat-linux/8/include \
	  -I/usr/include \
	  $< -o $@
=====


 >          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;

So calling dlopen() while still in the initialization phase of the run-time linker,
causes trouble for valgrind.  Get the source, apply a debugger, and find out why.

Calling dlopen() from a DT_INIT, DT_INIT_ARRAY, or DT_PREINIT_ARRAY function
is a design error: the run-time linker makes NO guarantees about what happens.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.