From 196535a69c8568342e62fdf5e3f5ade04470fd6a Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Sun, 21 Jun 2020 18:51:58 +0200 Subject: [PATCH] Various procfs.c cleanups While reading through procfs.c, I noticed a couple of cleanup opportunities: * Some comments and code allowed for portability across different targets. Since procfs.c is Solaris-only for some time now, those can go. * Likewise, there were some references to the old ioctl-based /proc left. * The code still allowed for SYS_exec. However, it is no longer present in either Solaris 11.3, 11.4, or Illumos. Checking the OpenSolaris sources, I found that it had already been removed in 2010 well before the Solaris 11 release. * Some blocks of #if 0 code can go: ** References to struct procinfo.{g,fp}regs_dirty which are no longer defined. ** Code handling the PR_ASLWP flag where has #define PR_ASLWP 0x00000040 /* obsolete flag; never set */ Tested on amd64-pc-solaris2.11. * procfs.c: Cleanup many comments. (READ_WATCHFLAG, WRITE_WATCHFLAG, EXEC_WATCHFLAG) (AFTER_WATCHFLAG): Replace by value. (MAIN_PROC_NAME_FORMAT): Inline ... (create_procinfo): ... here. (procfs_debug_inferior): Remove SYS_exec handling. (syscall_is_exec): Likewise. (procfs_set_exec_trap): Likewise. (syscall_is_lwp_exit): Inline in callers. (syscall_is_exit): Likewise. (syscall_is_exec): Likewise. (syscall_is_lwp_create): Likewise. (invalidate_cache): Remove #if 0 code. (make_signal_thread_runnable): Remove. (procfs_target::resume): Remove #if 0 code. --- gdb/ChangeLog | 24 ++++++ gdb/procfs.c | 203 +++++++------------------------------------------- 2 files changed, 52 insertions(+), 175 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1f614d5a42c..565a71a78d8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2020-06-21 Rainer Orth + + * procfs.c: Cleanup many comments. + + (READ_WATCHFLAG, WRITE_WATCHFLAG, EXEC_WATCHFLAG) + (AFTER_WATCHFLAG): Replace by value. + + (MAIN_PROC_NAME_FORMAT): Inline ... + (create_procinfo): ... here. + + (procfs_debug_inferior): Remove SYS_exec handling. + (syscall_is_exec): Likewise. + (procfs_set_exec_trap): Likewise. + + (syscall_is_lwp_exit): Inline in callers. + (syscall_is_exit): Likewise. + (syscall_is_exec): Likewise. + (syscall_is_lwp_create): Likewise. + + (invalidate_cache): Remove #if 0 code. + + (make_signal_thread_runnable): Remove. + (procfs_target::resume): Remove #if 0 code. + 2020-06-21 Rainer Orth PR gdb/25939 diff --git a/gdb/procfs.c b/gdb/procfs.c index 7abd6b97d06..6360436ce5b 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -197,18 +197,6 @@ procfs_target::auxv_parse (gdb_byte **readptr, /* =================== END, TARGET_OPS "MODULE" =================== */ -/* World Unification: - - Put any typedefs, defines etc. here that are required for the - unification of code that handles different versions of /proc. */ - -enum { READ_WATCHFLAG = WA_READ, - WRITE_WATCHFLAG = WA_WRITE, - EXEC_WATCHFLAG = WA_EXEC, - AFTER_WATCHFLAG = WA_TRAPAFTER -}; - - /* =================== STRUCT PROCINFO "MODULE" =================== */ /* FIXME: this comment will soon be out of date W.R.T. threads. */ @@ -231,7 +219,6 @@ enum { READ_WATCHFLAG = WA_READ, inferior's procinfo information. */ /* format strings for /proc paths */ -#define MAIN_PROC_NAME_FMT "/proc/%d" #define CTL_PROC_NAME_FMT "/proc/%d/ctl" #define AS_PROC_NAME_FMT "/proc/%d/as" #define MAP_PROC_NAME_FMT "/proc/%d/map" @@ -387,14 +374,14 @@ open_procinfo_files (procinfo *pi, int which) several. Here is some rationale: There are several file descriptors that may need to be open - for any given process or LWP. The ones we're interested in are: + for any given process or LWP. The ones we're interested in are: - control (ctl) write-only change the state - status (status) read-only query the state - address space (as) read/write access memory - map (map) read-only virtual addr map - Most of these are opened lazily as they are needed. - The pathnames for the 'files' for an LWP look slightly - different from those of a first-class process: + Most of these are opened lazily as they are needed. + The pathnames for the 'files' for an LWP look slightly + different from those of a first-class process: Pathnames for a process (): /proc//ctl /proc//status @@ -403,8 +390,8 @@ open_procinfo_files (procinfo *pi, int which) Pathnames for an LWP (lwp-id): /proc//lwp//lwpctl /proc//lwp//lwpstatus - An LWP has no map or address space file descriptor, since - the memory map and address space are shared by all LWPs. */ + An LWP has no map or address space file descriptor, since + the memory map and address space are shared by all LWPs. */ /* In this case, there are several different file descriptors that we might be asked to open. The control file descriptor will be @@ -479,7 +466,7 @@ create_procinfo (int pid, int tid) /* Chain into list. */ if (tid == 0) { - xsnprintf (pi->pathname, sizeof (pi->pathname), MAIN_PROC_NAME_FMT, pid); + xsnprintf (pi->pathname, sizeof (pi->pathname), "/proc/%d", pid); pi->next = procinfo_list; procinfo_list = pi; } @@ -592,7 +579,7 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p) /* =================== END, STRUCT PROCINFO "MODULE" =================== */ -/* =================== /proc "MODULE" =================== */ +/* =================== /proc "MODULE" =================== */ /* This "module" is the interface layer between the /proc system API and the gdb target vector functions. This layer consists of access @@ -600,9 +587,7 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p) need to use from the /proc API. The main motivation for this layer is to hide the fact that there - are two very different implementations of the /proc API. Rather - than have a bunch of #ifdefs all thru the gdb target vector - functions, we do our best to hide them all in here. */ + were two very different implementations of the /proc API. */ static long proc_flags (procinfo *pi); static int proc_why (procinfo *pi); @@ -931,10 +916,6 @@ proc_wait_for_stop (procinfo *pi) - clear current signal - abort the current system call - stop as soon as finished with system call - - (ioctl): set traced signal set - - (ioctl): set held signal set - - (ioctl): set traced fault set - - (ioctl): set start pc (vaddr) Always clears the current fault. PI is the process or LWP to operate on. If STEP is true, set the process or LWP to trap after @@ -1573,9 +1554,6 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags) /* =================== Thread "MODULE" =================== */ -/* NOTE: you'll see more ifdefs and duplication of functions here, - since there is a different way to do threads on every OS. */ - /* Returns the number of threads for the process. */ static int @@ -1592,9 +1570,7 @@ proc_get_nthreads (procinfo *pi) return pi->prstatus.pr_nlwp; } -/* LWP version. - - Return the ID of the thread that had an event of interest. +/* Return the ID of the thread that had an event of interest. (ie. the one that hit a breakpoint or other traced event). All other things being equal, this should be the ID of a thread that is currently executing. */ @@ -1618,8 +1594,7 @@ proc_get_current_thread (procinfo *pi) } /* Discover the IDs of all the threads within the process, and create - a procinfo for each of them (chained to the parent). This - unfortunately requires a different method on every OS. Returns + a procinfo for each of them (chained to the parent). Returns non-zero for success, zero for failure. */ static int @@ -1770,16 +1745,8 @@ procfs_debug_inferior (procinfo *pi) return __LINE__; /* Method for tracing exec syscalls. */ - /* GW: Rationale... - Not all systems with /proc have all the exec* syscalls with the same - names. On the SGI, for example, there is no SYS_exec, but there - *is* a SYS_execv. So, we try to account for that. */ - traced_syscall_exits = XNEW (sysset_t); premptyset (traced_syscall_exits); -#ifdef SYS_exec - praddset (traced_syscall_exits, SYS_exec); -#endif praddset (traced_syscall_exits, SYS_execve); praddset (traced_syscall_exits, SYS_lwp_create); praddset (traced_syscall_exits, SYS_lwp_exit); @@ -1961,10 +1928,6 @@ do_detach () /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers. - ??? Is the following note still relevant? We can't get individual - registers with the PT_GETREGS ptrace(2) request either, yet we - don't bother with caching at all in that case. - NOTE: Since the /proc interface cannot give us individual registers, we pay no attention to REGNUM, and just fetch them all. This results in the possibility that we will do unnecessarily many @@ -2064,42 +2027,6 @@ procfs_target::store_registers (struct regcache *regcache, int regnum) } } -static int -syscall_is_lwp_exit (procinfo *pi, int scall) -{ - if (scall == SYS_lwp_exit) - return 1; - return 0; -} - -static int -syscall_is_exit (procinfo *pi, int scall) -{ - if (scall == SYS_exit) - return 1; - return 0; -} - -static int -syscall_is_exec (procinfo *pi, int scall) -{ -#ifdef SYS_exec - if (scall == SYS_exec) - return 1; -#endif - if (scall == SYS_execve) - return 1; - return 0; -} - -static int -syscall_is_lwp_create (procinfo *pi, int scall) -{ - if (scall == SYS_lwp_create) - return 1; - return 0; -} - /* Retrieve the next stop event from the child process. If child has not stopped yet, wait for it to stop. Translate /proc eventcodes (or possibly wait eventcodes) into gdb internal event codes. @@ -2204,7 +2131,7 @@ wait_again: wstat = (what << 8) | 0177; break; case PR_SYSENTRY: - if (syscall_is_lwp_exit (pi, what)) + if (what == SYS_lwp_exit) { if (print_thread_events) printf_unfiltered (_("[%s exited]\n"), @@ -2213,7 +2140,7 @@ wait_again: status->kind = TARGET_WAITKIND_SPURIOUS; return retval; } - else if (syscall_is_exit (pi, what)) + else if (what == SYS_exit) { struct inferior *inf; @@ -2293,7 +2220,7 @@ wait_again: } break; case PR_SYSEXIT: - if (syscall_is_exec (pi, what)) + if (what == SYS_execve) { /* Hopefully this is our own "fork-child" execing the real child. Hoax this event into a trap, and @@ -2301,7 +2228,7 @@ wait_again: address. */ wstat = (SIGTRAP << 8) | 0177; } - else if (syscall_is_lwp_create (pi, what)) + else if (what == SYS_lwp_create) { /* This syscall is somewhat like fork/exec. We will get the event twice: once for the parent @@ -2325,7 +2252,7 @@ wait_again: status->kind = TARGET_WAITKIND_SPURIOUS; return inferior_ptid; } - else if (syscall_is_lwp_exit (pi, what)) + else if (what == SYS_lwp_exit) { if (print_thread_events) printf_unfiltered (_("[%s exited]\n"), @@ -2334,15 +2261,6 @@ wait_again: status->kind = TARGET_WAITKIND_SPURIOUS; return retval; } - else if (0) - { - /* FIXME: Do we need to handle SYS_sproc, - SYS_fork, or SYS_vfork here? The old procfs - seemed to use this event to handle threads on - older (non-LWP) systems, where I'm assuming - that threads were actually separate processes. - Irix, maybe? Anyway, low priority for now. */ - } else { printf_filtered (_("procfs: trapped on exit from ")); @@ -2528,20 +2446,6 @@ invalidate_cache (procinfo *parent, procinfo *pi, void *ptr) /* About to run the child; invalidate caches and do any other cleanup. */ -#if 0 - if (pi->gregs_dirty) - if (parent == NULL || proc_get_current_thread (parent) != pi->tid) - if (!proc_set_gregs (pi)) /* flush gregs cache */ - proc_warn (pi, "target_resume, set_gregs", - __LINE__); - if (gdbarch_fp0_regnum (target_gdbarch ()) >= 0) - if (pi->fpregs_dirty) - if (parent == NULL || proc_get_current_thread (parent) != pi->tid) - if (!proc_set_fpregs (pi)) /* flush fpregs cache */ - proc_warn (pi, "target_resume, set_fpregs", - __LINE__); -#endif - if (parent != NULL) { /* The presence of a parent indicates that this is an LWP. @@ -2552,36 +2456,12 @@ invalidate_cache (procinfo *parent, procinfo *pi, void *ptr) } pi->gregs_valid = 0; pi->fpregs_valid = 0; -#if 0 - pi->gregs_dirty = 0; - pi->fpregs_dirty = 0; -#endif pi->status_valid = 0; pi->threads_valid = 0; return 0; } -#if 0 -/* A callback function for iterate_over_threads. Find the - asynchronous signal thread, and make it runnable. See if that - helps matters any. */ - -static int -make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr) -{ -#ifdef PR_ASLWP - if (proc_flags (pi) & PR_ASLWP) - { - if (!proc_run_process (pi, 0, -1)) - proc_error (pi, "make_signal_thread_runnable", __LINE__); - return 1; - } -#endif - return 0; -} -#endif - /* Make the child process runnable. Normally we will then call procfs_wait and wait for it to stop again (unless gdb is async). @@ -2598,21 +2478,14 @@ procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo) procinfo *pi, *thread; int native_signo; - /* 2.1: - prrun.prflags |= PRSVADDR; - prrun.pr_vaddr = $PC; set resume address - prrun.prflags |= PRSTRACE; trace signals in pr_trace (all) - prrun.prflags |= PRSFAULT; trace faults in pr_fault (all but PAGE) - prrun.prflags |= PRCFAULT; clear current fault. - - PRSTRACE and PRSFAULT can be done by other means - (proc_trace_signals, proc_trace_faults) - PRSVADDR is unnecessary. - PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault) + /* FIXME: Check/reword. */ + + /* prrun.prflags |= PRCFAULT; clear current fault. + PRCFAULT may be replaced by a PCCFAULT call (proc_clear_current_fault) This basically leaves PRSTEP and PRCSIG. - PRCSIG is like PIOCSSIG (proc_clear_current_signal). + PRCSIG is like PCSSIG (proc_clear_current_signal). So basically PR_STEP is the sole argument that must be passed - to proc_run_process (for use in the prrun struct by ioctl). */ + to proc_run_process. */ /* Find procinfo for main process. */ pi = find_procinfo_or_die (inferior_ptid.pid (), 0); @@ -2647,11 +2520,6 @@ procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo) others. Set the child process's PR_ASYNC flag. */ if (!proc_set_async (pi)) proc_error (pi, "target_resume, set_async", __LINE__); -#if 0 - proc_iterate_over_threads (pi, - make_signal_thread_runnable, - NULL); -#endif pi = thread; /* Substitute the thread's procinfo for run. */ } @@ -2796,8 +2664,6 @@ procfs_target::procfs_init_inferior (int pid) procfs_notice_signals prfillset (fault) prdelset (FLTPAGE) - PIOCWSTOP - PIOCSFAULT */ /* If not stopped yet, wait for it to stop. */ @@ -2876,17 +2742,8 @@ procfs_set_exec_trap (void) _exit (127); } - /* Method for tracing exec syscalls. */ - /* GW: Rationale... - Not all systems with /proc have all the exec* syscalls with the same - names. On the SGI, for example, there is no SYS_exec, but there - *is* a SYS_execv. So, we try to account for that. */ - exitset = XNEW (sysset_t); premptyset (exitset); -#ifdef SYS_exec - praddset (exitset, SYS_exec); -#endif praddset (exitset, SYS_execve); if (!proc_set_traced_sysexit (pi, exitset)) @@ -3140,22 +2997,22 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, { switch (rwflag) { /* FIXME: need an enum! */ case hw_write: /* default watchpoint (write) */ - pflags = WRITE_WATCHFLAG; + pflags = WA_WRITE; break; case hw_read: /* read watchpoint */ - pflags = READ_WATCHFLAG; + pflags = WA_READ; break; case hw_access: /* access watchpoint */ - pflags = READ_WATCHFLAG | WRITE_WATCHFLAG; + pflags = WA_READ | WA_WRITE; break; case hw_execute: /* execution HW breakpoint */ - pflags = EXEC_WATCHFLAG; + pflags = WA_EXEC; break; default: /* Something weird. Return error. */ return -1; } if (after) /* Stop after r/w access is completed. */ - pflags |= AFTER_WATCHFLAG; + pflags |= WA_TRAPAFTER; } if (!proc_set_watchpoint (pi, addr, len, pflags)) @@ -3174,11 +3031,7 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, /* Return non-zero if we can set a hardware watchpoint of type TYPE. TYPE is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_watchpoint. CNT is the number of watchpoints used so - far. - - Note: procfs_can_use_hw_breakpoint() is not yet used by all - procfs.c targets due to the fact that some of them still define - target_can_use_hardware_watchpoint. */ + far. */ int procfs_target::can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) -- 2.30.2