Dear all, The code bellow in the dladdr function has different behaviors at different optimization levels. 2219 if (bestsym && besterr > bestsym->st_size-1) { 2220 best = 0; 2221 bestsym = 0; 2222 } Case of O1(arm32 little-endian): 154: e3580000 cmp r8, #0 158: 0a000003 beq 16c 15c: e5983008 ldr r3, [r8, #8] 160: e2433001 sub r3, r3, #1 164: e153000a cmp r3, sl 168: 3a000011 bcc 1bc Case of O2: 75e00: e5942044 ldr r2, [r4, #68] ; 0x44 75e04: e2433001 sub r3, r3, #1 75e08: e5941004 ldr r1, [r4, #4] 75e0c: e1530009 cmp r3, r9 75e10: 2a000007 bcs 75e34 75e14: e8870006 stm r7, {r1, r2} In case of O2, the first part "bestsym" has been optimized, which may cause segment fault. [patch] Signed-off-by: l00383200 > --- ldso/dynlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 7cb66db..c5f5fb7 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -2175,7 +2175,8 @@ int dladdr(const void *addr_arg, Dl_info *info) { size_t addr = (size_t)addr_arg; struct dso *p; - Sym *sym, *bestsym; + Sym *sym = NULL; + Sym *bestsym = NULL; uint32_t nsym; char *strings; size_t best = 0; -- 1.8.5.6 [testcase] ------------ #define _GNU_SOURCE #include #include #include #include #include static int callback(struct dl_phdr_info *info, size_t size, void *data) { int j,ret; printf ("name=%s (%d segments)\n", info->dlpi_name, info->dlpi_phnum); if(!strcmp(info->dlpi_name,"/lib/ld-musl-arm.so.1")) { printf("ld-musl-arm have no indo\n"); return 0; } for (j = 0; j < info->dlpi_phnum; j++) { void* addr = (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr); printf ("\t\t header %2d: address=%10p\n", j, addr); Dl_info dlinfo; ret = dladdr(addr, &dlinfo); printf("\t\t\t %s : %s.", dlinfo.dli_fname, dlinfo.dli_sname); if((addr == NULL && ret == 0) || (addr != NULL && ret == 1)) { printf(" dladdr pass return:%d\n",ret); } else { printf(" dladdr error return:%d\n",ret); } } return 0; } int main (int argc, char *argv[]) { dl_iterate_phdr(callback, NULL); exit(EXIT_SUCCESS); } ------------