/* Machine independent support for Solaris /proc (process file system) for GDB.
- Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ Copyright (C) 1999-2023 Free Software Foundation, Inc.
Written by Michael Snyder at Cygnus Solutions.
Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
#include "observable.h"
#include "gdbsupport/scoped_fd.h"
#include "gdbsupport/pathstuff.h"
+#include "gdbsupport/buildargv.h"
/* This module provides the interface between GDB and the
/proc file system, which is used on many versions of Unix
std::string pid_to_str (ptid_t) override;
- char *pid_to_exec_file (int pid) override;
+ const char *pid_to_exec_file (int pid) override;
thread_control_capabilities get_thread_control_capabilities () override
{ return tc_schedlock; }
bool info_proc (const char *, enum info_proc_what) override;
#if PR_MODEL_NATIVE == PR_MODEL_LP64
- int auxv_parse (gdb_byte **readptr,
- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+ int auxv_parse (const gdb_byte **readptr,
+ const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
override;
#endif
is presented in 64-bit format. We need to provide a custom parser
to handle that. */
int
-procfs_target::auxv_parse (gdb_byte **readptr,
- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+procfs_target::auxv_parse (const gdb_byte **readptr,
+ const gdb_byte *endptr, CORE_ADDR *typep,
+ CORE_ADDR *valp)
{
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- gdb_byte *ptr = *readptr;
+ const gdb_byte *ptr = *readptr;
if (endptr == ptr)
return 0;
static void
dead_procinfo (procinfo *pi, const char *msg, int kill_p)
{
- char procfile[80];
-
- if (pi->pathname)
- print_sys_errmsg (pi->pathname, errno);
- else
- {
- xsnprintf (procfile, sizeof (procfile), "process %d", pi->pid);
- print_sys_errmsg (procfile, errno);
- }
+ print_sys_errmsg (pi->pathname, errno);
if (kill_p == KILL)
kill (pi->pid, SIGKILL);
(procinfo *pi,
int (*func) (procinfo *, procinfo *, void *),
void *ptr);
+static void proc_resume (procinfo *pi, ptid_t scope_ptid,
+ int step, enum gdb_signal signo);
static void
proc_warn (procinfo *pi, const char *func, int line)
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
void *ptr;
- gdb_assert (sizeof (ptr) == TYPE_LENGTH (ptr_type));
+ gdb_assert (sizeof (ptr) == ptr_type->length ());
gdbarch_address_to_pointer (target_gdbarch (), ptr_type,
(gdb_byte *) &ptr, addr);
return ptr;
if (!open_procinfo_files (pi, FD_CTL))
{
- fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
+ gdb_printf (gdb_stderr, "procfs:%d -- ", __LINE__);
xsnprintf (errmsg, sizeof (errmsg),
"do_attach: couldn't open /proc file for process %d",
ptid.pid ());
inf = current_inferior ();
inferior_appeared (inf, pi->pid);
/* Let GDB know that the inferior was attached. */
- inf->attach_flag = 1;
+ inf->attach_flag = true;
/* Create a procinfo for the current lwp. */
lwpid = proc_get_current_thread (pi);
case PR_SYSENTRY:
if (what == SYS_lwp_exit)
{
- if (print_thread_events)
- printf_unfiltered (_("[%s exited]\n"),
- target_pid_to_str (retval).c_str ());
- delete_thread (find_thread_ptid (this, retval));
- target_continue_no_signal (ptid);
+ delete_thread (this->find_thread (retval));
+ proc_resume (pi, ptid, 0, GDB_SIGNAL_0);
goto wait_again;
}
else if (what == SYS_exit)
}
else
{
- printf_filtered (_("procfs: trapped on entry to "));
+ gdb_printf (_("procfs: trapped on entry to "));
proc_prettyprint_syscall (proc_what (pi), 0);
- printf_filtered ("\n");
+ gdb_printf ("\n");
long i, nsysargs, *sysargs;
if (nsysargs > 0 && sysargs != NULL)
{
- printf_filtered (_("%ld syscall arguments:\n"),
- nsysargs);
+ gdb_printf (_("%ld syscall arguments:\n"),
+ nsysargs);
for (i = 0; i < nsysargs; i++)
- printf_filtered ("#%ld: 0x%08lx\n",
- i, sysargs[i]);
+ gdb_printf ("#%ld: 0x%08lx\n",
+ i, sysargs[i]);
}
- /* How to keep going without returning to wfi: */
- target_continue_no_signal (ptid);
+ proc_resume (pi, ptid, 0, GDB_SIGNAL_0);
goto wait_again;
}
break;
if (!in_thread_list (this, temp_ptid))
add_thread (this, temp_ptid);
- target_continue_no_signal (ptid);
+ proc_resume (pi, ptid, 0, GDB_SIGNAL_0);
goto wait_again;
}
else if (what == SYS_lwp_exit)
{
- if (print_thread_events)
- printf_unfiltered (_("[%s exited]\n"),
- target_pid_to_str (retval).c_str ());
- delete_thread (find_thread_ptid (this, retval));
+ delete_thread (this->find_thread (retval));
status->set_spurious ();
return retval;
}
else
{
- printf_filtered (_("procfs: trapped on exit from "));
+ gdb_printf (_("procfs: trapped on exit from "));
proc_prettyprint_syscall (proc_what (pi), 0);
- printf_filtered ("\n");
+ gdb_printf ("\n");
long i, nsysargs, *sysargs;
if (nsysargs > 0 && sysargs != NULL)
{
- printf_filtered (_("%ld syscall arguments:\n"),
- nsysargs);
+ gdb_printf (_("%ld syscall arguments:\n"),
+ nsysargs);
for (i = 0; i < nsysargs; i++)
- printf_filtered ("#%ld: 0x%08lx\n",
- i, sysargs[i]);
+ gdb_printf ("#%ld: 0x%08lx\n",
+ i, sysargs[i]);
}
- target_continue_no_signal (ptid);
+ proc_resume (pi, ptid, 0, GDB_SIGNAL_0);
goto wait_again;
}
break;
#else
if (retry < 5)
{
- printf_filtered (_("Retry #%d:\n"), retry);
+ gdb_printf (_("Retry #%d:\n"), retry);
pi->status_valid = 0;
goto wait_again;
}
}
break;
default: /* switch (why) unmatched */
- printf_filtered ("procfs:%d -- ", __LINE__);
- printf_filtered (_("child stopped for unknown reason:\n"));
+ gdb_printf ("procfs:%d -- ", __LINE__);
+ gdb_printf (_("child stopped for unknown reason:\n"));
proc_prettyprint_why (why, what, 1);
error (_("... giving up..."));
break;
else /* Flags do not indicate STOPPED. */
{
/* surely this can't happen... */
- printf_filtered ("procfs:%d -- process not stopped.\n",
- __LINE__);
+ gdb_printf ("procfs:%d -- process not stopped.\n",
+ __LINE__);
proc_prettyprint_flags (flags, 1);
error (_("procfs: ...giving up..."));
}
return 0;
}
-/* Make the child process runnable. Normally we will then call
- procfs_wait and wait for it to stop again (unless gdb is async).
+/* Make child process PI runnable.
If STEP is true, then arrange for the child to stop again after
- executing a single instruction. If SIGNO is zero, then cancel any
- pending signal; if non-zero, then arrange for the indicated signal
- to be delivered to the child when it runs. If PID is -1, then
- allow any child thread to run; if non-zero, then allow only the
- indicated thread to run. (not implemented yet). */
+ executing a single instruction. SCOPE_PTID, STEP and SIGNO are
+ like in the target_resume interface. */
-void
-procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
+static void
+proc_resume (procinfo *pi, ptid_t scope_ptid, int step, enum gdb_signal signo)
{
- procinfo *pi, *thread;
+ procinfo *thread;
int native_signo;
/* FIXME: Check/reword. */
So basically PR_STEP is the sole argument that must be passed
to proc_run_process. */
- /* Find procinfo for main process. */
- pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
-
- /* First cut: ignore pid argument. */
errno = 0;
/* Convert signal to host numbering. */
/* Void the process procinfo's caches. */
invalidate_cache (NULL, pi, NULL);
- if (ptid.pid () != -1)
+ if (scope_ptid.pid () != -1)
{
/* Resume a specific thread, presumably suppressing the
others. */
- thread = find_procinfo (ptid.pid (), ptid.lwp ());
+ thread = find_procinfo (scope_ptid.pid (), scope_ptid.lwp ());
if (thread != NULL)
{
if (thread->tid != 0)
}
}
+/* Implementation of target_ops::resume. */
+
+void
+procfs_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
+{
+ /* Find procinfo for main process. */
+ procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
+
+ proc_resume (pi, scope_ptid, step, signo);
+}
+
/* Set up to trace signals in the child process. */
void
{
struct inferior *inf = current_inferior ();
- printf_filtered (_("\tUsing the running image of %s %s via /proc.\n"),
- inf->attach_flag? "attached": "child",
- target_pid_to_str (inferior_ptid).c_str ());
+ gdb_printf (_("\tUsing the running image of %s %s via /proc.\n"),
+ inf->attach_flag? "attached": "child",
+ target_pid_to_str (ptid_t (inf->pid)).c_str ());
}
/* Make it die. Wait for it to die. Clean up after it. Note: this
pi = create_procinfo (getpid (), 0);
if (pi == NULL)
- perror_with_name (_("procfs: create_procinfo failed in child."));
+ perror_with_name (_("procfs: create_procinfo failed in child"));
if (open_procinfo_files (pi, FD_CTL) == 0)
{
len = p1 - p;
else
len = strlen (p);
- strncpy (tryname, p, len);
+ memcpy (tryname, p, len);
tryname[len] = '\0';
strcat (tryname, "/");
strcat (tryname, shell_file);
{
ptid_t gdb_threadid = ptid_t (pi->pid, thread->tid, 0);
- thread_info *thr = find_thread_ptid (&the_procfs_target, gdb_threadid);
+ thread_info *thr = the_procfs_target.find_thread (gdb_threadid);
if (thr == NULL || thr->state == THREAD_EXITED)
add_thread (&the_procfs_target, gdb_threadid);
/* Accepts an integer PID; Returns a string representing a file that
can be opened to get the symbols for the child process. */
-char *
+const char *
procfs_target::pid_to_exec_file (int pid)
{
static char buf[PATH_MAX];
different. */
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
- if (sizeof (void *) != TYPE_LENGTH (ptr_type))
+ if (sizeof (void *) != ptr_type->length ())
return 0;
/* Other tests here??? */
(map->pr_mflags & MA_WRITE) != 0,
(map->pr_mflags & MA_EXEC) != 0,
1, /* MODIFIED is unknown, pass it as true. */
+ false,
data);
}
pr_off = (unsigned int) map->pr_offset;
if (gdbarch_addr_bit (target_gdbarch ()) == 32)
- printf_filtered ("\t%#10lx %#10lx %#10lx %#10x %7s\n",
- (unsigned long) map->pr_vaddr,
- (unsigned long) map->pr_vaddr + map->pr_size - 1,
- (unsigned long) map->pr_size,
- pr_off,
- mappingflags (map->pr_mflags));
+ gdb_printf ("\t%#10lx %#10lx %#10lx %#10x %7s\n",
+ (unsigned long) map->pr_vaddr,
+ (unsigned long) map->pr_vaddr + map->pr_size - 1,
+ (unsigned long) map->pr_size,
+ pr_off,
+ mappingflags (map->pr_mflags));
else
- printf_filtered (" %#18lx %#18lx %#10lx %#10x %7s\n",
- (unsigned long) map->pr_vaddr,
- (unsigned long) map->pr_vaddr + map->pr_size - 1,
- (unsigned long) map->pr_size,
- pr_off,
- mappingflags (map->pr_mflags));
+ gdb_printf (" %#18lx %#18lx %#10lx %#10x %7s\n",
+ (unsigned long) map->pr_vaddr,
+ (unsigned long) map->pr_vaddr + map->pr_size - 1,
+ (unsigned long) map->pr_size,
+ pr_off,
+ mappingflags (map->pr_mflags));
return 0;
}
if (summary)
return; /* No output for summary mode. */
- printf_filtered (_("Mapped address spaces:\n\n"));
+ gdb_printf (_("Mapped address spaces:\n\n"));
if (gdbarch_ptr_bit (target_gdbarch ()) == 32)
- printf_filtered ("\t%10s %10s %10s %10s %7s\n",
- "Start Addr",
- " End Addr",
- " Size",
- " Offset",
- "Flags");
+ gdb_printf ("\t%10s %10s %10s %10s %7s\n",
+ "Start Addr",
+ " End Addr",
+ " Size",
+ " Offset",
+ "Flags");
else
- printf_filtered (" %18s %18s %10s %10s %7s\n",
- "Start Addr",
- " End Addr",
- " Size",
- " Offset",
- "Flags");
+ gdb_printf (" %18s %18s %10s %10s %7s\n",
+ "Start Addr",
+ " End Addr",
+ " Size",
+ " Offset",
+ "Flags");
iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
- printf_filtered ("\n");
+ gdb_printf ("\n");
}
/* Implement the "info proc" command. */
if (process)
{
- printf_filtered (_("process %d flags:\n"), process->pid);
+ gdb_printf (_("process %d flags:\n"), process->pid);
proc_prettyprint_flags (proc_flags (process), 1);
if (proc_flags (process) & (PR_STOPPED | PR_ISTOP))
proc_prettyprint_why (proc_why (process), proc_what (process), 1);
if (proc_get_nthreads (process) > 1)
- printf_filtered ("Process has %d threads.\n",
- proc_get_nthreads (process));
+ gdb_printf ("Process has %d threads.\n",
+ proc_get_nthreads (process));
}
if (thread)
{
- printf_filtered (_("thread %d flags:\n"), thread->tid);
+ gdb_printf (_("thread %d flags:\n"), thread->tid);
proc_prettyprint_flags (proc_flags (thread), 1);
if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP))
proc_prettyprint_why (proc_why (thread), proc_what (thread), 1);