On Linux, we need to explicitly ptrace attach to all lwps of a
process. Because GDB might not be connected yet when an attach is
requested, and thus it may not be possible to activate thread_db, as
that requires access to symbols (IOW, gdbserver --attach), a while ago
we make linux_attach loop over the lwps as listed by /proc/PID/task to
find the lwps to attach to.
linux_attach_lwp_1 has:
...
if (initial)
/* If lwp is the tgid, we handle adding existing threads later.
Otherwise we just add lwp without bothering about any other
threads. */
ptid = ptid_build (lwpid, lwpid, 0);
else
{
/* Note that extracting the pid from the current inferior is
safe, since we're always called in the context of the same
process as this new thread. */
int pid = pid_of (current_inferior);
ptid = ptid_build (pid, lwpid, 0);
}
That "safe" comment referred to linux_attach_lwp being called by
thread-db.c. But this was clearly missed when a new call to
linux_attach_lwp_1 was added to linux_attach. As a result,
current_inferior will be set to some random process, and non-initial
lwps of the second inferior get assigned the pid of the wrong
inferior. E.g., in the case of attaching to two inferiors, for the
second inferior (and so on), non-initial lwps of the second inferior
get assigned the pid of the first inferior. This doesn't trigger on
the first inferior, when current_inferior is NULL, add_thread switches
the current inferior to the newly added thread.
Rather than making linux_attach switch current_inferior temporarily
(thus avoiding further reliance on global state), or making
linux_attach_lwp_1 get the tgid from /proc, which add extra syscalls,
and will be wrong in case of the user having originally attached
directly to a non-tgid lwp, and then that lwp spawning new clones (the
ptid.pid field of further new clones should be the same as the
original lwp's pid, which is not the tgid), we note that callers of
linux_attach_lwp/linux_attach_lwp_1 always have the right pid handy
already, so they can pass it down along with the lwpid.
The only other reason for the "initial" parameter is to error out
instead of warn in case of attach failure, when we're first attaching
to a process. There are only three callers of
linux_attach_lwp/linux_attach_lwp_1, and each wants to print a
different warn/error string, so we can just move the error/warn out of
linux_attach_lwp_1 to the callers, thus getting rid of the "initial"
parameter.
There really nothing gdbserver-specific about attaching to two
threaded processes, so this adds a new test under gdb.multi/. The
test passes cleanly against the native GNU/Linux target, but
fails/triggers the bug against GDBserver (before the patch), with the
native-extended-remote board (as plain remote doesn't support
multi-process).
Tested on x86_64 Fedora 17, with the native-extended-gdbserver board.
gdb/gdbserver/
2014-04-25 Pedro Alves <palves@redhat.com>
PR server/16255
* linux-low.c (linux_attach_fail_reason_string): New function.
(linux_attach_lwp): Delete.
(linux_attach_lwp_1): Rename to ...
(linux_attach_lwp): ... this. Take a ptid instead of a pid as
argument. Remove "initial" parameter. Return int instead of
void. Don't error or warn here.
(linux_attach): Adjust to call linux_attach_lwp. Call error on
failure to attach to the tgid. Call warning when failing to
attach to an lwp.
* linux-low.h (linux_attach_lwp): Take a ptid instead of a pid as
argument. Remove "initial" parameter. Return int instead of
void. Don't error or warn here.
(linux_attach_fail_reason_string): New declaration.
* thread-db.c (attach_thread): Adjust to linux_attach_lwp's
interface change. Use linux_attach_fail_reason_string.
gdb/
2014-04-25 Pedro Alves <palves@redhat.com>
PR server/16255
* common/linux-ptrace.c (linux_ptrace_attach_warnings): Rename to ...
(linux_ptrace_attach_fail_reason): ... this. Remove "warning: "
and newline from built string.
* common/linux-ptrace.h (linux_ptrace_attach_warnings): Rename to ...
(linux_ptrace_attach_fail_reason): ... this.
* linux-nat.c (linux_nat_attach): Adjust to use
linux_ptrace_attach_fail_reason.
gdb/testsuite/
2014-04-25 Simon Marchi <simon.marchi@ericsson.com>
Pedro Alves <palves@redhat.com>
PR server/16255
* gdb.multi/multi-attach.c: New file.
* gdb.multi/multi-attach.exp: New file.
sh-linux-gnu-gcc (...) src/gdb/gdbserver/linux-low.c
.../src/gdb/gdbserver/linux-low.c: In function 'linux_read_loadmap':
.../src/gdb/gdbserver/linux-low.c:5284:13: error: 'struct lwp_info' has no member named 'entry'
make[1]: *** [linux-low.o] Error 1
gdb/gdbserver/
2014-04-09 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_read_loadmap): Pass current_inferior directly
to lwpid_of.
GDBserver currently hangs forever in waitpid if the leader thread
exits before other threads, or if all resumed threads exit - e.g.,
next over a thread exit with sched-locking on. This is exposed by
leader-exit.exp. leader-exit.exp is part of a series of tests for a
set of related problems. See
<http://www.sourceware.org/ml/gdb-patches/2011-10/msg00704.html>:
"
To recap, on the Linux kernel, ptrace/waitpid don't allow reaping the
leader thread until all other threads in the group are reaped. When
the leader exits, it goes zombie, but waitpid will not return an exit
status until the other threads are gone. This is presently exercised
by the gdb.threads/leader-exit.exp test. The fix for that test, in
linux-nat.c:wait_lwp, handles the case where we see the leader gone
when we're stopping all threads to report an event to some other
thread to the core.
(...)
The latter bit about not blocking if there no resumed threads in the
process also applies to some other thread exiting, not just the main
thread. E.g., this test starts a thread, and runs to a breakpoint in
that thread:
...
(gdb) c
Continuing.
[New Thread 0x7ffff75a4700 (LWP 23397)]
[Switching to Thread 0x7ffff75a4700 (LWP 23397)]
Breakpoint 2, thread_a (arg=0x0) at ../../../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:28
28 return 0; /* break-here */
(gdb) info threads
* 2 Thread 0x7ffff75a4700 (LWP 23397) thread_a (arg=0x0) at ../../../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:28
1 Thread 0x7ffff7fcb720 (LWP 23391) 0x00007ffff7bc606d in pthread_join (threadid=140737343276800, thread_return=0x0) at pthread_join.c:89
The thread will exit as soon as we resume it. But if we only resume
that thread, leaving the rest of the threads stopped:
(gdb) set scheduler-locking on
(gdb) c
Continuing.
^C^C^C^C^C^C^C^C
"
This patch fixes the issues by implementing TARGET_WAITKIND_NO_RESUMED
on GDBserver, similarly to what the patch above did for native
Linux GDB.
gdb.threads/leader-exit.exp now passes.
gdb.threads/no-unwaited-for-left.exp now at least errors out instead
of hanging:
continue
Continuing.
warning: Remote failure reply: E.No unwaited-for children left.
[Thread 15454] #1 stopped.
0x00000034cf408e60 in pthread_join (threadid=140737353922368, thread_return=0x0) at pthread_join.c:93
93 lll_wait_tid (pd->tid);
(gdb) FAIL: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits
The gdb.threads/non-ldr-exc-*.exp tests are skipped because GDBserver
unfortunately doesn't support fork/exec yet, but I'm confident this
fixes the related issues.
I'm leaving modeling TARGET_WAITKIND_NO_RESUMED in the RSP for a
separate pass.
(BTW, in case of error in response to a vCont, it would be better for
GDB to query the target for the current thread, or re-select one,
instead of assuming current inferior_ptid is still the selected
thread.)
This implementation is a little different from GDB's, because I'm
avoiding bringing in more of this broken use of waitpid(PID) into
GDBserver. Specifically, this avoids waitpid(PID) when stopping all
threads. There's really no need for wait_for_sigstop to wait for each
LWP in turn. Instead, with some refactoring, we make it reuse
linux_wait_for_event.
gdb/gdbserver/
2014-02-27 Pedro Alves <palves@redhat.com>
PR 12702
* inferiors.h (A_I_NEXT, ALL_INFERIORS_TYPE, ALL_PROCESSES): New
macros.
* linux-low.c (delete_lwp, handle_extended_wait): Add debug
output.
(last_thread_of_process_p): Take a PID argument instead of a
thread pointer.
(linux_wait_for_lwp): Delete.
(num_lwps, check_zombie_leaders, not_stopped_callback): New
functions.
(linux_low_filter_event): New function, party factored out from
linux_wait_for_event.
(linux_wait_for_event): Rename to ...
(linux_wait_for_event_filtered): ... this. Add new filter ptid
argument. Partly rewrite. Always use waitpid(-1, WNOHANG) and
sigsuspend. Check for zombie leaders.
(linux_wait_for_event): Reimplement as wrapper around
linux_wait_for_event_filtered.
(linux_wait_1): Handle TARGET_WAITKIND_NO_RESUMED. Assume that if
a normal or signal exit is seen, it's the whole process exiting.
(wait_for_sigstop): No longer a for_each_inferior callback.
Rewrite on top of linux_wait_for_event_filtered.
(stop_all_lwps): Call wait_for_sigstop directly.
* server.c (resume, handle_target_event): Handle
TARGET_WAITKIND_NO_RESUMED.
* gdbthread.h (add_thread): Change result type to struct thread_info *.
* inferiors.c (add_thread): Change result type to struct thread_info *.
All callers updated.
(add_lwp): Call add_thread here instead of in callers.
All callers updated.
* linux-low.h (get_lwp_thread): Rewrite.
(struct lwp_info): New member "thread".
This speeds up gdbserver attach in non-stop mode because now get_lwp_thread
doesn't do a linear search for the corresponding thread_info object.
* dll.c (clear_dlls): Replace accessing list implemention details
with API function.
* gdbthread.h (get_first_thread): Declare.
* inferiors.c (for_each_inferior_with_data): New function.
(get_first_thread): New function.
(find_thread_ptid): Simplify.
(get_first_inferior): New function.
(clear_list): Delete.
(one_inferior_p): New function.
(clear_inferior_list): New function.
(clear_inferiors): Update.
* inferiors.h (for_each_inferior_with_data): Declare.
(clear_inferior_list): Declare.
(one_inferior_p): Declare.
(get_first_inferior): Declare.
* linux-low.c (linux_wait_for_event): Replace accessing list
implemention details with API function.
* server.c (target_running): Ditto.
(accumulate_file_name_length): New function.
(emit_dll_description): New function.
(handle_qxfer_libraries): Replace accessing list implemention
details with API function.
(handle_qxfer_threads_worker): New function.
(handle_qxfer_threads_proper): Replace accessing list implemention
details with API function.
(handle_query): Ditto.
(visit_actioned_threads_callback_ftype): New typedef.
(visit_actioned_threads_data): New struct.
(visit_actioned_threads): Rewrite to be find_inferior callback.
(resume): Call find_inferior.
(handle_status): Replace accessing list implemention
details with API function.
(process_serial_event): Replace accessing list implemention details
with API function.
* target.c (set_desired_inferior): Replace accessing list implemention
details with API function.
* tracepoint.c (same_process_p): New function.
(gdb_agent_about_to_close): Replace accessing list implemention
details with API function.
* win32-low.c (child_delete_thread): Replace accessing list
implemention details with API function.
(match_dll_by_basename): New function.
(dll_is_loaded_by_basename): New function.
(win32_ensure_ntdll_loaded): Replace accessing list implemention
details call to dll_is_loaded_by_basename.
Read branch trace data incrementally and extend the current trace rather than
discarding it and reading the entire trace buffer each time.
If the branch trace buffer overflowed, we can't extend the current trace so we
discard it and start anew by reading the entire branch trace buffer.
2014-01-16 Markus Metzger <markus.t.metzger@intel.com>
* common/linux-btrace.c (perf_event_read_bts, linux_read_btrace):
Support delta reads.
(linux_disable_btrace): Change return type.
* common/linux-btrace.h (linux_read_btrace): Change parameters
and return type to allow error reporting. Update users.
(linux_disable_btrace): Change return type. Update users.
* common/btrace-common.h (btrace_read_type) <BTRACE_READ_DELTA>:
New.
(btrace_error): New.
(btrace_block) <begin>: Comment on BEGIN == 0.
* btrace.c (btrace_compute_ftrace): Start from the end of
the current trace.
(btrace_stitch_trace, btrace_clear_history): New.
(btrace_fetch): Read delta trace, return if replaying.
(btrace_clear): Move clear history code to btrace_clear_history.
(parse_xml_btrace): Throw an error if parsing failed.
* target.h (struct target_ops) <to_read_btrace>: Change parameters
and return type to allow error reporting.
(target_read_btrace): Change parameters and return type to allow
error reporting.
* target.c (target_read_btrace): Update.
* remote.c (remote_read_btrace): Support delta reads. Pass
errors on.
* NEWS: Announce it.
gdbserver/
* target.h (target_ops) <read_btrace>: Change parameters and
return type to allow error reporting.
* server.c (handle_qxfer_btrace): Support delta reads. Pass
trace reading errors on.
* linux-low.c (linux_low_read_btrace): Pass trace reading
errors on.
(linux_low_disable_btrace): New.
This patch is purely mechanical. It removes gdb_stat.h and changes
the code to use sys/stat.h.
2013-11-18 Tom Tromey <tromey@redhat.com>
* common/gdb_stat.h: Remove.
* ada-lang.c: Use sys/stat.h, not gdb_stat.h.
* common/filestuff.c: Use sys/stat.h, not gdb_stat.h.
* common/linux-osdata.c: Use sys/stat.h, not gdb_stat.h.
* corefile.c: Use sys/stat.h, not gdb_stat.h.
* ctf.c: Use sys/stat.h, not gdb_stat.h.
* darwin-nat.c: Use sys/stat.h, not gdb_stat.h.
* dbxread.c: Use sys/stat.h, not gdb_stat.h.
* dwarf2read.c: Use sys/stat.h, not gdb_stat.h.
* exec.c: Use sys/stat.h, not gdb_stat.h.
* gdbserver/linux-low.c: Use sys/stat.h, not gdb_stat.h.
* gdbserver/remote-utils.c: Use sys/stat.h, not gdb_stat.h.
* inf-child.c: Use sys/stat.h, not gdb_stat.h.
* jit.c: Use sys/stat.h, not gdb_stat.h.
* linux-nat.c: Use sys/stat.h, not gdb_stat.h.
* m68klinux-nat.c: Use sys/stat.h, not gdb_stat.h.
* main.c: Use sys/stat.h, not gdb_stat.h.
* mdebugread.c: Use sys/stat.h, not gdb_stat.h.
* mi/mi-cmd-env.c: Use sys/stat.h, not gdb_stat.h.
* nto-tdep.c: Use sys/stat.h, not gdb_stat.h.
* objfiles.c: Use sys/stat.h, not gdb_stat.h.
* procfs.c: Use sys/stat.h, not gdb_stat.h.
* remote-fileio.c: Use sys/stat.h, not gdb_stat.h.
* remote-mips.c: Use sys/stat.h, not gdb_stat.h.
* remote.c: Use sys/stat.h, not gdb_stat.h.
* rs6000-nat.c: Use sys/stat.h, not gdb_stat.h.
* sol-thread.c: Use sys/stat.h, not gdb_stat.h.
* solib-spu.c: Use sys/stat.h, not gdb_stat.h.
* source.c: Use sys/stat.h, not gdb_stat.h.
* symfile.c: Use sys/stat.h, not gdb_stat.h.
* symmisc.c: Use sys/stat.h, not gdb_stat.h.
* symtab.c: Use sys/stat.h, not gdb_stat.h.
* top.c: Use sys/stat.h, not gdb_stat.h.
* xcoffread.c: Use sys/stat.h, not gdb_stat.h.
to PTRACE_TYPE_ARG3.
* linux-low.c: Rename all occurrences of PTRACE_ARG3_TYPE
to PTRACE_TYPE_ARG3 and PTRACE_ARG4_TYPE to
PTRACE_TYPE_ARG4.
* linux-low.h (PTRACE_ARG3_TYPE): Rename to PTRACE_TYPE_ARG3.
(PTRACE_ARG4_TYPE): Rename to PTRACE_TYPE_ARG4.
With the pathmax gnulib module in place, we can use PATH_MAX
consistently throughout, instead of the current mixbag of PATH_MAX and
MAXPATHLEN uses. It's no longer necessary to include sys/param.h
(supposedly, I can't check all ports touched here) for MAXPATHLEN.
Don't remove sys/param.h from GDB's configure.ac, as later tests in
the file use HAVE_SYS_PARAM_H checks.
Tested on x86_64 Fedora 17.
Also cross-built for --host=i686-w64-mingw32, and --host=i586-pc-msdosdjgpp.
gdb/
2013-07-01 Pedro Alves <palves@redhat.com>
* defs.h: Include "pathmax.h".
* utils.c: Don't include sys/param.h.
(gdb_realpath): Remove code that checks for MAXPATHLEN.
* solib-ia64-hpux.c (ia64_hpux_handle_load_event): Use PATH_MAX
instead of MAXPATHLEN.
* solib-sunos.c: Don't include sys/param.h.
* xcoffread.c: Don't include sys/param.h.
* bsd-kvm.c: Don't include sys/param.h.
* darwin-nat.c: Don't include sys/param.h.
(darwin_pid_to_exec_file): Use PATH_MAX instead of MAXPATHLEN.
* darwin-nat-info.c: Don't include sys/param.h.
* fbsd-nat.c (fbsd_pid_to_exec_file): Use PATH_MAX instead of
MAXPATHLEN.
* i386obsd-nat.c: Don't include sys/param.h.
* inf-child.c: Don't include sys/param.h.
(inf_child_fileio_readlink): Use PATH_MAX instead of MAXPATHLEN.
* linux-fork.c: Don't include sys/param.h.
(fork_save_infrun_state): Use PATH_MAX instead of MAXPATHLEN.
* linux-nat.c: Don't include sys/param.h.
(linux_child_pid_to_exec_file, linux_proc_pending_signals)
(linux_proc_pending_signals): Use PATH_MAX instead of MAXPATHLEN.
* m68klinux-nat.c: Don't include sys/param.h.
* nbsd-nat.c: Don't include sys/param.h.
(nbsd_pid_to_exec_file): Use PATH_MAX instead of MAXPATHLEN.
* ppc-linux-nat.c: Don't include sys/param.h.
* rs6000-nat.c: Don't include sys/param.h.
* spu-linux-nat.c. Don't include sys/param.h.
* windows-nat.c: Don't include sys/param.h.
* xtensa-linux-nat.c: Don't include sys/param.h.
* config/i386/nm-fbsd.h: Don't include sys/param.h.
gdb/gdbserver/
2013-07-01 Pedro Alves <palves@redhat.com>
* server.h: Include "pathmax.h".
* linux-low.c: Don't include sys/param.h.
(linux_pid_exe_is_elf_64_file): Use PATH_MAX instead of
MAXPATHLEN.
* win32-low.c: Don't include sys/param.h.
(win32_create_inferior): Use PATH_MAX instead of MAXPATHLEN.
There's no need for every arch to pre-allocate disabled_regsets.
Chances are the array won't be used.
(I have a hunch that with some more work we could dispense with
initialize_regsets_info.)
Tested on x86_64 Fedora 17 w/ -lmcheck.
gdb/gdbserver/
2013-06-11 Pedro Alves <palves@redhat.com>
* linux-low.c (regset_disabled, disable_regset): New functions.
(regsets_fetch_inferior_registers)
(regsets_store_inferior_registers): Use them.
(initialize_regsets_info); Don't allocate the disabled_regsets
array here.
* linux-low.h (struct regsets_info) <disabled_regsets>: Extend
comment.
This fixes the regression reported at
<http://sourceware.org/ml/gdb-patches/2013-06/msg00185.html>.
GDBserver was reaching:
static int
regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
struct regcache *regcache)
{
struct regset_info *regset;
int saw_general_regs = 0;
int pid;
struct iovec iov;
regset = regsets_info->regsets;
pid = lwpid_of (get_thread_lwp (current_inferior));
while (regset->size >= 0)
{
void *buf, *data;
int nt_type, res;
if (regset->size == 0
|| regsets_info->disabled_regsets[regset - regsets_info->regsets])
{
>>>>>>> regset ++; <<<<<<< HERE
continue;
}
Because info->disabled_regsets[] was not being initialized, and that
causes all sorts of wrong.
gdb/gdbserver/
2013-06-11 Pedro Alves <palves@redhat.com>
* linux-low.c (initialize_regsets_info): Use xcalloc instead of
xmalloc.
This patch makes GDBserver support multi-process + biarch.
Currently, if you're debugging more than one process at once with a
single gdbserver (in extended-remote mode), then all processes must
have the same architecture (e.g., 64-bit vs 32-bit). Otherwise, you
see this:
Added inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
Reading symbols from /home/pedro/gdb/tests/main32...done.
Temporary breakpoint 2 at 0x4004cf: main. (2 locations)
Starting program: /home/pedro/gdb/tests/main32
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
warning: Architecture rejected target-supplied description
Remote 'g' packet reply is too long: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090cfffff0000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000b042f7460000000000020000230000002b0000002b0000002b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f03000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f00003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
... etc, etc ...
Even though the process was running a 32-bit program, GDBserver sent
back to GDB a register set in 64-bit layout.
A patch (http://sourceware.org/ml/gdb-patches/2012-11/msg00228.html) a
while ago made GDB track a target_gdbarch per inferior, and as
consequence, fetch a target description per-inferior. This patch is
the GDBserver counterpart, that makes GDBserver keep track of each
process'es XML target description and register layout. So in the
example above, GDBserver will send the correct register set in 32-bit
layout to GDB.
A new "struct target_desc" object (tdesc for short) is added, that
holds the target description and register layout information about
each process. Each `struct process_info' holds a pointer to a target
description. The regcache also gains a pointer to a target
description, mainly for convenience, and parallel with GDB (and
possible future support for programs that flip processor modes).
The low target's arch_setup routines are responsible for setting the
process'es correct tdesc. This isn't that much different to how
things were done before, except that instead of detecting the inferior
process'es architecture and calling the corresponding
init_registers_FOO routine, which would change the regcache layout
globals and recreate the threads' regcaches, the regcache.c globals
are gone, and the init_registers_$BAR routines now each initialize a
separate global struct target_desc object (one for each arch variant
GDBserver supports), and so all the init_registers_$BAR routines that
are built into GDBserver are called early at GDBserver startup time
(similarly to how GDB handles its built-in target descriptions), and
then the arch_setup routine is responsible for making
process_info->tdesc point to one of these target description globals.
The regcache module is all parameterized to get the regcache's layout
from the tdesc object instead of the old register_bytes, etc. globals.
The threads' regcaches are now created lazily. The old scheme where
we created each of them when we added a new thread doesn't work
anymore, because we add the main thread/lwp before we see it stop for
the first time, and it is only when we see the thread stop for the
first time that we have a chance of determining the inferior's
architecture (through the_low_target.arch_setup). Therefore when we
add the main thread we don't know which architecture/tdesc its
regcache should have.
This patch makes the gdb.multi/multi-arch.exp test now pass against
(extended-remote) GDBserver. It currently fails, without this patch.
The IPA also uses the regcache, so it gains a new global struct
target_desc pointer, which points at the description of the process it
is loaded in.
Re. the linux-low.c & friends changes. Since the register map
etc. may differ between processes (64-bit vs 32-bit) etc., the
linux_target_ops num_regs, regmap and regset_bitmap data fields are no
longer sufficient. A new method is added in their place that returns
a pointer to a new struct that includes all info linux-low.c needs to
access registers of the current inferior.
The patch/discussion that originally introduced
linux-low.c:disabled_regsets mentions that the disabled_regsets set
may be different per mode (in a biarch setup), and indeed that is
cleared whenever we start a new (first) inferior, so that global is
moved as well behind the new `struct regs_info'.
On the x86 side:
I simply replaced the i387-fp.c:num_xmm_registers global with a check
for 64-bit or 32-bit process, which is equivalent to how the global
was set. This avoided coming up with some more general mechanism that
would work for all targets that use this module (GNU/Linux, Windows,
etc.).
Tested:
GNU/Linux IA64
GNU/Linux MIPS64
GNU/Linux PowerPC (Fedora 16)
GNU/Linux s390x (Fedora 16)
GNU/Linux sparc64 (Debian)
GNU/Linux x86_64, -m64 and -m32 (Fedora 17)
Cross built, and smoke tested:
i686-w64-mingw32, under Wine.
GNU/Linux TI C6x, by Yao Qi.
Cross built but otherwise not tested:
aarch64-linux-gnu
arm-linux-gnu
m68k-linux
nios2-linux-gnu
sh-linux-gnu
spu
tilegx-unknown-linux-gnu
Completely untested:
GNU/Linux Blackfin
GNU/Linux CRIS
GNU/Linux CRISv32
GNU/Linux TI Xtensa
GNU/Linux M32R
LynxOS
QNX NTO
gdb/gdbserver/
2013-06-07 Pedro Alves <palves@redhat.com>
* Makefile.in (OBS): Add tdesc.o.
(IPA_OBJS): Add tdesc-ipa.o.
(tdesc-ipa.o): New rule.
* ax.c (gdb_eval_agent_expr): Adjust register_size call to new
interface.
* linux-low.c (new_inferior): Delete.
(disabled_regsets, num_regsets): Delete.
(linux_add_process): Adjust to set the new per-process
new_inferior flag.
(linux_detach_one_lwp): Adjust to call regcache_invalidate_thread.
(linux_wait_for_lwp): Adjust. Only call arch_setup if the event
was a stop. When calling arch_setup, switch the current inferior
to the thread that got an event.
(linux_resume_one_lwp): Adjust to call regcache_invalidate_thread.
(regsets_fetch_inferior_registers)
(regsets_store_inferior_registers): New regsets_info parameter.
Adjust to use it.
(linux_register_in_regsets): New regs_info parameter. Adjust to
use it.
(register_addr, fetch_register, store_register): New usrregs_info
parameter. Adjust to use it.
(usr_fetch_inferior_registers, usr_store_inferior_registers): New
parameter regs_info. Adjust to use it.
(linux_fetch_registers): Get the current inferior's regs_info, and
adjust to use it.
(linux_store_registers): Ditto.
[HAVE_LINUX_REGSETS] (initialize_regsets_info): New.
(initialize_low): Don't initialize the target_regsets here. Call
initialize_low_arch.
* linux-low.h (target_regsets): Delete declaration.
(struct regsets_info): New.
(struct usrregs_info): New.
(struct regs_info): New.
(struct process_info_private) <new_inferior>: New field.
(struct linux_target_ops): Delete the num_regs, regmap, and
regset_bitmap fields. New field regs_info.
[HAVE_LINUX_REGSETS] (initialize_regsets_info): Declare.
* i387-fp.c (num_xmm_registers): Delete.
(i387_cache_to_fsave, i387_fsave_to_cache): Adjust find_regno
calls to new interface.
(i387_cache_to_fxsave, i387_cache_to_xsave, i387_fxsave_to_cache)
(i387_xsave_to_cache): Adjust find_regno calls to new interface.
Infer the number of xmm registers from the regcache's target
description.
* i387-fp.h (num_xmm_registers): Delete.
* inferiors.c (add_thread): Don't install the thread's regcache
here.
* proc-service.c (gregset_info): Fetch the current inferior's
regs_info. Adjust to use it.
* regcache.c: Include tdesc.h.
(register_bytes, reg_defs, num_registers)
(gdbserver_expedite_regs): Delete.
(get_thread_regcache): If the thread doesn't have a regcache yet,
create one, instead of aborting gdbserver.
(regcache_invalidate_one): Rename to ...
(regcache_invalidate_thread): ... this.
(regcache_invalidate_one): New.
(regcache_invalidate): Only invalidate registers of the current
process.
(init_register_cache): Add target_desc parameter, and use it.
(new_register_cache): Ditto. Assert the target description has a
non zero registers_size.
(regcache_cpy): Add assertions. Adjust.
(realloc_register_cache, set_register_cache): Delete.
(registers_to_string, registers_from_string): Adjust.
(find_register_by_name, find_regno, find_register_by_number)
(register_cache_size): Add target_desc parameter, and use it.
(free_register_cache_thread, free_register_cache_thread_one)
(regcache_release, register_cache_size): New.
(register_size): Add target_desc parameter, and use it.
(register_data, supply_register, supply_register_zeroed)
(supply_regblock, supply_register_by_name, collect_register)
(collect_register_as_string, collect_register_by_name): Adjust.
* regcache.h (struct target_desc): Forward declare.
(struct regcache) <tdesc>: New field.
(init_register_cache, new_register_cache): Add target_desc
parameter.
(regcache_invalidate_thread): Declare.
(regcache_invalidate_one): Delete declaration.
(regcache_release): Declare.
(find_register_by_number, register_cache_size, register_size)
(find_regno): Add target_desc parameter.
(gdbserver_expedite_regs, gdbserver_xmltarget): Delete
declarations.
* remote-utils.c: Include tdesc.h.
(outreg, prepare_resume_reply): Adjust.
* server.c: Include tdesc.h.
(gdbserver_xmltarget): Delete declaration.
(get_features_xml, process_serial_event): Adjust.
* server.h [IN_PROCESS_AGENT] (struct target_desc): Forward
declare.
(struct process_info) <tdesc>: New field.
(ipa_tdesc): Declare.
* tdesc.c: New file.
* tdesc.h: New file.
* tracepoint.c: Include tdesc.h.
[IN_PROCESS_AGENT] (ipa_tdesc): Define.
(get_context_regcache): Adjust to pass ipa_tdesc down.
(do_action_at_tracepoint): Adjust to get the register cache size
from the context regcache's description.
(traceframe_walk_blocks): Adjust to get the register cache size
from the current trace frame's description.
(traceframe_get_pc): Adjust to get current trace frame's
description and pass it down.
(gdb_collect): Adjust to get the register cache size from the
IPA's description.
* linux-amd64-ipa.c (tdesc_amd64_linux): Declare.
(gdbserver_xmltarget): Delete.
(initialize_low_tracepoint): Set the ipa's target description.
* linux-i386-ipa.c (tdesc_i386_linux): Declare.
(initialize_low_tracepoint): Set the ipa's target description.
* linux-x86-low.c: Include tdesc.h.
[__x86_64__] (is_64bit_tdesc): New.
(ps_get_thread_area, x86_get_thread_area): Use it.
(i386_cannot_store_register): Rename to ...
(x86_cannot_store_register): ... this. Use is_64bit_tdesc.
(i386_cannot_fetch_register): Rename to ...
(x86_cannot_fetch_register): ... this. Use is_64bit_tdesc.
(x86_fill_gregset, x86_store_gregset): Adjust register_size calls
to new interface.
(target_regsets): Rename to ...
(x86_regsets): ... this.
(x86_get_pc, x86_set_pc): Adjust register_size calls to new
interface.
(x86_siginfo_fixup): Use is_64bit_tdesc.
[__x86_64__] (tdesc_amd64_linux, tdesc_amd64_avx_linux)
(tdesc_x32_avx_linux, tdesc_x32_linux)
(tdesc_i386_linux, tdesc_i386_mmx_linux, tdesc_i386_avx_linux):
Declare.
(x86_linux_update_xmltarget): Delete.
(I386_LINUX_XSAVE_XCR0_OFFSET): Define.
(have_ptrace_getfpxregs, have_ptrace_getregset): New.
(AMD64_LINUX_USER64_CS): New.
(x86_linux_read_description): New, based on
x86_linux_update_xmltarget.
(same_process_callback): New.
(x86_arch_setup_process_callback): New.
(x86_linux_update_xmltarget): New.
(x86_regsets_info): New.
(amd64_linux_regs_info): New.
(i386_linux_usrregs_info): New.
(i386_linux_regs_info): New.
(x86_linux_regs_info): New.
(x86_arch_setup): Reimplement.
(x86_install_fast_tracepoint_jump_pad): Use is_64bit_tdesc.
(x86_emit_ops): Ditto.
(the_low_target): Adjust. Install x86_linux_regs_info,
x86_cannot_fetch_register, and x86_cannot_store_register.
(initialize_low_arch): New.
* linux-ia64-low.c (tdesc_ia64): Declare.
(ia64_fetch_register): Adjust.
(ia64_usrregs_info, regs_info): New globals.
(ia64_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-sparc-low.c (tdesc_sparc64): Declare.
(sparc_fill_gregset_to_stack, sparc_store_gregset_from_stack):
Adjust.
(sparc_arch_setup): New function.
(sparc_regsets_info, sparc_usrregs_info, regs_info): New globals.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-ppc-low.c (tdesc_powerpc_32l, tdesc_powerpc_altivec32l)
(tdesc_powerpc_cell32l, tdesc_powerpc_vsx32l)
(tdesc_powerpc_isa205_32l, tdesc_powerpc_isa205_altivec32l)
(tdesc_powerpc_isa205_vsx32l, tdesc_powerpc_e500l)
(tdesc_powerpc_64l, tdesc_powerpc_altivec64l)
(tdesc_powerpc_cell64l, tdesc_powerpc_vsx64l)
(tdesc_powerpc_isa205_64l, tdesc_powerpc_isa205_altivec64l)
(tdesc_powerpc_isa205_vsx64l): Declare.
(ppc_cannot_store_register, ppc_collect_ptrace_register)
(ppc_supply_ptrace_register, parse_spufs_run, ppc_get_pc)
(ppc_set_pc, ppc_get_hwcap): Adjust.
(ppc_usrregs_info): Forward declare.
(!__powerpc64__) ppc_regmap_adjusted: New global.
(ppc_arch_setup): Adjust to the current process'es target
description.
(ppc_fill_vsxregset, ppc_store_vsxregset, ppc_fill_vrregset)
(ppc_store_vrregset, ppc_fill_evrregset, ppc_store_evrregse)
(ppc_store_evrregset): Adjust.
(target_regsets): Rename to ...
(ppc_regsets): ... this, and make static.
(ppc_usrregs_info, ppc_regsets_info, regs_info): New globals.
(ppc_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-s390-low.c (tdesc_s390_linux32, tdesc_s390_linux32v1)
(tdesc_s390_linux32v2, tdesc_s390_linux64, tdesc_s390_linux64v1)
(tdesc_s390_linux64v2, tdesc_s390x_linux64, tdesc_s390x_linux64v1)
(tdesc_s390x_linux64v2): Declare.
(s390_collect_ptrace_register, s390_supply_ptrace_register)
(s390_fill_gregset, s390_store_last_break): Adjust.
(target_regsets): Rename to ...
(s390_regsets): ... this, and make static.
(s390_get_pc, s390_set_pc): Adjust.
(s390_get_hwcap): New target_desc parameter, and use it.
[__s390x__] (have_hwcap_s390_high_gprs): New global.
(s390_arch_setup): Adjust to set the current process'es target
description. Don't adjust the regmap.
(s390_usrregs_info, s390_regsets_info, regs_info): New globals.
[__s390x__] (s390_usrregs_info_3264, s390_regsets_info_3264)
(regs_info_3264): New globals.
(s390_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-mips-low.c (tdesc_mips_linux, tdesc_mips_dsp_linux)
(tdesc_mips64_linux, tdesc_mips64_dsp_linux): Declare.
[__mips64] (init_registers_mips_linux)
(init_registers_mips_dsp_linux): Delete defines.
[__mips64] (tdesc_mips_linux, tdesc_mips_dsp_linux): New defines.
(have_dsp): New global.
(mips_read_description): New, based on mips_arch_setup.
(mips_arch_setup): Reimplement.
(get_usrregs_info): New function.
(mips_cannot_fetch_register, mips_cannot_store_register)
(mips_get_pc, mips_set_pc, mips_fill_gregset, mips_store_gregset)
(mips_fill_fpregset, mips_store_fpregset): Adjust.
(target_regsets): Rename to ...
(mips_regsets): ... this, and make static.
(mips_regsets_info, mips_dsp_usrregs_info, mips_usrregs_info)
(dsp_regs_info, regs_info): New globals.
(mips_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-arm-low.c (tdesc_arm, tdesc_arm_with_iwmmxt)
(tdesc_arm_with_vfpv2, tdesc_arm_with_vfpv3, tdesc_arm_with_neon):
Declare.
(arm_fill_vfpregset, arm_store_vfpregset): Adjust.
(arm_read_description): New, with bits factored from
arm_arch_setup.
(arm_arch_setup): Reimplement.
(target_regsets): Rename to ...
(arm_regsets): ... this, and make static.
(arm_regsets_info, arm_usrregs_info, regs_info): New globals.
(arm_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-m68k-low.c (tdesc_m68k): Declare.
(target_regsets): Rename to ...
(m68k_regsets): ... this, and make static.
(m68k_regsets_info, m68k_usrregs_info, regs_info): New globals.
(m68k_regs_info): New function.
(m68k_arch_setup): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-sh-low.c (tdesc_sharch): Declare.
(target_regsets): Rename to ...
(sh_regsets): ... this, and make static.
(sh_regsets_info, sh_usrregs_info, regs_info): New globals.
(sh_regs_info, sh_arch_setup): New functions.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-bfin-low.c (tdesc_bfin): Declare.
(bfin_arch_setup): New function.
(bfin_usrregs_info, regs_info): New globals.
(bfin_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-cris-low.c (tdesc_cris): Declare.
(cris_arch_setup): New function.
(cris_usrregs_info, regs_info): New globals.
(cris_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-cris-low.c (tdesc_crisv32): Declare.
(cris_arch_setup): New function.
(cris_regsets_info, cris_usrregs_info, regs_info): New globals.
(cris_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-m32r-low.c (tdesc_m32r): Declare.
(m32r_arch_setup): New function.
(m32r_usrregs_info, regs_info): New globals.
(m32r_regs_info): Adjust.
(initialize_low_arch): New function.
* linux-tic6x-low.c (tdesc_tic6x_c64xp_linux)
(tdesc_tic6x_c64x_linux, tdesc_tic6x_c62x_linux): Declare.
(tic6x_usrregs_info): Forward declare.
(tic6x_read_description): New function, based on ...
(tic6x_arch_setup): ... this. Reimplement.
(target_regsets): Rename to ...
(tic6x_regsets): ... this, and make static.
(tic6x_regsets_info, tic6x_usrregs_info, regs_info): New globals.
(tic6x_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-xtensa-low.c (tdesc_xtensa): Declare.
(xtensa_fill_gregset, xtensa_store_gregset): Adjust.
(target_regsets): Rename to ...
(xtensa_regsets): ... this, and make static.
(xtensa_regsets_info, xtensa_usrregs_info, regs_info): New
globals.
(xtensa_arch_setup, xtensa_regs_info): New functions.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-nios2-low.c (tdesc_nios2_linux): Declare.
(nios2_arch_setup): Set the current process'es tdesc.
(target_regsets): Rename to ...
(nios2_regsets): ... this.
(nios2_regsets_info, nios2_usrregs_info, regs_info): New globals.
(nios2_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-aarch64-low.c (tdesc_aarch64): Declare.
(aarch64_arch_setup): Set the current process'es tdesc.
(target_regsets): Rename to ...
(aarch64_regsets): ... this.
(aarch64_regsets_info, aarch64_usrregs_info, regs_info): New globals.
(aarch64_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-tile-low.c (tdesc_tilegx, tdesc_tilegx32): Declare
globals.
(target_regsets): Rename to ...
(tile_regsets): ... this.
(tile_regsets_info, tile_usrregs_info, regs_info): New globals.
(tile_regs_info): New function.
(tile_arch_setup): Set the current process'es tdesc.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* spu-low.c (tdesc_spu): Declare.
(spu_create_inferior, spu_attach): Set the new process'es tdesc.
* win32-arm-low.c (tdesc_arm): Declare.
(arm_arch_setup): New function.
(the_low_target): Install arm_arch_setup instead of
init_registers_arm.
* win32-i386-low.c (tdesc_i386, tdesc_amd64): Declare.
(init_windows_x86): Rename to ...
(i386_arch_setup): ... this. Set `win32_tdesc'.
(the_low_target): Adjust.
* win32-low.c (win32_tdesc): New global.
(child_add_thread): Don't create the thread cache here.
(do_initial_child_stuff): Set the new process'es tdesc.
* win32-low.h (struct target_desc): Forward declare.
(win32_tdesc): Declare.
* lynx-i386-low.c (tdesc_i386): Declare global.
(lynx_i386_arch_setup): Set `lynx_tdesc'.
* lynx-low.c (lynx_tdesc): New global.
(lynx_add_process): Set the new process'es tdesc.
* lynx-low.h (struct target_desc): Forward declare.
(lynx_tdesc): Declare global.
* lynx-ppc-low.c (tdesc_powerpc_32): Declare global.
(lynx_ppc_arch_setup): Set `lynx_tdesc'.
* nto-low.c (nto_tdesc): New global.
(do_attach): Set the new process'es tdesc.
* nto-low.h (struct target_desc): Forward declare.
(nto_tdesc): Declare.
* nto-x86-low.c (tdesc_i386): Declare.
(nto_x86_arch_setup): Set `nto_tdesc'.
gdb/
2013-06-07 Pedro Alves <palves@redhat.com>
* regformats/regdat.sh: Output #include tdesc.h. Make globals
static. Output a global target description pointer.
(init_registers_${name}): Adjust to initialize a
target description structure.
This patch adds support for range stepping to GDBserver, teaching it
about vCont;r.
It'd be easy to enable this for all hardware single-step targets
without needing the linux_target_ops hook, however, at least PPC needs
special care, due to the fact that PPC atomic sequences can't be
hardware single-stepped through, a thing which GDBserver doesn't know
about. So this leaves the support limited to x86/x86_64.
gdb/
2013-05-23 Pedro Alves <palves@redhat.com>
* NEWS: Mention GDBserver range stepping support.
gdb/gdbserver/
2013-05-23 Yao Qi <yao@codesourcery.com>
Pedro Alves <palves@redhat.com>
* linux-low.c (lwp_in_step_range): New function.
(linux_wait_1): If the thread was range stepping and stopped
outside the stepping range, report the stop to GDB. Otherwise,
continue stepping. Add range stepping debug output.
(linux_set_resume_request): Copy the step range from the resume
request to the lwp.
(linux_supports_range_stepping): New.
(linux_target_ops) <supports_range_stepping>: Set to
linux_supports_range_stepping.
* linux-low.h (struct linux_target_ops)
<supports_range_stepping>: New field.
(struct lwp_info) <step_range_start, step_range_end>: New fields.
* linux-x86-low.c (x86_supports_range_stepping): New.
(the_low_target) <supports_range_stepping>: Set to
x86_supports_range_stepping.
* server.c (handle_v_cont): Handle 'r' action.
(handle_v_requests): Append ";r" if the target supports range
stepping.
* target.h (struct thread_resume) <step_range_start,
step_range_end>: New fields.
(struct target_ops) <supports_range_stepping>:
New field.
(target_supports_range_stepping): New macro.
PT_DATA_ADDR and PT_TEXT_END_ADDR. Update comments.
(linux_read_offsets): Remove PT_TEXT_ADDR, PT_DATA_ADDR and
PT_TEXT_END_ADDR guards. Update comments.
(linux_target_op) <read_offsets>: Conditionally define to
linux_read_offsets if the target is UCLIBC and if it defines
PT_TEXT_ADDR, PT_DATA_ADDR and PT_TEXT_END_ADDR.
Oleg Nesterov told me that the Linux kernel copies the parent's ptrace
options to fork/clone children, so there's no need for GDB to do that
manually.
I was actually a bit surprised, since I thought the ptracer had to
always set the ptrace options itself, and GDB is indeed calling
PTRACE_SETOPTIONS for each new fork child, if it'll stay attached.
Looking at the history of that code, I found that is was actually I
who added that set-ptrace-options-in-children bit, back in
http://sourceware.org/ml/gdb-patches/2009-05/msg00656.html. But,
honestly, I don't recall why I needed that. I think I may have just
blindly believed it was necessary.
I then looked back at the history of all the PTRACE_SETOPTIONS code we
have, and found that gdb never did copy the ptrace options before my
patch. But, when gdbserver learnt to use PTRACE_EVENT_CLONE, at
http://sourceware.org/ml/gdb-patches/2007-10/msg00547.html, it was
made to do 'ptrace (PTRACE_SETOPTIONS, new_pid, 0,
PTRACE_O_TRACECLONE)' for all new clones. Hmmm. But, GDB itself
never did that, so it can't really ever have been necessary, I
believe, otherwise GDB should have been doing it too.
(GDBserver doesn't support following forks, and so naturally doesn't
do any PTRACE_SETOPTIONS on fork children.)
So this patch removes the -I believe- unnecessary ptrace syscalls.
Tested on x86_64 Fedora 17, native/gdbserver, and on x86_64 RHEL5
native/gdbserver (Linux 2.6.18, I think a ptrace-on-utrace kernel).
No regressions.
gdb/
2013-03-22 Pedro Alves <palves@redhat.com>
* linux-nat.c (linux_child_follow_fork): Don't call
linux_enable_event_reporting.
(linux_handle_extended_wait): Don't call
linux_enable_event_reporting.
gdb/gdbserver/
2013-03-22 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Don't call
linux_enable_event_reporting.
This fixes the followin error when HAVE_LINUX_BTRACE is not defined:
linux-low.c:5943: error: excess elements in struct initializer
linux-low.c:5943: error: (near initialization for 'linux_target_ops')
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_target_ops) [!HAVE_LINUX_BTRACE]:
Remove extraneous NULL element.
We define the following packets:
Qbtrace:bts enable branch tracing for the current thread
returns "OK" or "Enn"
Qbtrace:off disable branch tracing for the current thread
returns "OK" or "Enn"
qXfer:btrace:read read the full branch trace data for the current thread
gdb/
* target.h (enum target_object): Add TARGET_OBJECT_BTRACE.
* remote.c: Include btrace.h.
(struct btrace_target_info): New struct.
(remote_supports_btrace): New function.
(send_Qbtrace): New function.
(remote_enable_btrace): New function.
(remote_disable_btrace): New function.
(remote_teardown_btrace): New function.
(remote_read_btrace): New function.
(init_remote_ops): Add btrace ops.
(enum <unnamed>): Add btrace packets.
(struct protocol_feature remote_protocol_features[]): Add btrace packets.
(_initialize_remote): Add packet configuration for branch tracing.
gdbserver/
* target.h (struct target_ops): Add btrace ops.
(target_supports_btrace): New macro.
(target_enable_btrace): New macro.
(target_disable_btrace): New macro.
(target_read_btrace): New macro.
* gdbthread.h (struct thread_info): Add btrace field.
* server.c: Include btrace-common.h.
(handle_btrace_general_set): New function.
(handle_btrace_enable): New function.
(handle_btrace_disable): New function.
(handle_general_set): Call handle_btrace_general_set.
(handle_qxfer_btrace): New function.
(struct qxfer qxfer_packets[]): Add btrace entry.
* inferiors.c (remove_thread): Disable btrace.
* linux-low: Include linux-btrace.h.
(linux_low_enable_btrace): New function.
(linux_low_read_btrace): New function.
(linux_target_ops): Add btrace ops.
* configure.srv (i[34567]86-*-linux*): Add linux-btrace.o.
Add srv_linux_btrace=yes.
(x86_64-*-linux*): Add linux-btrace.o.
Add srv_linux_btrace=yes.
* configure.ac: Define HAVE_LINUX_BTRACE.
* config.in: Regenerated.
* configure: Regenerated.
PROBLEM:
The function linux_write_memory () in linux-low.c allocates a buffer
on the stack to hold a copy of the data to be written.
register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *)
alloca (count * sizeof (PTRACE_XFER_TYPE));
"count" is the number of bytes to be written, rounded up to the
nearest multiple of sizeof (PTRACE_XFER_TYPE) and allowing for not
being an aligned address. The function later uses
buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
(PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);
The problem is that this function can be called to write zero bytes on
an aligned address, for example when receiving an X packet of length 0
(used to test if 8-bit write is supported). Under these circumstances,
count can be zero.
Since in this case, buffer[0] may never have been allocated, the stack
is corrupted and gdbserver may crash.
SOLUTION:
Writing zero bytes should always succeed. The patch below returns
successfully early if the length is zero, so avoiding the stack
corruption.
Verified on the ARC GDB 7.5.1 port.
2013-03-07 Jeremy Bennett <jeremy.bennett@embecosm.com>
PR server/15236
* linux-low.c (linux_write_memory): Return early success if LEN is
zero.
Two modifications:
1. The addition of 2013 to the copyright year range for every file;
2. The use of a single year range, instead of potentially multiple
year ranges, as approved by the FSF.
ARI fixes: move gdb_wait and gdb_stat headers to common subdirectory.
* gdb_stat.h: Delete. Moved to common directory.
* common/gdb_stat.h: New file.
* gdb_wait.h: Delete. Moved to common directory.
* common/gdb_wait.h: New file.
* Makefile.in (H_FILES_NO_SRC): Adapt to new header
location.
* contrib/ari/gdb_ari.sh (wait.h rule): Adapt to new gdb_wait.h
location.
(stat.h rule): Adapt to new gdb_stat.h location.
* common/linux-osdata.c: Include "gdb_stat.h" header instead of
<sys/stat.h> header.
* common/linux-ptrace.c: Include "gdb_wait.h" header instead of
<sys/wait.h> header.
gdbserver ChangeLog entry:
2012-11-15 Pierre Muller <muller@sourceware.org>
* configure.ac (AC_CHECK_HEADERS): Add wait.h header.
* config.in: Regenerate.
* configure: Regenerate.
* linux-low.c: Use "gdb_stat.h" header instead of <sys/stat.h> header.
Use "gdb_wait.h" header instead of <sys/wait.h> header.
* lynx-low.c: Use "gdb_wait.h" header instead of <sys/wait.h> header.
* remote-utils.c: Use "gdb_stat.h" header instead of <sys/stat.h>
header.
* server.c: Remove HAVE_WAIT_H conditional. Use "gdb_wait.h" header
instead of <sys/wait.h> header.
* spu-low.c: Use "gdb_wait.h" header instead of <sys/wait.h> header.
* solib-svr4.c (svr4_current_sos): New comment on
svr4_current_sos_via_xfer_libraries fall back.
gdb/gdbserver/
* linux-low.c (linux_qxfer_libraries_svr4): Return -1 if R_DEBUG is -1.
gdb/testsuite/
* gdb.server/solib-list-lib.c: New file.
* gdb.server/solib-list-main.c: New file.
* gdb.server/solib-list.exp: New file.
* linux-low (__UCLIBC__ && !(__UCLIBC_HAS_MMU__ || __ARCH_HAS_MMU__)):
Include asm/ptrace.h.
(PT_TEXT_ADDR, PT_DATA_ADDR, PT_TEXT_END_ADDR): Define only if not
already defined.
Pedro Alves <palves@redhat.com>
* linux-low.c (enum stopping_threads_kind): New.
(stopping_threads): Change type to `enum stopping_threads_kind'.
(handle_extended_wait): If stopping and suspending threads, leave
the new_lwp suspended too.
(linux_wait_for_event): Adjust.
(stop_all_lwps): Set `stopping_threads' to
STOPPING_AND_SUSPENDING_THREADS or STOPPING_THREADS depending on
whether we're suspending threads or just stopping them. Assert no
recursion happens.
(PTRACE_ARG4_TYPE): Likewise.
(PTRACE_XFER_TYPE): Likewise.
* linux-arm-low.c (arm_prepare_to_resume): Cast third argument of
ptrace to PTRACE_ARG3_TYPE.
* linux-low.c (PTRACE_ARG3_TYPE): Move macro to linux-low.h.
(PTRACE_ARG4_TYPE): Likewise.
(PTRACE_XFER_TYPE): Likewise.
(linux_detach_one_lwp): Cast fourth argument of
ptrace to long then PTRACE_ARG4_TYPE.
(regsets_fetch_inferior_registers): Cast third argument of
ptrace to long then PTRACE_ARG3_TYPE.
(regsets_store_inferior_registers): Likewise.