/* Low level interface to ptrace, for the remote server for GDB.
- Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "common-inferior.h"
#include "nat/fork-inferior.h"
#include "environ.h"
+#include "common/scoped_restore.h"
#ifndef ELFMAG0
/* Don't include <linux/elf.h> here. If it got included by gdb_proc_service.h
then ELFMAG0 will have been defined. If it didn't get included by
static void complete_ongoing_step_over (void);
static int linux_low_ptrace_options (int attached);
static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
-static int proceed_one_lwp (thread_info *thread, void *except);
+static void proceed_one_lwp (thread_info *thread, lwp_info *except);
/* When the event-loop is doing a step-over, this points at the thread
being stepped. */
static int
handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
{
+ client_state &cs = get_client_state ();
struct lwp_info *event_lwp = *orig_event_lwp;
int event = linux_ptrace_get_extended_event (wstat);
struct thread_info *event_thr = get_lwp_thread (event_lwp);
new_lwp->status_pending_p = 1;
new_lwp->status_pending = status;
}
- else if (report_thread_events)
+ else if (cs.report_thread_events)
{
new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
new_lwp->status_pending_p = 1;
new_lwp->status_pending = status;
}
+#ifdef USE_THREAD_DB
thread_db_notice_clone (event_thr, ptid);
+#endif
/* Don't report the event. */
return 1;
/* Report the event. */
return 0;
}
- else if (event == PTRACE_EVENT_EXEC && report_exec_events)
+ else if (event == PTRACE_EVENT_EXEC && cs.report_exec_events)
{
struct process_info *proc;
std::vector<int> syscalls_to_catch;
linux_create_inferior (const char *program,
const std::vector<char *> &program_args)
{
+ client_state &cs = get_client_state ();
struct lwp_info *new_lwp;
int pid;
ptid_t ptid;
{
maybe_disable_address_space_randomization restore_personality
- (disable_randomization);
+ (cs.disable_randomization);
std::string str_program_args = stringify_argv (program_args);
pid = fork_inferior (program,
}
else if (err != 0)
{
- warning (_("Cannot attach to lwp %d: %s"),
- lwpid,
- linux_ptrace_attach_fail_reason_string (ptid, err));
+ std::string reason
+ = linux_ptrace_attach_fail_reason_string (ptid, err);
+
+ warning (_("Cannot attach to lwp %d: %s"), lwpid, reason.c_str ());
}
return 1;
soon. */
err = linux_attach_lwp (ptid);
if (err != 0)
- error ("Cannot attach to process %ld: %s",
- pid, linux_ptrace_attach_fail_reason_string (ptid, err));
+ {
+ std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
+
+ error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
+ }
proc = linux_add_process (pid, 1);
static int
get_detach_signal (struct thread_info *thread)
{
+ client_state &cs = get_client_state ();
enum gdb_signal signo = GDB_SIGNAL_0;
int status;
struct lwp_info *lp = get_thread_lwp (thread);
signo = gdb_signal_from_host (WSTOPSIG (status));
- if (program_signals_p && !program_signals[signo])
+ if (cs.program_signals_p && !cs.program_signals[signo])
{
if (debug_threads)
debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
gdb_signal_to_string (signo));
return 0;
}
- else if (!program_signals_p
+ else if (!cs.program_signals_p
/* If we have no way to know which signals GDB does not
want to have passed to the program, assume
SIGTRAP/SIGINT, which is GDB's default. */
/* Remove all LWPs that belong to process PROC from the lwp list. */
-static int
-delete_lwp_callback (thread_info *thread, void *proc)
-{
- struct lwp_info *lwp = get_thread_lwp (thread);
- struct process_info *process = (struct process_info *) proc;
-
- if (pid_of (thread) == pid_of (process))
- delete_lwp (lwp);
-
- return 0;
-}
-
static void
linux_mourn (struct process_info *process)
{
thread_db_mourn (process);
#endif
- find_inferior (&all_threads, delete_lwp_callback, process);
+ for_each_thread (process->pid, [] (thread_info *thread)
+ {
+ delete_lwp (get_thread_lwp (thread));
+ });
/* Freeing all private data. */
priv = process->priv;
return lp->status_pending_p;
}
-static int
-same_lwp (thread_info *thread, void *data)
-{
- ptid_t ptid = *(ptid_t *) data;
- int lwp;
-
- if (ptid_get_lwp (ptid) != 0)
- lwp = ptid_get_lwp (ptid);
- else
- lwp = ptid_get_pid (ptid);
-
- if (thread->id.lwp () == lwp)
- return 1;
-
- return 0;
-}
-
struct lwp_info *
find_lwp_pid (ptid_t ptid)
{
- thread_info *thread = find_inferior (&all_threads, same_lwp, &ptid);
+ thread_info *thread = find_thread ([&] (thread_info *thread)
+ {
+ int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
+ return thread->id.lwp () == lwp;
+ });
if (thread == NULL)
return NULL;
});
}
-/* Callback for `find_inferior'. Returns the first LWP that is not
- stopped. ARG is a PTID filter. */
+/* Callback for `find_thread'. Returns the first LWP that is not
+ stopped. */
-static int
-not_stopped_callback (thread_info *thread, void *arg)
+static bool
+not_stopped_callback (thread_info *thread, ptid_t filter)
{
- struct lwp_info *lwp;
- ptid_t filter = *(ptid_t *) arg;
-
- if (!ptid_match (ptid_of (thread), filter))
- return 0;
+ if (!thread->id.matches (filter))
+ return false;
- lwp = get_thread_lwp (thread);
- if (!lwp->stopped)
- return 1;
+ lwp_info *lwp = get_thread_lwp (thread);
- return 0;
+ return !lwp->stopped;
}
/* Increment LWP's suspend count. */
static int
linux_low_ptrace_options (int attached)
{
+ client_state &cs = get_client_state ();
int options = 0;
if (!attached)
options |= PTRACE_O_EXITKILL;
- if (report_fork_events)
+ if (cs.report_fork_events)
options |= PTRACE_O_TRACEFORK;
- if (report_vfork_events)
+ if (cs.report_vfork_events)
options |= (PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE);
- if (report_exec_events)
+ if (cs.report_exec_events)
options |= PTRACE_O_TRACEEXEC;
options |= PTRACE_O_TRACESYSGOOD;
static struct lwp_info *
linux_low_filter_event (int lwpid, int wstat)
{
+ client_state &cs = get_client_state ();
struct lwp_info *child;
struct thread_info *thread;
int have_stop_pc = 0;
/* If there is at least one more LWP, then the exit signal was
not the end of the debugged application and should be
ignored, unless GDB wants to hear about thread exits. */
- if (report_thread_events
+ if (cs.report_thread_events
|| last_thread_of_process_p (pid_of (thread)))
{
/* Since events are serialized to GDB core, and we can't
/* Now that we've pulled all events out of the kernel, resume
LWPs that don't have an interesting event to report. */
if (stopping_threads == NOT_STOPPING_THREADS)
- for_each_inferior (&all_threads, resume_stopped_resumed_lwps);
+ for_each_thread (resume_stopped_resumed_lwps);
/* ... and find an LWP with a status to report to the core, if
any. */
until all other threads in the thread group are. */
check_zombie_leaders ();
+ auto not_stopped = [&] (thread_info *thread)
+ {
+ return not_stopped_callback (thread, wait_ptid);
+ };
+
/* If there are no resumed children left in the set of LWPs we
want to wait for, bail. We can't just block in
waitpid/sigsuspend, because lwps might have been left stopped
their status to change (which would only happen if we resumed
them). Even if WNOHANG is set, this return code is preferred
over 0 (below), as it is more detailed. */
- if ((find_inferior (&all_threads,
- not_stopped_callback,
- &wait_ptid) == NULL))
+ if (find_thread (not_stopped) == NULL)
{
if (debug_threads)
debug_printf ("LLW: exit (no unwaited-for LWP)\n");
return linux_wait_for_event_filtered (ptid, ptid, wstatp, options);
}
-/* Count the LWP's that have had events. */
-
-static int
-count_events_callback (thread_info *thread, void *data)
-{
- struct lwp_info *lp = get_thread_lwp (thread);
- int *count = (int *) data;
-
- gdb_assert (count != NULL);
-
- /* Count only resumed LWPs that have an event pending. */
- if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
- && lp->status_pending_p)
- (*count)++;
-
- return 0;
-}
-
-/* Select the LWP (if any) that is currently being single-stepped. */
-
-static int
-select_singlestep_lwp_callback (thread_info *thread, void *data)
-{
- struct lwp_info *lp = get_thread_lwp (thread);
-
- if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
- && thread->last_resume_kind == resume_step
- && lp->status_pending_p)
- return 1;
- else
- return 0;
-}
-
-/* Select the Nth LWP that has had an event. */
-
-static int
-select_event_lwp_callback (thread_info *thread, void *data)
-{
- struct lwp_info *lp = get_thread_lwp (thread);
- int *selector = (int *) data;
-
- gdb_assert (selector != NULL);
-
- /* Select only resumed LWPs that have an event pending. */
- if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
- && lp->status_pending_p)
- if ((*selector)-- == 0)
- return 1;
-
- return 0;
-}
-
/* Select one LWP out of those that have events pending. */
static void
select_event_lwp (struct lwp_info **orig_lp)
{
- int num_events = 0;
int random_selector;
struct thread_info *event_thread = NULL;
would report it to the user as a random signal. */
if (!non_stop)
{
- event_thread
- = (struct thread_info *) find_inferior (&all_threads,
- select_singlestep_lwp_callback,
- NULL);
+ event_thread = find_thread ([] (thread_info *thread)
+ {
+ lwp_info *lp = get_thread_lwp (thread);
+
+ return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+ && thread->last_resume_kind == resume_step
+ && lp->status_pending_p);
+ });
+
if (event_thread != NULL)
{
if (debug_threads)
which have had events. */
/* First see how many events we have. */
- find_inferior (&all_threads, count_events_callback, &num_events);
+ int num_events = 0;
+ for_each_thread ([&] (thread_info *thread)
+ {
+ lwp_info *lp = get_thread_lwp (thread);
+
+ /* Count only resumed LWPs that have an event pending. */
+ if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+ && lp->status_pending_p)
+ num_events++;
+ });
gdb_assert (num_events > 0);
/* Now randomly pick a LWP out of those that have had
debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
num_events, random_selector);
- event_thread
- = (struct thread_info *) find_inferior (&all_threads,
- select_event_lwp_callback,
- &random_selector);
+ event_thread = find_thread ([&] (thread_info *thread)
+ {
+ lwp_info *lp = get_thread_lwp (thread);
+
+ /* Select only resumed LWPs that have an event pending. */
+ if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+ && lp->status_pending_p)
+ if (random_selector-- == 0)
+ return true;
+
+ return false;
+ });
}
if (event_thread != NULL)
static void move_out_of_jump_pad_callback (thread_info *thread);
static bool stuck_in_jump_pad_callback (thread_info *thread);
-static int lwp_running (thread_info *thread, void *data);
+static bool lwp_running (thread_info *thread);
static ptid_t linux_wait_1 (ptid_t ptid,
struct target_waitstatus *ourstatus,
int target_options);
stabilizing_threads = 1;
/* Kick 'em all. */
- for_each_inferior (&all_threads, move_out_of_jump_pad_callback);
+ for_each_thread (move_out_of_jump_pad_callback);
/* Loop until all are stopped out of the jump pads. */
- while (find_inferior (&all_threads, lwp_running, NULL) != NULL)
+ while (find_thread (lwp_running) != NULL)
{
struct target_waitstatus ourstatus;
struct lwp_info *lwp;
filter_exit_event (struct lwp_info *event_child,
struct target_waitstatus *ourstatus)
{
+ client_state &cs = get_client_state ();
struct thread_info *thread = get_lwp_thread (event_child);
ptid_t ptid = ptid_of (thread);
if (!last_thread_of_process_p (pid_of (thread)))
{
- if (report_thread_events)
+ if (cs.report_thread_events)
ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
else
ourstatus->kind = TARGET_WAITKIND_IGNORE;
linux_wait_1 (ptid_t ptid,
struct target_waitstatus *ourstatus, int target_options)
{
+ client_state &cs = get_client_state ();
int w;
struct lwp_info *event_child;
int options;
return status_pending_p_callback (thread, minus_one_ptid);
};
+ auto not_stopped = [&] (thread_info *thread)
+ {
+ return not_stopped_callback (thread, minus_one_ptid);
+ };
+
/* Find a resumed LWP, if any. */
if (find_thread (status_pending_p_any) != NULL)
any_resumed = 1;
- else if ((find_inferior (&all_threads,
- not_stopped_callback,
- &minus_one_ptid) != NULL))
+ else if (find_thread (not_stopped) != NULL)
any_resumed = 1;
else
any_resumed = 0;
|| WSTOPSIG (w) == __SIGRTMIN + 1))
||
#endif
- (pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
+ (cs.pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
&& !(WSTOPSIG (w) == SIGSTOP
&& current_thread->last_resume_kind == resume_stop)
&& !linux_wstatus_maybe_breakpoint (w))))
it was a software breakpoint, and the client doesn't know we can
adjust the breakpoint ourselves. */
if (event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
- && !swbreak_feature)
+ && !cs.swbreak_feature)
{
int decr_pc = the_low_target.decr_pc_after_break;
kill_lwp (pid, SIGSTOP);
}
-static int
-send_sigstop_callback (thread_info *thread, void *except)
+static void
+send_sigstop (thread_info *thread, lwp_info *except)
{
struct lwp_info *lwp = get_thread_lwp (thread);
/* Ignore EXCEPT. */
if (lwp == except)
- return 0;
+ return;
if (lwp->stopped)
- return 0;
+ return;
send_sigstop (lwp);
- return 0;
}
/* Increment the suspend count of an LWP, and stop it, if not stopped
yet. */
-static int
-suspend_and_send_sigstop_callback (thread_info *thread, void *except)
+static void
+suspend_and_send_sigstop (thread_info *thread, lwp_info *except)
{
struct lwp_info *lwp = get_thread_lwp (thread);
/* Ignore EXCEPT. */
if (lwp == except)
- return 0;
+ return;
lwp_suspended_inc (lwp);
- return send_sigstop_callback (thread, except);
+ send_sigstop (thread, except);
}
static void
current_thread = saved_thread;
}
-static int
-lwp_running (thread_info *thread, void *data)
+static bool
+lwp_running (thread_info *thread)
{
struct lwp_info *lwp = get_thread_lwp (thread);
if (lwp_is_marked_dead (lwp))
- return 0;
- if (lwp->stopped)
- return 0;
- return 1;
+ return false;
+
+ return !lwp->stopped;
}
/* Stop all lwps that aren't stopped yet, except EXCEPT, if not NULL.
: STOPPING_THREADS);
if (suspend)
- find_inferior (&all_threads, suspend_and_send_sigstop_callback, except);
+ for_each_thread ([&] (thread_info *thread)
+ {
+ suspend_and_send_sigstop (thread, except);
+ });
else
- find_inferior (&all_threads, send_sigstop_callback, except);
+ for_each_thread ([&] (thread_info *thread)
+ {
+ send_sigstop (thread, except);
+ });
+
wait_for_sigstop ();
stopping_threads = NOT_STOPPING_THREADS;
{
struct thread_info *thread = get_lwp_thread (lwp);
struct regcache *regcache = get_thread_regcache (thread, 1);
- struct cleanup *old_chain = make_cleanup_restore_current_thread ();
+
+ scoped_restore save_current_thread = make_scoped_restore (¤t_thread);
current_thread = thread;
std::vector<CORE_ADDR> next_pcs = the_low_target.get_next_pcs (regcache);
for (CORE_ADDR pc : next_pcs)
set_single_step_breakpoint (pc, current_ptid);
-
- do_cleanups (old_chain);
}
/* Single step via hardware or software single step.
lwp->resume = NULL;
}
-/* find_inferior callback for linux_resume.
- Set *FLAG_P if this lwp has an interesting status pending. */
+/* find_thread callback for linux_resume. Return true if this lwp has an
+ interesting status pending. */
static bool
resume_status_pending_p (thread_info *thread)
lwpid_of (thread), paddress (pc));
/* We've found an lwp that needs stepping over --- return 1 so
- that find_inferior stops looking. */
+ that find_thread stops looking. */
current_thread = saved_thread;
return true;
event to report, so we don't need to preserve any step requests;
they should be re-issued if necessary. */
-static int
-linux_resume_one_thread (thread_info *thread, void *arg)
+static void
+linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
{
struct lwp_info *lwp = get_thread_lwp (thread);
- int leave_all_stopped = * (int *) arg;
int leave_pending;
if (lwp->resume == NULL)
- return 0;
+ return;
if (lwp->resume->kind == resume_stop)
{
/* For stop requests, we're done. */
lwp->resume = NULL;
thread->last_status.kind = TARGET_WAITKIND_IGNORE;
- return 0;
+ return;
}
/* If this thread which is about to be resumed has a pending status,
thread->last_status.kind = TARGET_WAITKIND_IGNORE;
lwp->resume = NULL;
- return 0;
}
static void
linux_resume (struct thread_resume *resume_info, size_t n)
{
struct thread_info *need_step_over = NULL;
- int leave_all_stopped;
if (debug_threads)
{
if (!any_pending && supports_breakpoints ())
need_step_over = find_thread (need_step_over_p);
- leave_all_stopped = (need_step_over != NULL || any_pending);
+ bool leave_all_stopped = (need_step_over != NULL || any_pending);
if (debug_threads)
{
/* Even if we're leaving threads stopped, queue all signals we'd
otherwise deliver. */
- find_inferior (&all_threads, linux_resume_one_thread, &leave_all_stopped);
+ for_each_thread ([&] (thread_info *thread)
+ {
+ linux_resume_one_thread (thread, leave_all_stopped);
+ });
if (need_step_over)
start_step_over (get_thread_lwp (need_step_over));
breakpoint that needs stepping over, we start a step-over operation
on that particular thread, and leave all others stopped. */
-static int
-proceed_one_lwp (thread_info *thread, void *except)
+static void
+proceed_one_lwp (thread_info *thread, lwp_info *except)
{
struct lwp_info *lwp = get_thread_lwp (thread);
int step;
if (lwp == except)
- return 0;
+ return;
if (debug_threads)
debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (thread));
{
if (debug_threads)
debug_printf (" LWP %ld already running\n", lwpid_of (thread));
- return 0;
+ return;
}
if (thread->last_resume_kind == resume_stop
if (debug_threads)
debug_printf (" client wants LWP to remain %ld stopped\n",
lwpid_of (thread));
- return 0;
+ return;
}
if (lwp->status_pending_p)
if (debug_threads)
debug_printf (" LWP %ld has pending status, leaving stopped\n",
lwpid_of (thread));
- return 0;
+ return;
}
gdb_assert (lwp->suspended >= 0);
{
if (debug_threads)
debug_printf (" LWP %ld is suspended\n", lwpid_of (thread));
- return 0;
+ return;
}
if (thread->last_resume_kind == resume_stop
step = 0;
linux_resume_one_lwp (lwp, step, 0, NULL);
- return 0;
}
-static int
-unsuspend_and_proceed_one_lwp (thread_info *thread, void *except)
+static void
+unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except)
{
struct lwp_info *lwp = get_thread_lwp (thread);
if (lwp == except)
- return 0;
+ return;
lwp_suspended_decr (lwp);
- return proceed_one_lwp (thread, except);
+ proceed_one_lwp (thread, except);
}
/* When we finish a step-over, set threads running again. If there's
if (debug_threads)
debug_printf ("Proceeding, no step-over needed\n");
- find_inferior (&all_threads, proceed_one_lwp, NULL);
+ for_each_thread ([] (thread_info *thread)
+ {
+ proceed_one_lwp (thread, NULL);
+ });
}
/* Stopped LWPs that the client wanted to be running, that don't have
}
if (unsuspend)
- find_inferior (&all_threads, unsuspend_and_proceed_one_lwp, except);
+ for_each_thread ([&] (thread_info *thread)
+ {
+ unsuspend_and_proceed_one_lwp (thread, except);
+ });
else
- find_inferior (&all_threads, proceed_one_lwp, except);
+ for_each_thread ([&] (thread_info *thread)
+ {
+ proceed_one_lwp (thread, except);
+ });
if (debug_threads)
{
(PTRACE_TYPE_ARG3) (uintptr_t) regaddr, (PTRACE_TYPE_ARG4) 0);
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
- error ("reading register %d: %s", regno, strerror (errno));
+ {
+ /* Mark register REGNO unavailable. */
+ supply_register (regcache, regno, NULL);
+ return;
+ }
}
if (the_low_target.supply_ptrace_register)
unsigned const char *writebuf,
CORE_ADDR offset, int len)
{
- char *document;
- unsigned document_len;
struct process_info_private *const priv = current_process ()->priv;
char filename[PATH_MAX];
int pid, is_elf64;
unsigned int machine;
int ptr_size;
CORE_ADDR lm_addr = 0, lm_prev = 0;
- int allocated = 1024;
- char *p;
CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
int header_done = 0;
}
}
- document = (char *) xmalloc (allocated);
- strcpy (document, "<library-list-svr4 version=\"1.0\"");
- p = document + strlen (document);
+ std::string document = "<library-list-svr4 version=\"1.0\"";
while (lm_addr
&& read_one_ptr (lm_addr + lmo->l_name_offset,
executable does not have PT_DYNAMIC present and this function already
exited above due to failed get_r_debug. */
if (lm_prev == 0)
- {
- sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
- p = p + strlen (p);
- }
+ string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
else
{
/* Not checking for error because reading may stop before
libname[sizeof (libname) - 1] = '\0';
if (libname[0] != '\0')
{
- /* 6x the size for xml_escape_text below. */
- size_t len = 6 * strlen ((char *) libname);
-
if (!header_done)
{
/* Terminate `<library-list-svr4'. */
- *p++ = '>';
+ document += '>';
header_done = 1;
}
- while (allocated < p - document + len + 200)
- {
- /* Expand to guarantee sufficient storage. */
- uintptr_t document_len = p - document;
-
- document = (char *) xrealloc (document, 2 * allocated);
- allocated *= 2;
- p = document + document_len;
- }
-
- std::string name = xml_escape_text ((char *) libname);
- p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
- "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
- name.c_str (), (unsigned long) lm_addr,
- (unsigned long) l_addr, (unsigned long) l_ld);
+ string_appendf (document, "<library name=\"");
+ xml_escape_text_append (&document, (char *) libname);
+ string_appendf (document, "\" lm=\"0x%lx\" "
+ "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
+ (unsigned long) lm_addr, (unsigned long) l_addr,
+ (unsigned long) l_ld);
}
}
if (!header_done)
{
/* Empty list; terminate `<library-list-svr4'. */
- strcpy (p, "/>");
+ document += "/>";
}
else
- strcpy (p, "</library-list-svr4>");
+ document += "</library-list-svr4>";
- document_len = strlen (document);
+ int document_len = document.length ();
if (offset < document_len)
document_len -= offset;
else
if (len > document_len)
len = document_len;
- memcpy (readbuf, document + offset, len);
- xfree (document);
+ memcpy (readbuf, document.data () + offset, len);
return len;
}
linux_qxfer_libraries_svr4,
linux_supports_agent,
#ifdef HAVE_LINUX_BTRACE
- linux_supports_btrace,
linux_enable_btrace,
linux_low_disable_btrace,
linux_low_read_btrace,
NULL,
NULL,
NULL,
- NULL,
#endif
linux_supports_range_stepping,
linux_proc_pid_to_exec_file,