diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-03-13 15:02:25 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-03-13 15:02:25 +0000 |
commit | 87b0bb13cbbea83ec1896b3ab915c8ce48ab6d44 (patch) | |
tree | fb17c271ea65ada68744e144e81fb7cb09f8d3f4 /gdb/common | |
parent | 5f572decf9c6fe42f07706514b5056e7fc65cfef (diff) | |
download | gdb-87b0bb13cbbea83ec1896b3ab915c8ce48ab6d44.zip gdb-87b0bb13cbbea83ec1896b3ab915c8ce48ab6d44.tar.gz gdb-87b0bb13cbbea83ec1896b3ab915c8ce48ab6d44.tar.bz2 |
gdb/
* common/linux-procfs.c (linux_proc_get_int): New, from
linux_proc_get_tgid, change its LWPID type to pid_t, add parameter
field.
(linux_proc_get_tgid): Only call linux_proc_get_int.
(linux_proc_get_tracerpid): New.
(linux_proc_pid_has_state): New, from linux_proc_pid_is_zombie.
(linux_proc_pid_is_stopped, linux_proc_pid_is_zombie): Only call
linux_proc_pid_has_state.
* common/linux-procfs.h (linux_proc_get_tracerpid): New declaration.
* common/linux-ptrace.c: Include linux-procfs.h and buffer.h.
(linux_ptrace_attach_warnings): New.
* common/linux-ptrace.h (struct buffer, linux_ptrace_attach_warnings):
New declaration.
* linux-nat.c: Include exceptions.h, linux-ptrace.h and buffer.h.
(linux_nat_attach): New variables ex, buffer, message and message_s.
Wrap to_attach by TRY_CATCH and call linux_ptrace_attach_warnings.
gdb/gdbserver/
* linux-low.c (linux_attach_lwp_1): New variable buffer. Call
linux_ptrace_attach_warnings.
gdb/testsuite/
* gdb.base/attach-twice.c: New files.
* gdb.base/attach-twice.exp: New files.
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/linux-procfs.c | 93 | ||||
-rw-r--r-- | gdb/common/linux-procfs.h | 7 | ||||
-rw-r--r-- | gdb/common/linux-ptrace.c | 23 | ||||
-rw-r--r-- | gdb/common/linux-ptrace.h | 4 |
4 files changed, 81 insertions, 46 deletions
diff --git a/gdb/common/linux-procfs.c b/gdb/common/linux-procfs.c index b7d98a5..a5aa830 100644 --- a/gdb/common/linux-procfs.c +++ b/gdb/common/linux-procfs.c @@ -28,67 +28,54 @@ /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not found. */ -int -linux_proc_get_tgid (int lwpid) +static int +linux_proc_get_int (pid_t lwpid, const char *field) { + size_t field_len = strlen (field); FILE *status_file; char buf[100]; - int tgid = -1; + int retval = -1; snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid); status_file = fopen (buf, "r"); - if (status_file != NULL) + if (status_file == NULL) { - while (fgets (buf, sizeof (buf), status_file)) - { - if (strncmp (buf, "Tgid:", 5) == 0) - { - tgid = strtoul (buf + strlen ("Tgid:"), NULL, 10); - break; - } - } - - fclose (status_file); + warning (_("unable to open /proc file '%s'"), buf); + return -1; } - return tgid; + while (fgets (buf, sizeof (buf), status_file)) + if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':') + { + retval = strtol (&buf[field_len + 1], NULL, 10); + break; + } + + fclose (status_file); + return retval; } -/* Detect `T (stopped)' in `/proc/PID/status'. - Other states including `T (tracing stop)' are reported as false. */ +/* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not + found. */ int -linux_proc_pid_is_stopped (pid_t pid) +linux_proc_get_tgid (pid_t lwpid) { - FILE *status_file; - char buf[100]; - int retval = 0; + return linux_proc_get_int (lwpid, "Tgid"); +} - snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid); - status_file = fopen (buf, "r"); - if (status_file != NULL) - { - int have_state = 0; - - while (fgets (buf, sizeof (buf), status_file)) - { - if (strncmp (buf, "State:", 6) == 0) - { - have_state = 1; - break; - } - } - if (have_state && strstr (buf, "T (stopped)") != NULL) - retval = 1; - fclose (status_file); - } - return retval; +/* See linux-procfs.h. */ + +pid_t +linux_proc_get_tracerpid (pid_t lwpid) +{ + return linux_proc_get_int (lwpid, "TracerPid"); } -/* See linux-procfs.h declaration. */ +/* Return non-zero if 'State' of /proc/PID/status contains STATE. */ -int -linux_proc_pid_is_zombie (pid_t pid) +static int +linux_proc_pid_has_state (pid_t pid, const char *state) { char buffer[100]; FILE *procfile; @@ -110,8 +97,24 @@ linux_proc_pid_is_zombie (pid_t pid) have_state = 1; break; } - retval = (have_state - && strcmp (buffer, "State:\tZ (zombie)\n") == 0); + retval = (have_state && strstr (buffer, state) != NULL); fclose (procfile); return retval; } + +/* Detect `T (stopped)' in `/proc/PID/status'. + Other states including `T (tracing stop)' are reported as false. */ + +int +linux_proc_pid_is_stopped (pid_t pid) +{ + return linux_proc_pid_has_state (pid, "T (stopped)"); +} + +/* See linux-procfs.h declaration. */ + +int +linux_proc_pid_is_zombie (pid_t pid) +{ + return linux_proc_pid_has_state (pid, "Z (zombie)"); +} diff --git a/gdb/common/linux-procfs.h b/gdb/common/linux-procfs.h index 130adeb..167b507 100644 --- a/gdb/common/linux-procfs.h +++ b/gdb/common/linux-procfs.h @@ -24,7 +24,12 @@ /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not found. */ -extern int linux_proc_get_tgid (int lwpid); +extern int linux_proc_get_tgid (pid_t lwpid); + +/* Return the TracerPid of LWPID from /proc/pid/status. Returns -1 if not + found. */ + +extern pid_t linux_proc_get_tracerpid (pid_t lwpid); /* Detect `T (stopped)' in `/proc/PID/status'. Other states including `T (tracing stop)' are reported as false. */ diff --git a/gdb/common/linux-ptrace.c b/gdb/common/linux-ptrace.c index 6dea677..600dcb9 100644 --- a/gdb/common/linux-ptrace.c +++ b/gdb/common/linux-ptrace.c @@ -24,3 +24,26 @@ #endif #include "linux-ptrace.h" +#include "linux-procfs.h" +#include "buffer.h" + +/* Find all possible reasons we could fail to attach PID and append these + newline terminated reason strings to initialized BUFFER. '\0' termination + of BUFFER must be done by the caller. */ + +void +linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer) +{ + pid_t tracerpid; + + tracerpid = linux_proc_get_tracerpid (pid); + if (tracerpid > 0) + buffer_xml_printf (buffer, _("warning: process %d is already traced " + "by process %d\n"), + (int) pid, (int) tracerpid); + + if (linux_proc_pid_is_zombie (pid)) + buffer_xml_printf (buffer, _("warning: process %d is a zombie " + "- the process has already terminated\n"), + (int) pid); +} diff --git a/gdb/common/linux-ptrace.h b/gdb/common/linux-ptrace.h index 96ac3fb..6315b13 100644 --- a/gdb/common/linux-ptrace.h +++ b/gdb/common/linux-ptrace.h @@ -18,6 +18,8 @@ #ifndef COMMON_LINUX_PTRACE_H #define COMMON_LINUX_PTRACE_H +struct buffer; + #include <sys/ptrace.h> #ifndef PTRACE_GETSIGINFO @@ -65,4 +67,6 @@ #define __WALL 0x40000000 /* Wait for any child. */ #endif +extern void linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer); + #endif /* COMMON_LINUX_PTRACE_H */ |