[PATCH v2 33/47] gdbserver: adjust pid after the target attaches

Tankut Baris Aktemur
2024-12-13T16:35:24Z

The PID argument of the attach operation may be interpreted in a
target specific way, and may not necessarily mean that the process we
attached to has PID as its process id. This is for example the case
for Intel GT targets, where the PID refers to the process id of the
host application that is using the devices. The target in that case
creates a new process for each device where the PID of the process is
the device id/ordinal. Therefore, once the target completes the
attach, we want adjust the PID value. For this, revise the meaning
of the return value of the 'attach' target op in case of success:
return the PID of the process that was attached to.

The PID argument to the 'attach' target op is of type 'int' in caller
sites. Also, the type of the PID field in ptid_t is of type 'int'.
Hence, update the parameter of 'attach' to 'int', too.
---
gdbserver/linux-low.cc | 6 +++---
gdbserver/linux-low.h | 2 +-
gdbserver/netbsd-low.cc | 2 +-
gdbserver/netbsd-low.h | 2 +-
gdbserver/server.cc | 18 ++++++++++++++----
gdbserver/target.h | 11 ++++++++---
gdbserver/win32-low.cc | 4 ++--
gdbserver/win32-low.h | 2 +-
8 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index dfe4c6a39a0b3a6eaaf8aea71d45f2025bf09471..dd580b3f484d1700f1df1a229904fbcce5196544 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -1156,7 +1156,7 @@ static void async_file_mark (void);
of its threads. */

int
-linux_process_target::attach (unsigned long pid)
+linux_process_target::attach (int pid)
{
struct process_info *proc;
thread_info *initial_thread;
@@ -1175,7 +1175,7 @@ linux_process_target::attach (unsigned long pid)
this->remove_linux_process (proc);

std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
- error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
+ error ("Cannot attach to process %d: %s", pid, reason.c_str ());
}

open_proc_mem_file (proc);
@@ -1239,7 +1239,7 @@ linux_process_target::attach (unsigned long pid)
gdb_assert (proc->tdesc != NULL);
}

- return 0;
+ return pid;
}

static int
diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h
index 5be00b8c98cb87fb12277ac269d804e1efe602e1..05fb7985c4199fd5038f19998e333599a1ecfb65 100644
--- a/gdbserver/linux-low.h
+++ b/gdbserver/linux-low.h
@@ -145,7 +145,7 @@ class linux_process_target : public process_stratum_target

void post_create_inferior () override;

- int attach (unsigned long pid) override;
+ int attach (int pid) override;

int kill (process_info *proc) override;

diff --git a/gdbserver/netbsd-low.cc b/gdbserver/netbsd-low.cc
index 04e103563e793a06fbd90a7bbcb139da8a4b9a63..a246cc2befac7477f05fcce407a505250e79c46a 100644
--- a/gdbserver/netbsd-low.cc
+++ b/gdbserver/netbsd-low.cc
@@ -107,7 +107,7 @@ netbsd_process_target::post_create_inferior ()
/* Implement the attach target_ops method. */

int
-netbsd_process_target::attach (unsigned long pid)
+netbsd_process_target::attach (int pid)
{
/* Unimplemented. */
return -1;
diff --git a/gdbserver/netbsd-low.h b/gdbserver/netbsd-low.h
index 53200ddffc42a8102f66f0808289589e65af8762..00a0287384a37c859dbb8216c6217020d4e1d583 100644
--- a/gdbserver/netbsd-low.h
+++ b/gdbserver/netbsd-low.h
@@ -46,7 +46,7 @@ class netbsd_process_target : public process_stratum_target

void post_create_inferior () override;

- int attach (unsigned long pid) override;
+ int attach (int pid) override;

int kill (process_info *proc) override;

diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index b144d2b165564f1681e1082e230fdbbeac8d3bf6..db68ca6c74bd6e5b17565163906cccddabe80bcc 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -297,16 +297,26 @@ static int
attach_inferior (int pid)
{
client_state &cs = get_client_state ();
- /* myattach should return -1 if attaching is unsupported,
- 0 if it succeeded, and call error() otherwise. */

if (find_process_pid (pid) != nullptr)
error ("Already attached to process %d\n", pid);

- if (myattach (pid) != 0)
+ /* If attaching is unsupported, myattach returns -1. If successful,
+ it returns the PID of the process that was attached to. In other
+ cases, it calls error(). */
+ int new_pid = myattach (pid);
+ if (new_pid == -1)
return -1;

- fprintf (stderr, "Attached; pid = %d\n", pid);
+ if (new_pid == pid)
+ fprintf (stderr, "Attached; pid = %d\n", pid);
+ else
+ {
+ fprintf (stderr, "Attached; given pid = %d, updated to %d\n",
+ pid, new_pid);
+ pid = new_pid;
+ }
+
fflush (stderr);

/* FIXME - It may be that we should get the SIGNAL_PID from the
diff --git a/gdbserver/target.h b/gdbserver/target.h
index 2fa88e09ffbc65c37fe468bbc5ea3580971ccfdb..93e1f066955b7b3fde50fa965346e028dcf784af 100644
--- a/gdbserver/target.h
+++ b/gdbserver/target.h
@@ -94,9 +94,14 @@ class process_stratum_target
PID is the process ID to attach to, specified by the user
or a higher layer.

- Returns -1 if attaching is unsupported, 0 on success, and calls
- error() otherwise. */
- virtual int attach (unsigned long pid) = 0;
+ If attaching is unsupported, returns -1.
+
+ If successful, returns the ID of the process that was attached to.
+ This return value may be different from the argument PID, depending
+ on how the target interpreted the argument.
+
+ Calls error() in other cases. */
+ virtual int attach (int pid) = 0;

/* Kill process PROC. Return -1 on failure, and 0 on success. */
virtual int kill (process_info *proc) = 0;
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 49f0ed3b1f4d2b2ac1d1c194d3910e4918568241..a9dda19e707a8cfe2b2209b95974025fff514e14 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -585,7 +585,7 @@ win32_process_target::create_inferior (const char *program,
PID is the process ID to attach to, specified by the user
or a higher layer. */
int
-win32_process_target::attach (unsigned long pid)
+win32_process_target::attach (int pid)
{
HANDLE h;
DWORD err;
@@ -600,7 +600,7 @@ win32_process_target::attach (unsigned long pid)
/* win32_wait needs to know we're attaching. */
windows_process.attaching = 1;
do_initial_child_stuff (h, pid, 1);
- return 0;
+ return pid;
}

CloseHandle (h);
diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h
index daed16a6ae6a097ad4383c7ebe8b3cd3752b5eae..5c7f195e8c4eaa7568d457f17c1f4802192100c6 100644
--- a/gdbserver/win32-low.h
+++ b/gdbserver/win32-low.h
@@ -103,7 +103,7 @@ class win32_process_target : public process_stratum_target
int create_inferior (const char *program,
const std::vector<char *> &program_args) override;

- int attach (unsigned long pid) override;
+ int attach (int pid) override;

int kill (process_info *proc) override;