Hi, Ref: http://www.mail-archive.com/svn-src-all_at_freebsd.org/msg10960.html Log: Allow order of initialization of loaded shared objects to be altered through their .init code. This might happen if init vector calls dlopen on its own and that dlopen causes some not yet initialized object to be initialized earlier as part of that dlopened DAG. Do not reset module reference counts to zero on final fini vector run when process is exiting. Just add an additional parameter to force fini vector invocation regardless of current reference count value if object was not destructed yet. This allows dlclose called from fini vector to proceed normally instead of failing with handle validation error. Query: ------- I have one question regarding " Do not reset module reference counts to zero on final fini vector run when process is exiting". Observation: --------------- The above issue normally happened when object is destructed and gives handle validation error. I have expected this is related to dl_refcount issue when process is exiting. Am just giving some more explanation regarding this issue: When i tested in the my Linux environment it shows the dl_reference count is 1 when dlopen and 0 when dlclose. In this test when the main dlclose invokes, the reference count is decremented to zero But still other dependent objects are present and for these objects dl_reference count is required with one(1) to close the handle successfully. As per dl* scenario, the dl_reference count has to be incremented by one(1) for the main object(main executable) as well as other ELF dependencies object. Now, I have invoked dl_reference count is incremented by one(1) for main object handle in _rtld_map_object function which is called by _rtld(). rtld Changes: --------------- _rtld(): /* Load the main program. */ Location: src/libexec/ld.elf_so/rtld.c: _rtld_objmain = _rtld_map_object(obj_name, fd, NULL); _rtld_map_object(): / * * Map a shared object into memory. The argument is a file descriptor, * which must be open on the object and positioned at its beginning. * The return value is a pointer to a newly-allocated Obj_Entry structure * for the shared object. Returns NULL on failure. */ --- a/src/libexec/ld.elf_so/map_object.c +++ b/src/libexec/ld.elf_so/map_object.c _at__at_ -181,6 +181,10 _at__at_ _rtld_map_object(const char *path, int f phdr = (Elf_Phdr *) ((caddr_t)ehdr + ehdr->e_phoff); phlimit = phdr + ehdr->e_phnum; nsegs = 0; + + /* + * And it was opened directly If trying to open + * the link map for the main executable. So the dl_recount + * must be the main dlopen one. + */ + ++obj->dl_refcount; + while (phdr < phlimit) { switch (phdr->p_type) { case PT_INTERP: After the above changes, [libc] dlclose does not give "invalid shared object handle" with/without pthread combination Since the dl_reference count is 2 instead of 1 for main object handle and 1 instead of 0 for other dependent objects. Could you give opinion about the above issue? Thanks & Regards, Venkappa ---------- Forwarded message ---------- From: venki kaps <venkiece2005_at_gmail.com> Date: Fri, Jun 19, 2009 at 10:18 AM Subject: [libc] dlclose gives "invalid shared object handle" without pthread combination. To: gnats-bugs_at_netbsd.org Hi, I am using the NetBSD implementation of rtld(src/libexec/ld.elf_so/) for ARM/MIPS and have been porting NetBSD source in the Linux environment with our own pthread library. system environment: Compiler: arm-linux-gcc-4.3.3 OS: Linux Kernel: 2.6.29 I have C++ static constructor/destructor issue with my rtld. Problem Report: "ld.elf_so does not execute .init/.fini functions in order" and [libc] dlclose gives "invalid shared object handle" when called through the fini function of another module. The similar NetBSD/freeBSD issues are found from the following References: [1] http://gnats.netbsd.org/37347 [2] http://updraft3.jp.freebsd.org/cgi/query-pr.cgi?pr=kern/42956 The above issues are already commited in NetBSD-5-0-RELEASE. I have ported NetBSD-5-0-RELEASE rtld and tested Ref[1] provided static constructor/destructor test and did not find any issues with shared pthread combination but noticed [libc] dlclose gives "invalid shared object handle" without pthread combination. The static constructor/destructor test results: It should be : -------------- $ ./foobar foo_ctor bar_ctor tar_ctor main_ctor dep1_ctor dep2_ctor dll_ctor dll_dtor dep2_dtor dep1_dtor main_dtor tar_dtor bar_dtor foo_dtor While currently I get: ---------------------- with pthreads: $ ./foobar foo_ctor bar_ctor tar_ctor main_ctor dep1_ctor dep2_ctor dll_ctor dll_dtor dep2_dtor dep1_dtor main_dtor tar_dtor bar_dtor foo_dtor without pthreads: $ ./foobar foo_ctor bar_ctor tar_ctor main_ctor dep1_ctor dep2_ctor dll_ctor dll_dtor dep2_dtor dep1_dtor main_dtor tar_dtor bar_dtor foo_dtor Invalid shared object handle 0xbdbed400 This gives a "invalid shared object handle" message because the refcount field (obj->dl_refcount) for the handle is zero. it never even calls dlerr() in dlcose but __dlclose(void *handle) source sequence, int dlclose(void *handle) { Obj_Entry *root = _rtld_dlcheck(handle); if (root == NULL) return -1; _rtld_debug.r_state = RT_DELETE; _rtld_debug_state(); --root->dl_refcount; _rtld_unload_object(root, true); _rtld_debug.r_state = RT_CONSISTENT; _rtld_debug_state(); return 0; } static Obj_Entry * _rtld_dlcheck(void *handle) { Obj_Entry *obj; for (obj = _rtld_objlist; obj != NULL; obj = obj->next) if (obj == (Obj_Entry *) handle) break; xprintf("obj->dl_refcount is %d\n",obj->dl_refcount); if (obj == NULL || obj->dl_refcount == 0) { xwarnx("Invalid shared object handle %p", handle); return NULL; } return obj; } I have printed xprintf("obj->dl_refcount is %d\n",obj->dl_refcount); obj->dl_refcount is getting zero(0). So due to "obj->dl_refcount == 0" the error "invalid shared object handle" is showing. I have little bit confused about dlclose destructor with/without pthreads. I have some queries: 1) Is it required any changes apart from the NetBSD-5-0-RELEASE/{Ref[1],[2]}? 2) Are any changes required in thread-stub? 3) i do not know why this error is coming even though all the constructor/destructor sequences are completed. 4) is it rtld_exit/fini/static C++ destructor/dlcose sequence problem? (OR) is it crtstuff/exit/atexit/cxa_finalize/cxa_atexit sequence problem? Could anyone provide any inputs to the my issue? Thanks in advance. Thanks & Regards, VenkappaReceived on Mon Jun 29 2009 - 05:33:18 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:50 UTC