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 <sys/procfs.h> 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.
This commit is contained in:
Rainer Orth
2020-06-21 18:51:58 +02:00
parent cf6f3e86de
commit 196535a69c
2 changed files with 51 additions and 174 deletions

View File

@ -1,3 +1,27 @@
2020-06-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* 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 <ro@CeBiTec.Uni-Bielefeld.DE> 2020-06-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR gdb/25939 PR gdb/25939

View File

@ -197,18 +197,6 @@ procfs_target::auxv_parse (gdb_byte **readptr,
/* =================== END, TARGET_OPS "MODULE" =================== */ /* =================== 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" =================== */ /* =================== STRUCT PROCINFO "MODULE" =================== */
/* FIXME: this comment will soon be out of date W.R.T. threads. */ /* 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. */ inferior's procinfo information. */
/* format strings for /proc paths */ /* format strings for /proc paths */
#define MAIN_PROC_NAME_FMT "/proc/%d"
#define CTL_PROC_NAME_FMT "/proc/%d/ctl" #define CTL_PROC_NAME_FMT "/proc/%d/ctl"
#define AS_PROC_NAME_FMT "/proc/%d/as" #define AS_PROC_NAME_FMT "/proc/%d/as"
#define MAP_PROC_NAME_FMT "/proc/%d/map" #define MAP_PROC_NAME_FMT "/proc/%d/map"
@ -387,14 +374,14 @@ open_procinfo_files (procinfo *pi, int which)
several. Here is some rationale: several. Here is some rationale:
There are several file descriptors that may need to be open 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 - control (ctl) write-only change the state
- status (status) read-only query the state - status (status) read-only query the state
- address space (as) read/write access memory - address space (as) read/write access memory
- map (map) read-only virtual addr map - map (map) read-only virtual addr map
Most of these are opened lazily as they are needed. Most of these are opened lazily as they are needed.
The pathnames for the 'files' for an LWP look slightly The pathnames for the 'files' for an LWP look slightly
different from those of a first-class process: different from those of a first-class process:
Pathnames for a process (<proc-id>): Pathnames for a process (<proc-id>):
/proc/<proc-id>/ctl /proc/<proc-id>/ctl
/proc/<proc-id>/status /proc/<proc-id>/status
@ -403,8 +390,8 @@ open_procinfo_files (procinfo *pi, int which)
Pathnames for an LWP (lwp-id): Pathnames for an LWP (lwp-id):
/proc/<proc-id>/lwp/<lwp-id>/lwpctl /proc/<proc-id>/lwp/<lwp-id>/lwpctl
/proc/<proc-id>/lwp/<lwp-id>/lwpstatus /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
An LWP has no map or address space file descriptor, since An LWP has no map or address space file descriptor, since
the memory map and address space are shared by all LWPs. */ the memory map and address space are shared by all LWPs. */
/* In this case, there are several different file descriptors that /* In this case, there are several different file descriptors that
we might be asked to open. The control file descriptor will be 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. */ /* Chain into list. */
if (tid == 0) 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; pi->next = procinfo_list;
procinfo_list = pi; procinfo_list = pi;
} }
@ -592,7 +579,7 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p)
/* =================== END, STRUCT PROCINFO "MODULE" =================== */ /* =================== END, STRUCT PROCINFO "MODULE" =================== */
/* =================== /proc "MODULE" =================== */ /* =================== /proc "MODULE" =================== */
/* This "module" is the interface layer between the /proc system API /* This "module" is the interface layer between the /proc system API
and the gdb target vector functions. This layer consists of access 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. need to use from the /proc API.
The main motivation for this layer is to hide the fact that there The main motivation for this layer is to hide the fact that there
are two very different implementations of the /proc API. Rather were two very different implementations of the /proc API. */
than have a bunch of #ifdefs all thru the gdb target vector
functions, we do our best to hide them all in here. */
static long proc_flags (procinfo *pi); static long proc_flags (procinfo *pi);
static int proc_why (procinfo *pi); static int proc_why (procinfo *pi);
@ -931,10 +916,6 @@ proc_wait_for_stop (procinfo *pi)
- clear current signal - clear current signal
- abort the current system call - abort the current system call
- stop as soon as finished with 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 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 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" =================== */ /* =================== 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. */ /* Returns the number of threads for the process. */
static int static int
@ -1592,9 +1570,7 @@ proc_get_nthreads (procinfo *pi)
return pi->prstatus.pr_nlwp; 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 (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 other things being equal, this should be the ID of a thread that is
currently executing. */ currently executing. */
@ -1618,8 +1594,7 @@ proc_get_current_thread (procinfo *pi)
} }
/* Discover the IDs of all the threads within the process, and create /* Discover the IDs of all the threads within the process, and create
a procinfo for each of them (chained to the parent). This a procinfo for each of them (chained to the parent). Returns
unfortunately requires a different method on every OS. Returns
non-zero for success, zero for failure. */ non-zero for success, zero for failure. */
static int static int
@ -1770,16 +1745,8 @@ procfs_debug_inferior (procinfo *pi)
return __LINE__; return __LINE__;
/* Method for tracing exec syscalls. */ /* 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); traced_syscall_exits = XNEW (sysset_t);
premptyset (traced_syscall_exits); 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_execve);
praddset (traced_syscall_exits, SYS_lwp_create); praddset (traced_syscall_exits, SYS_lwp_create);
praddset (traced_syscall_exits, SYS_lwp_exit); 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 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
for all registers. 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 NOTE: Since the /proc interface cannot give us individual
registers, we pay no attention to REGNUM, and just fetch them all. registers, we pay no attention to REGNUM, and just fetch them all.
This results in the possibility that we will do unnecessarily many 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 /* Retrieve the next stop event from the child process. If child has
not stopped yet, wait for it to stop. Translate /proc eventcodes not stopped yet, wait for it to stop. Translate /proc eventcodes
(or possibly wait eventcodes) into gdb internal event codes. (or possibly wait eventcodes) into gdb internal event codes.
@ -2204,7 +2131,7 @@ wait_again:
wstat = (what << 8) | 0177; wstat = (what << 8) | 0177;
break; break;
case PR_SYSENTRY: case PR_SYSENTRY:
if (syscall_is_lwp_exit (pi, what)) if (what == SYS_lwp_exit)
{ {
if (print_thread_events) if (print_thread_events)
printf_unfiltered (_("[%s exited]\n"), printf_unfiltered (_("[%s exited]\n"),
@ -2213,7 +2140,7 @@ wait_again:
status->kind = TARGET_WAITKIND_SPURIOUS; status->kind = TARGET_WAITKIND_SPURIOUS;
return retval; return retval;
} }
else if (syscall_is_exit (pi, what)) else if (what == SYS_exit)
{ {
struct inferior *inf; struct inferior *inf;
@ -2293,7 +2220,7 @@ wait_again:
} }
break; break;
case PR_SYSEXIT: case PR_SYSEXIT:
if (syscall_is_exec (pi, what)) if (what == SYS_execve)
{ {
/* Hopefully this is our own "fork-child" execing /* Hopefully this is our own "fork-child" execing
the real child. Hoax this event into a trap, and the real child. Hoax this event into a trap, and
@ -2301,7 +2228,7 @@ wait_again:
address. */ address. */
wstat = (SIGTRAP << 8) | 0177; 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 /* This syscall is somewhat like fork/exec. We
will get the event twice: once for the parent will get the event twice: once for the parent
@ -2325,7 +2252,7 @@ wait_again:
status->kind = TARGET_WAITKIND_SPURIOUS; status->kind = TARGET_WAITKIND_SPURIOUS;
return inferior_ptid; return inferior_ptid;
} }
else if (syscall_is_lwp_exit (pi, what)) else if (what == SYS_lwp_exit)
{ {
if (print_thread_events) if (print_thread_events)
printf_unfiltered (_("[%s exited]\n"), printf_unfiltered (_("[%s exited]\n"),
@ -2334,15 +2261,6 @@ wait_again:
status->kind = TARGET_WAITKIND_SPURIOUS; status->kind = TARGET_WAITKIND_SPURIOUS;
return retval; 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 else
{ {
printf_filtered (_("procfs: trapped on exit from ")); 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 /* About to run the child; invalidate caches and do any other
cleanup. */ 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) if (parent != NULL)
{ {
/* The presence of a parent indicates that this is an LWP. /* 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->gregs_valid = 0;
pi->fpregs_valid = 0; pi->fpregs_valid = 0;
#if 0
pi->gregs_dirty = 0;
pi->fpregs_dirty = 0;
#endif
pi->status_valid = 0; pi->status_valid = 0;
pi->threads_valid = 0; pi->threads_valid = 0;
return 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 /* Make the child process runnable. Normally we will then call
procfs_wait and wait for it to stop again (unless gdb is async). 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; procinfo *pi, *thread;
int native_signo; int native_signo;
/* 2.1: /* FIXME: Check/reword. */
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 /* prrun.prflags |= PRCFAULT; clear current fault.
(proc_trace_signals, proc_trace_faults) PRCFAULT may be replaced by a PCCFAULT call (proc_clear_current_fault)
PRSVADDR is unnecessary.
PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault)
This basically leaves PRSTEP and PRCSIG. 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 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. */ /* Find procinfo for main process. */
pi = find_procinfo_or_die (inferior_ptid.pid (), 0); 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. */ others. Set the child process's PR_ASYNC flag. */
if (!proc_set_async (pi)) if (!proc_set_async (pi))
proc_error (pi, "target_resume, set_async", __LINE__); 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 pi = thread; /* Substitute the thread's procinfo
for run. */ for run. */
} }
@ -2796,8 +2664,6 @@ procfs_target::procfs_init_inferior (int pid)
procfs_notice_signals procfs_notice_signals
prfillset (fault) prfillset (fault)
prdelset (FLTPAGE) prdelset (FLTPAGE)
PIOCWSTOP
PIOCSFAULT
*/ */
/* If not stopped yet, wait for it to stop. */ /* If not stopped yet, wait for it to stop. */
@ -2876,17 +2742,8 @@ procfs_set_exec_trap (void)
_exit (127); _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); exitset = XNEW (sysset_t);
premptyset (exitset); premptyset (exitset);
#ifdef SYS_exec
praddset (exitset, SYS_exec);
#endif
praddset (exitset, SYS_execve); praddset (exitset, SYS_execve);
if (!proc_set_traced_sysexit (pi, exitset)) 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! */ switch (rwflag) { /* FIXME: need an enum! */
case hw_write: /* default watchpoint (write) */ case hw_write: /* default watchpoint (write) */
pflags = WRITE_WATCHFLAG; pflags = WA_WRITE;
break; break;
case hw_read: /* read watchpoint */ case hw_read: /* read watchpoint */
pflags = READ_WATCHFLAG; pflags = WA_READ;
break; break;
case hw_access: /* access watchpoint */ case hw_access: /* access watchpoint */
pflags = READ_WATCHFLAG | WRITE_WATCHFLAG; pflags = WA_READ | WA_WRITE;
break; break;
case hw_execute: /* execution HW breakpoint */ case hw_execute: /* execution HW breakpoint */
pflags = EXEC_WATCHFLAG; pflags = WA_EXEC;
break; break;
default: /* Something weird. Return error. */ default: /* Something weird. Return error. */
return -1; return -1;
} }
if (after) /* Stop after r/w access is completed. */ if (after) /* Stop after r/w access is completed. */
pflags |= AFTER_WATCHFLAG; pflags |= WA_TRAPAFTER;
} }
if (!proc_set_watchpoint (pi, addr, len, pflags)) 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 /* 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, is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint,
or bp_hardware_watchpoint. CNT is the number of watchpoints used so or bp_hardware_watchpoint. CNT is the number of watchpoints used so
far. 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. */
int int
procfs_target::can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) procfs_target::can_use_hw_breakpoint (enum bptype type, int cnt, int othertype)