gdbserver: convert the global dll list into a process_info field

The 'all_dlls' list is global.  This would cause the complete dll list
to be reported for individual processes.  Move the list into the
process_info struct.

Currently the dll list is used only by the win32-low target, which
does not support the multi-process feature.  Therefore, it practically
does not matter whether the list is global or per-process.  However,
there may be targets that are outside the binutils-gdb repo (e.g. we,
at Intel, have such a target) that have multi-process and use the dll
list.  So, it makes sense to do the right thing.

gdbserver/ChangeLog:
2021-03-22  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

	* inferiors.h (struct process_info) <all_dlls, dlls_changed>: New
	fields.
	* dll.h (loaded_dll)
	(unloaded_dll): Declare an overloaded version that takes a proc
	parameter.
	* dll.cc (loaded_dll)
	(unloaded_dll): Implement the overloaded versions.
	(clear_dlls): Clear all process' dll lists.
	(all_dlls, dlls_changed): Remove the global variables.
	* remote-utils.cc (prepare_resume_reply): Update to consider a dll
	list per proc.
	* server.cc (handle_qxfer_libraries): Ditto.
	(handle_v_attach): Ditto.
	(captured_main): Ditto.
This commit is contained in:
Tankut Baris Aktemur 2021-03-16 19:36:39 +01:00
parent 2aaf2ce843
commit d171632faa
6 changed files with 70 additions and 20 deletions

View File

@ -1,3 +1,20 @@
2021-03-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
* inferiors.h (struct process_info) <all_dlls, dlls_changed>: New
fields.
* dll.h (loaded_dll)
(unloaded_dll): Declare an overloaded version that takes a proc
parameter.
* dll.cc (loaded_dll)
(unloaded_dll): Implement the overloaded versions.
(clear_dlls): Clear all process' dll lists.
(all_dlls, dlls_changed): Remove the global variables.
* remote-utils.cc (prepare_resume_reply): Update to consider a dll
list per proc.
* server.cc (handle_qxfer_libraries): Ditto.
(handle_v_attach): Ditto.
(captured_main): Ditto.
2021-02-23 Simon Marchi <simon.marchi@polymtl.ca> 2021-02-23 Simon Marchi <simon.marchi@polymtl.ca>
* linux-low.cc (linux_process_target::filter_event): Return * linux-low.cc (linux_process_target::filter_event): Return

View File

@ -23,23 +23,40 @@
/* An "unspecified" CORE_ADDR, for match_dll. */ /* An "unspecified" CORE_ADDR, for match_dll. */
#define UNSPECIFIED_CORE_ADDR (~(CORE_ADDR) 0) #define UNSPECIFIED_CORE_ADDR (~(CORE_ADDR) 0)
std::list<dll_info> all_dlls; /* Record a newly loaded DLL at BASE_ADDR for the current process. */
int dlls_changed;
/* Record a newly loaded DLL at BASE_ADDR. */
void void
loaded_dll (const char *name, CORE_ADDR base_addr) loaded_dll (const char *name, CORE_ADDR base_addr)
{ {
all_dlls.emplace_back (name != NULL ? name : "", base_addr); loaded_dll (current_process (), name, base_addr);
dlls_changed = 1;
} }
/* Record that the DLL with NAME and BASE_ADDR has been unloaded. */ /* Record a newly loaded DLL at BASE_ADDR for PROC. */
void
loaded_dll (process_info *proc, const char *name, CORE_ADDR base_addr)
{
gdb_assert (proc != nullptr);
proc->all_dlls.emplace_back (name != nullptr ? name : "", base_addr);
proc->dlls_changed = true;
}
/* Record that the DLL with NAME and BASE_ADDR has been unloaded
from the current process. */
void void
unloaded_dll (const char *name, CORE_ADDR base_addr) unloaded_dll (const char *name, CORE_ADDR base_addr)
{ {
unloaded_dll (current_process (), name, base_addr);
}
/* Record that the DLL with NAME and BASE_ADDR has been unloaded
from PROC. */
void
unloaded_dll (process_info *proc, const char *name, CORE_ADDR base_addr)
{
gdb_assert (proc != nullptr);
auto pred = [&] (const dll_info &dll) auto pred = [&] (const dll_info &dll)
{ {
if (base_addr != UNSPECIFIED_CORE_ADDR if (base_addr != UNSPECIFIED_CORE_ADDR
@ -52,9 +69,10 @@ unloaded_dll (const char *name, CORE_ADDR base_addr)
return false; return false;
}; };
auto iter = std::find_if (all_dlls.begin (), all_dlls.end (), pred); auto iter = std::find_if (proc->all_dlls.begin (), proc->all_dlls.end (),
pred);
if (iter == all_dlls.end ()) if (iter == proc->all_dlls.end ())
/* For some inferiors we might get unloaded_dll events without having /* For some inferiors we might get unloaded_dll events without having
a corresponding loaded_dll. In that case, the dll cannot be found a corresponding loaded_dll. In that case, the dll cannot be found
in ALL_DLL, and there is nothing further for us to do. in ALL_DLL, and there is nothing further for us to do.
@ -68,13 +86,16 @@ unloaded_dll (const char *name, CORE_ADDR base_addr)
{ {
/* DLL has been found so remove the entry and free associated /* DLL has been found so remove the entry and free associated
resources. */ resources. */
all_dlls.erase (iter); proc->all_dlls.erase (iter);
dlls_changed = 1; proc->dlls_changed = true;
} }
} }
void void
clear_dlls (void) clear_dlls (void)
{ {
all_dlls.clear (); for_each_process ([] (process_info *proc)
{
proc->all_dlls.clear ();
});
} }

