提交 711283b6 编写于 作者: G guzhihao4

Fix dlclose error about weak symbol dependency

Do unmap_library after all dependent libraries are closed.

Test: local test pass & libctest pass
Issue: #I7SRPDw
Signed-off-by: Nguzhihao4 <guzhihao4@huawei.com>
Change-Id: Ie27666dfb07e85d7123150ba26797626bbc46c79
上级 dc6ae366
......@@ -39,6 +39,11 @@ test_sharedlib("tls_align_dso") {
}
test_sharedlib("atexit_dlclose_dso") {
}
test_sharedlib("dlopen_weak_deps") {
}
test_sharedlib("dlopen_weak") {
deps = [ ":dlopen_weak_deps" ]
}
group("dso_shared") {
testonly = true
......@@ -51,6 +56,8 @@ group("dso_shared") {
":dlopen_for_load_by_local_dso",
":dlopen_ns_dso",
":dlopen_so_dep_dlopen_ns_dso",
":dlopen_weak",
":dlopen_weak_deps",
":tls_align_dso",
":tls_init_dso",
]
......
......@@ -121,6 +121,23 @@ void dlopen_dlclose()
}
}
#define DLOPEN_WEAK "libdlopen_weak.so"
typedef int (*FuncPtr_TestNumber)(int input);
void dlopen_dlclose_weak()
{
void* handle = dlopen(DLOPEN_WEAK, RTLD_LAZY | RTLD_GLOBAL);
if (!handle)
t_error("dlopen(name=%s, mode=%d) failed: %s\n", DLOPEN_WEAK, RTLD_LAZY | RTLD_GLOBAL, dlerror());
FuncPtr_TestNumber fn = (FuncPtr_TestNumber)dlsym(handle, "TestNumber");
if (fn) {
int ret = fn(12);
if (ret != 0)
t_error("weak symbol relocation error: so_name: %s, symbol: TestNumber\n", DLOPEN_WEAK);
}
dlclose(handle);
}
int main(int argc, char *argv[])
{
void *h, *g;
......@@ -179,6 +196,7 @@ int main(int argc, char *argv[])
dlopen_so_used_by_dlsym();
dlopen_nodelete_and_noload();
dlopen_dlclose();
dlopen_dlclose_weak();
return t_status;
}
#include "dlopen_weak_deps.h"
__attribute__((weak)) int TestFunction(int input)
{
return input % 2;
}
int TestNumber(int input)
{
return TestNumber2(input);
}
__attribute__((weak)) int TestFunction(int input)
{
return input % 5;
}
int TestNumber2(int input)
{
return TestFunction(input) == 2;
}
int TestNumber2(int input);
__attribute__((weak)) int TestFunction(int input);
......@@ -3754,7 +3754,7 @@ static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra)
extern int invalidate_exit_funcs(struct dso *p);
static int dlclose_impl(struct dso *p)
static int dlclose_impl(struct dso *p, struct dso **dso_close_list, int *dso_close_list_size)
{
size_t n;
struct dso *d;
......@@ -3864,7 +3864,9 @@ static int dlclose_impl(struct dso *p)
if (p->deps != no_deps)
free(p->deps);
LD_LOGD("dlclose unloading %{public}s @%{public}p", p->name, p);
unmap_library(p);
dso_close_list[*dso_close_list_size] = p;
*dso_close_list_size += 1;
if (p->parents) {
free(p->parents);
......@@ -3906,16 +3908,25 @@ static int do_dlclose(struct dso *p)
memcpy(deps_bak, p->deps, deps_num*sizeof(struct dso*));
}
struct dso **dso_close_list = malloc((deps_num + 1) * sizeof(struct dso*));
memset(dso_close_list, 0, deps_num + 1);
int dso_close_list_size = 0;
LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", p->name, p->nr_dlopen, p->by_dlopen);
dlclose_impl(p);
dlclose_impl(p, dso_close_list, &dso_close_list_size);
if (ldclose_deps) {
for (size_t i = 0; i < deps_num; i++) {
LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", deps_bak[i]->name, deps_bak[i]->nr_dlopen, deps_bak[i]->by_dlopen);
dlclose_impl(deps_bak[i]);
dlclose_impl(deps_bak[i], dso_close_list, &dso_close_list_size);
}
}
for (size_t i = 0; i < dso_close_list_size; i++) {
unmap_library(dso_close_list[i]);
}
free(dso_close_list);
free(deps_bak);
return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册