4924df7977
Code rationale ============== by: Gabriel Krisman Bertazi This is a fix for bug 16297. The problem occurs when the user attempts to catch any syscall 0 (such as syscall read on Linux/x86_64). GDB was not able to catch the syscall and was missing the breakpoint. Now, breakpoint_hit_catch_syscall returns immediately when it finds the correct syscall number, avoiding a following check for the end of the search vector, that returns a no hit if the syscall number was zero. Testcase rationale ================== by: Sergio Durigan Junior This testcase is a little difficult to write. By doing a quick inspection at the Linux source, one can see that, in many targets, the syscall number 0 is restart_syscall, which is forbidden to be called from userspace. Therefore, on many targets, there's just no way to test this safely. My decision was to take the simpler route and just adds the "read" syscall on the default test. Its number on x86_64 is zero, which is "good enough" since many people here do their tests on x86_64 anyway and it is a popular architecture. However, there was another little gotcha. When using "read" passing 0 as the third parameter (i.e., asking it to read 0 bytes), current libc implementations could choose not to effectively call the syscall. Therefore, the best solution was to create a temporary pipe, write 1 byte into it, and then read this byte from it. gdb/ChangeLog 2013-12-19 Gabriel Krisman Bertazi <gabriel@krisman.be> PR breakpoints/16297 * breakpoint.c (breakpoint_hit_catch_syscall): Return immediately when expected syscall is hit. gdb/testsuite/ChangeLog 2013-12-19 Sergio Durigan Junior <sergiodj@redhat.com> PR breakpoints/16297 * gdb.base/catch-syscall.c (read_syscall, pipe_syscall) (write_syscall): New variables. (main): Create a pipe, write 1 byte in it, and read 1 byte from it. * gdb.base/catch-syscall.exp (all_syscalls): Include "pipe, "write" and "read" syscalls. (fill_all_syscalls_numbers): Improve the way to obtain syscalls numbers.
48 lines
1.3 KiB
C
48 lines
1.3 KiB
C
/* This file is used to test the 'catch syscall' feature on GDB.
|
|
|
|
Please, if you are going to edit this file DO NOT change the syscalls
|
|
being called (nor the order of them). If you really must do this, then
|
|
take a look at catch-syscall.exp and modify there too.
|
|
|
|
Written by Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com>
|
|
September, 2008 */
|
|
|
|
#include <unistd.h>
|
|
#include <sys/syscall.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
/* These are the syscalls numbers used by the test. */
|
|
|
|
static int close_syscall = SYS_close;
|
|
static int chroot_syscall = SYS_chroot;
|
|
/* GDB had a bug where it couldn't catch syscall number 0 (PR 16297).
|
|
In most GNU/Linux architectures, syscall number 0 is
|
|
restart_syscall, which can't be called from userspace. However,
|
|
the "read" syscall is zero on x86_64. */
|
|
static int read_syscall = SYS_read;
|
|
static int pipe_syscall = SYS_pipe;
|
|
static int write_syscall = SYS_write;
|
|
static int exit_group_syscall = SYS_exit_group;
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
int fd[2];
|
|
char buf1[2] = "a";
|
|
char buf2[2];
|
|
|
|
/* A close() with a wrong argument. We are only
|
|
interested in the syscall. */
|
|
close (-1);
|
|
|
|
chroot (".");
|
|
|
|
pipe (fd);
|
|
|
|
write (fd[1], buf1, sizeof (buf1));
|
|
read (fd[0], buf2, sizeof (buf2));
|
|
|
|
/* The last syscall. Do not change this. */
|
|
_exit (0);
|
|
}
|