stub doesn't report this feature supported, then GDB will not use
the 'x' packet.
+* MI changes
+
+** The =library-unloaded event now includes the 'ranges' field, which
+ has the same meaning as for the =library-loaded event.
+
+** The =library-unloaded event now includes the 'still-in-use' field.
+ This field is 'true' when a library is unloaded (removed from the
+ inferior's list of loaded libraries), but the mapping within the
+ inferior's address space is retained, as the library was mapped
+ multiple times, and the same mapping was being reused. In all
+ other cases, this field will have the value 'false'.
+
*** Changes in GDB 16
* Support for Nios II targets has been removed as this architecture
@item =library-unloaded,...
Reports that a library was unloaded by the program. This notification
-has 3 fields---@var{id}, @var{target-name} and @var{host-name} with
-the same meaning as for the @code{=library-loaded} notification.
+has the following fields---@var{id}, @var{target-name},
+@var{host-name} and @var{ranges} with the same meaning as for the
+@code{=library-loaded} notification.
+
+It is possible that a library can appear multiple times in an
+inferior's library list, but the library is only mapped once into the
+inferior's address space. When this happens, and one copy of the
+library is unloaded, but there are remaining copies, the
+@var{still-in-use} field will be @samp{true}. In all other
+situations, the @var{still-in-use} field will have the value
+@samp{false}.
+
The @var{thread-group} field, if present, specifies the id of the
-thread group in whose context the library was unloaded. If the field is
-absent, it means the library was unloaded in the context of all present
-thread groups.
+thread group in whose context the library was unloaded. If the field
+is absent, it means the library was unloaded in the context of all
+present thread groups.
@item =traceframe-changed,num=@var{tfnum},tracepoint=@var{tpnum}
@itemx =traceframe-changed,end
/* See mi-interp.h. */
-void
-mi_output_solib_attribs (ui_out *uiout, const solib &solib)
+static void
+mi_output_solib_attribs_1 (ui_out *uiout, const solib &solib,
+ bool include_symbols_loaded_p)
{
gdbarch *gdbarch = current_inferior ()->arch ();
uiout->field_string ("id", solib.so_original_name);
uiout->field_string ("target-name", solib.so_original_name);
uiout->field_string ("host-name", solib.so_name);
- uiout->field_signed ("symbols-loaded", solib.symbols_loaded);
+ if (include_symbols_loaded_p)
+ uiout->field_signed ("symbols-loaded", solib.symbols_loaded);
if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
}
}
+/* See mi-interp.h. */
+
+void
+mi_output_solib_attribs (ui_out *uiout, const solib &solib)
+{
+ mi_output_solib_attribs_1 (uiout, solib, true);
+}
+
void
mi_interp::on_solib_loaded (const solib &solib)
{
ui_out_redirect_pop redir (uiout, this->event_channel);
- uiout->field_string ("id", solib.so_original_name);
- uiout->field_string ("target-name", solib.so_original_name);
- uiout->field_string ("host-name", solib.so_name);
- if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
- uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
+ /* Pass false here so that 'symbols-loaded' is not included. */
+ mi_output_solib_attribs_1 (uiout, solib, false);
+ uiout->field_string ("still-in-use", still_in_use ? "true" : "false");
gdb_flush (this->event_channel);
}
# unload events. Process them now.
set dyld_unload_count 0
array set unload_counts {}
+ set still_in_use_fields_correct true
gdb_test_multiple "" "" -prompt $::mi_gdb_prompt {
- -re "=library-unloaded,id=\"(\[^\"\]+)\",\[^\r\n\]+\r\n" {
+ -re "=library-unloaded,id=\"(\[^\"\]+)\",\[^\r\n\]+,ranges=\\\[\\{from=\"$::hex\",to=\"$::hex\"\\}\\\],still-in-use=\"(true|false)\"\r\n" {
set lib $expect_out(1,string)
+ set in_use $expect_out(2,string)
if {[is_dyln $lib]} {
# This is the dynamic linker being unloaded.
incr dyld_unload_count
+ set expected_in_use "true"
+ } else {
+ set expected_in_use "false"
}
+
+ if { $in_use ne $expected_in_use } {
+ set still_in_use_fields_correct false
+ }
+
set filename [file tail $lib]
incr unload_counts($filename)
exp_continue
gdb_assert { $dyld_unload_count == $dyld_count - 1 } \
"expected number of dynamic linker unloads"
+ gdb_assert { $still_in_use_fields_correct } \
+ "still-in-use fields were all correct"
+
# Check that we saw the expected number of library-unloaded events for
# each library. Each DESC is a list of two elements, a filename for a
# library, and the number of times it should have been unloaded.