This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
dangling pointer in so_list
- From: Aleksandar Ristovski <aristovski at qnx dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 31 Aug 2011 16:01:08 -0400
- Subject: dangling pointer in so_list
Hello,
I run into a gdb crash examining a core file. This happened on gdb 7.3,
on QNX. Unfortunately, I could not come up with a reproducible testcase
on gnu/linux due to differences in dynamic linkers, but offer a detailed
explanation instead:
What happened is that a process loaded the same shared object more than
once. Then it crashed and a core was generated.
In the core, we had a link map specifying the same shared object more
than once. While traversing the link map, gdb loaded shared objects
(symbols), thus associating each so_list object with an objfile object.
During the process, it detected duplicates and associated multiple
so_list objects with the same objfile instance.
At this point, a change to solib-search-path causes gdb to reload
symbols, and the crash happens: while traversing so_list in
solib.c:reload_shared_libraries_1, in one iteration gdb calls
'free_objfile' with a pointer to an instance of the objfile. In a
subsequent iteration, it tries to do the same with, now, dangling
pointer to the same objfile object. Not good.
The attached patch fixes the issue.
Thanks,
Aleksandar Ristovski
QNX Software Systems
ChangeLog:
<date> Aleksandar Ristovski <aristovski@qnx.com>
* solib.c (reload_shared_libraries_1): Check whether objfile is
used before
freeing it.
Index: gdb/solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.153
diff -u -p -r1.153 solib.c
--- gdb/solib.c 30 Aug 2011 02:48:05 -0000 1.153
+++ gdb/solib.c 31 Aug 2011 19:20:44 -0000
@@ -1226,7 +1226,22 @@ reload_shared_libraries_1 (int from_tty)
&& filename_cmp (found_pathname, so->so_name) != 0))
{
if (so->objfile && ! (so->objfile->flags & OBJF_USERLOADED))
- free_objfile (so->objfile);
+ {
+ struct so_list *pivot;
+ int used = 0;
+
+ for (pivot = so_list_head; pivot != NULL; pivot = pivot->next)
+ {
+ if (pivot != so && pivot->objfile == so->objfile)
+ {
+ used = 1;
+ break;
+ }
+ }
+
+ if (!used)
+ free_objfile (so->objfile);
+ }
remove_target_sections (so->abfd);
free_so_symbols (so);
}