View File

@ -20,6 +20,8 @@
#include <list> #include <list>
struct process_info;
struct dll_info struct dll_info
{ {
dll_info (const std::string &name_, CORE_ADDR base_addr_) dll_info (const std::string &name_, CORE_ADDR base_addr_)
@ -30,11 +32,12 @@ struct dll_info
CORE_ADDR base_addr; CORE_ADDR base_addr;
}; };
extern std::list<dll_info> all_dlls;
extern int dlls_changed;
extern void clear_dlls (void); extern void clear_dlls (void);
extern void loaded_dll (const char *name, CORE_ADDR base_addr); extern void loaded_dll (const char *name, CORE_ADDR base_addr);
extern void loaded_dll (process_info *proc, const char *name,
CORE_ADDR base_addr);
extern void unloaded_dll (const char *name, CORE_ADDR base_addr); extern void unloaded_dll (const char *name, CORE_ADDR base_addr);
extern void unloaded_dll (process_info *proc, const char *name,
CORE_ADDR base_addr);
#endif /* GDBSERVER_DLL_H */ #endif /* GDBSERVER_DLL_H */

View File

@ -20,6 +20,7 @@
#define GDBSERVER_INFERIORS_H #define GDBSERVER_INFERIORS_H
#include "gdbsupport/gdb_vecs.h" #include "gdbsupport/gdb_vecs.h"
#include "dll.h"
#include <list> #include <list>
struct thread_info; struct thread_info;
@ -68,6 +69,12 @@ struct process_info
/* Private target data. */ /* Private target data. */
struct process_info_private *priv = NULL; struct process_info_private *priv = NULL;
/* DLLs thats are loaded for this proc. */
std::list<dll_info> all_dlls;
/* Flag to mark that the DLL list has changed. */
bool dlls_changed = false;
}; };
/* Get the pid of PROC. */ /* Get the pid of PROC. */

View File

@ -1270,11 +1270,11 @@ prepare_resume_reply (char *buf, ptid_t ptid,
} }
} }
if (dlls_changed) if (current_process ()->dlls_changed)
{ {
strcpy (buf, "library:;"); strcpy (buf, "library:;");
buf += strlen (buf); buf += strlen (buf);
dlls_changed = 0; current_process ()->dlls_changed = false;
} }
current_thread = saved_thread; current_thread = saved_thread;

View File

@ -1470,7 +1470,8 @@ handle_qxfer_libraries (const char *annex,
std::string document = "<library-list version=\"1.0\">\n"; std::string document = "<library-list version=\"1.0\">\n";
for (const dll_info &dll : all_dlls) process_info *proc = current_process ();
for (const dll_info &dll : proc->all_dlls)
document += string_printf document += string_printf
(" <library name=\"%s\"><segment address=\"0x%s\"/></library>\n", (" <library name=\"%s\"><segment address=\"0x%s\"/></library>\n",
dll.name.c_str (), paddress (dll.base_addr)); dll.name.c_str (), paddress (dll.base_addr));
@ -2848,7 +2849,7 @@ handle_v_attach (char *own_buf)
some libraries are preloaded. GDB will always poll the some libraries are preloaded. GDB will always poll the
library list. Avoids the "stopped by shared library event" library list. Avoids the "stopped by shared library event"
notice on the GDB side. */ notice on the GDB side. */
dlls_changed = 0; current_process ()->dlls_changed = false;
if (non_stop) if (non_stop)
{ {
@ -3796,7 +3797,8 @@ captured_main (int argc, char *argv[])
/* Don't report shared library events on the initial connection, /* Don't report shared library events on the initial connection,
even if some libraries are preloaded. Avoids the "stopped by even if some libraries are preloaded. Avoids the "stopped by
shared library event" notice on gdb side. */ shared library event" notice on gdb side. */
dlls_changed = 0; if (current_thread != nullptr)
current_process ()->dlls_changed = false;
if (cs.last_status.kind == TARGET_WAITKIND_EXITED if (cs.last_status.kind == TARGET_WAITKIND_EXITED
|| cs.last_status.kind == TARGET_WAITKIND_SIGNALLED) || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)