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:
parent
2aaf2ce843
commit
d171632faa
@ -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>
|
||||
|
||||
* linux-low.cc (linux_process_target::filter_event): Return
|
||||
|
@ -23,23 +23,40 @@
|
||||
/* An "unspecified" CORE_ADDR, for match_dll. */
|
||||
#define UNSPECIFIED_CORE_ADDR (~(CORE_ADDR) 0)
|
||||
|
||||
std::list<dll_info> all_dlls;
|
||||
int dlls_changed;
|
||||
|
||||
/* Record a newly loaded DLL at BASE_ADDR. */
|
||||
/* Record a newly loaded DLL at BASE_ADDR for the current process. */
|
||||
|
||||
void
|
||||
loaded_dll (const char *name, CORE_ADDR base_addr)
|
||||
{
|
||||
all_dlls.emplace_back (name != NULL ? name : "", base_addr);
|
||||
dlls_changed = 1;
|
||||
loaded_dll (current_process (), name, base_addr);
|
||||
}
|
||||
|
||||
/* 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
|
||||
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)
|
||||
{
|
||||
if (base_addr != UNSPECIFIED_CORE_ADDR
|
||||
@ -52,9 +69,10 @@ unloaded_dll (const char *name, CORE_ADDR base_addr)
|
||||
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
|
||||
a corresponding loaded_dll. In that case, the dll cannot be found
|
||||
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
|
||||
resources. */
|
||||
all_dlls.erase (iter);
|
||||
dlls_changed = 1;
|
||||
proc->all_dlls.erase (iter);
|
||||
proc->dlls_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clear_dlls (void)
|
||||
{
|
||||
all_dlls.clear ();
|
||||
for_each_process ([] (process_info *proc)
|
||||
{
|
||||
proc->all_dlls.clear ();
|
||||
});
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
struct process_info;
|
||||
|
||||
struct dll_info
|
||||
{
|
||||
dll_info (const std::string &name_, CORE_ADDR base_addr_)
|
||||
@ -30,11 +32,12 @@ struct dll_info
|
||||
CORE_ADDR base_addr;
|
||||
};
|
||||
|
||||
extern std::list<dll_info> all_dlls;
|
||||
extern int dlls_changed;
|
||||
|
||||
extern void clear_dlls (void);
|
||||
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 (process_info *proc, const char *name,
|
||||
CORE_ADDR base_addr);
|
||||
|
||||
#endif /* GDBSERVER_DLL_H */
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define GDBSERVER_INFERIORS_H
|
||||
|
||||
#include "gdbsupport/gdb_vecs.h"
|
||||
#include "dll.h"
|
||||
#include <list>
|
||||
|
||||
struct thread_info;
|
||||
@ -68,6 +69,12 @@ struct process_info
|
||||
|
||||
/* Private target data. */
|
||||
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. */
|
||||
|
@ -1270,11 +1270,11 @@ prepare_resume_reply (char *buf, ptid_t ptid,
|
||||
}
|
||||
}
|
||||
|
||||
if (dlls_changed)
|
||||
if (current_process ()->dlls_changed)
|
||||
{
|
||||
strcpy (buf, "library:;");
|
||||
buf += strlen (buf);
|
||||
dlls_changed = 0;
|
||||
current_process ()->dlls_changed = false;
|
||||
}
|
||||
|
||||
current_thread = saved_thread;
|
||||
|
@ -1470,7 +1470,8 @@ handle_qxfer_libraries (const char *annex,
|
||||
|
||||
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
|
||||
(" <library name=\"%s\"><segment address=\"0x%s\"/></library>\n",
|
||||
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
|
||||
library list. Avoids the "stopped by shared library event"
|
||||
notice on the GDB side. */
|
||||
dlls_changed = 0;
|
||||
current_process ()->dlls_changed = false;
|
||||
|
||||
if (non_stop)
|
||||
{
|
||||
@ -3796,7 +3797,8 @@ captured_main (int argc, char *argv[])
|
||||
/* Don't report shared library events on the initial connection,
|
||||
even if some libraries are preloaded. Avoids the "stopped by
|
||||
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
|
||||
|| cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
|
||||
|
Loading…
x
Reference in New Issue
Block a user