di = find_or_create_DebugInfo_for( filename );
vg_assert(di);
+ /* Ignore all mappings for this filename once we've read debuginfo for it.
+ This avoids the confusion of picking up "irrelevant" mappings in
+ applications which mmap their objects outside of ld.so, for example
+ Firefox's Gecko profiler.
+
+ What happens in that case is: the application maps the object "ro" for
+ whatever reason. We record the mapping di->fsm.maps. The application
+ later unmaps the object. However, the mapping is not removed from
+ di->fsm.maps. Later, when some other (unrelated) object is mapped (via
+ ld.so) into that address space, we first unload any debuginfo that has a
+ mapping intersecting that area. That means we will end up incorrectly
+ unloading debuginfo for the object with the "irrelevant" mappings. This
+ causes various problems, not least because it can unload the debuginfo
+ for libc.so and so cause malloc intercepts to become un-intercepted.
+
+ This fix assumes that all mappings made once we've read debuginfo for
+ an object are irrelevant. I think that's OK, but need to check with
+ mjw/thh. */
+ if (di->have_dinfo) {
+ if (debug)
+ VG_(printf)("di_notify_mmap-4x: "
+ "ignoring mapping because we already read debuginfo "
+ "for DebugInfo* %p\n", di);
+ return 0;
+ }
+
if (debug)
VG_(printf)("di_notify_mmap-4: "
"noting details in DebugInfo* at %p\n", di);
di->fsm.have_ro_map |= is_ro_map;
/* So, finally, are we in an accept state? */
- if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
+ vg_assert(!di->have_dinfo);
+ if (di->fsm.have_rx_map && di->fsm.have_rw_map) {
/* Ok, so, finally, we found what we need, and we haven't
already read debuginfo for this object. So let's do so now.
Yee-ha! */