* inf-ttrace.c: Include <sys/mman.h>.
(struct inf_ttrace_page): New. (struct inf_ttrace_page_dict): New. (inf_ttrace_num_threads_in_syscall) (inf_ttrace_reenable_page_protections): New variables. (inf_ttrace_enable_syscall_events) (inf_ttrace_disable_syscall_events, inf_ttrace_get_page) (inf_ttrace_remove_page, inf_ttrace_mask_page_protections) (inf_ttrace_enable_page_protections) (inf_ttrace_disable_page_protections) (inf_ttrace_insert_watchpoint, inf_ttrace_remove_watchpoint) (inf_ttrace_can_use_hw_breakpoint) (inf_ttrace_region_size_ok_for_hw_watchpoint) (inf_ttrace_stopped_by_watchpoint): New functions. (inf_ttrace_him): Remove unsused varaible `tts'. (inf_ttrace_create_inferior): Add assertionts. (inf_ttrace_mourn_inferior): Clear page dictionary. (inf_ttrace_attach): Set initial event mask. (inf_ttrace_detach): Reset number of threads in system call. (inf_ttrace_wait): Deal with system call events. (inf_ttrace_target): Initialize "hardware" watchpoint-related parts of the target vector. (_initialize_inf_ttrace): New prototype and function.
This commit is contained in:
parent
697afb65fc
commit
932936f0df
2 changed files with 458 additions and 2 deletions
|
@ -1,5 +1,30 @@
|
|||
2004-12-03 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* inf-ttrace.c: Include <sys/mman.h>.
|
||||
(struct inf_ttrace_page): New.
|
||||
(struct inf_ttrace_page_dict): New.
|
||||
(inf_ttrace_num_threads_in_syscall)
|
||||
(inf_ttrace_reenable_page_protections): New variables.
|
||||
(inf_ttrace_enable_syscall_events)
|
||||
(inf_ttrace_disable_syscall_events, inf_ttrace_get_page)
|
||||
(inf_ttrace_add_page, inf_ttrace_insert_page)
|
||||
(inf_ttrace_remove_page, inf_ttrace_mask_page_protections)
|
||||
(inf_ttrace_enable_page_protections)
|
||||
(inf_ttrace_disable_page_protections)
|
||||
(inf_ttrace_insert_watchpoint, inf_ttrace_remove_watchpoint)
|
||||
(inf_ttrace_can_use_hw_breakpoint)
|
||||
(inf_ttrace_region_size_ok_for_hw_watchpoint)
|
||||
(inf_ttrace_stopped_by_watchpoint): New functions.
|
||||
(inf_ttrace_him): Remove unsused varaible `tts'.
|
||||
(inf_ttrace_create_inferior): Add assertionts.
|
||||
(inf_ttrace_mourn_inferior): Clear page dictionary.
|
||||
(inf_ttrace_attach): Set initial event mask.
|
||||
(inf_ttrace_detach): Reset number of threads in system call.
|
||||
(inf_ttrace_wait): Deal with system call events.
|
||||
(inf_ttrace_target): Initialize "hardware" watchpoint-related
|
||||
parts of the target vector.
|
||||
(_initialize_inf_ttrace): New prototype and function.
|
||||
|
||||
* hppa-hpux-tdep.c (hppa_hpux_push_dummy_code): Use ULONGEST as
|
||||
type of `gp' variable.
|
||||
|
||||
|
|
435
gdb/inf-ttrace.c
435
gdb/inf-ttrace.c
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ttrace.h>
|
||||
|
||||
#include "inf-child.h"
|
||||
|
@ -40,6 +41,347 @@
|
|||
|
||||
/* HACK: Save the ttrace ops returned by inf_ttrace_target. */
|
||||
static struct target_ops *ttrace_ops_hack;
|
||||
|
||||
|
||||
/* On HP-UX versions that have the ttrace(2) system call, we can
|
||||
implement "hardware" watchpoints by fiddling with the protection of
|
||||
pages in the address space that contain the variable being watched.
|
||||
In order to implement this, we keep a dictionary of pages for which
|
||||
we have changed the protection. */
|
||||
|
||||
struct inf_ttrace_page
|
||||
{
|
||||
CORE_ADDR addr; /* Page address. */
|
||||
int prot; /* Protection. */
|
||||
int refcount; /* Reference count. */
|
||||
struct inf_ttrace_page *next;
|
||||
struct inf_ttrace_page *prev;
|
||||
};
|
||||
|
||||
struct inf_ttrace_page_dict
|
||||
{
|
||||
struct inf_ttrace_page buckets[128];
|
||||
int pagesize; /* Page size. */
|
||||
int count; /* Number of pages in this dictionary. */
|
||||
} inf_ttrace_page_dict;
|
||||
|
||||
/* Number of threads that are currently in a system call. */
|
||||
static int inf_ttrace_num_threads_in_syscall;
|
||||
|
||||
/* Flag to indicate whether we should re-enable page protections after
|
||||
the next wait. */
|
||||
static int inf_ttrace_reenable_page_protections;
|
||||
|
||||
/* Enable system call events for process PID. */
|
||||
|
||||
static void
|
||||
inf_ttrace_enable_syscall_events (pid_t pid)
|
||||
{
|
||||
ttevent_t tte;
|
||||
ttstate_t tts;
|
||||
|
||||
gdb_assert (inf_ttrace_num_threads_in_syscall == 0);
|
||||
|
||||
if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
|
||||
(uintptr_t)&tte, sizeof tte, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
tte.tte_events |= (TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
|
||||
|
||||
if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
|
||||
(uintptr_t)&tte, sizeof tte, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
if (ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
|
||||
(uintptr_t)&tts, sizeof tts, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
if (tts.tts_flags & TTS_INSYSCALL)
|
||||
inf_ttrace_num_threads_in_syscall++;
|
||||
|
||||
/* FIXME: Handle multiple threads. */
|
||||
}
|
||||
|
||||
/* Disable system call events for process PID. */
|
||||
|
||||
static void
|
||||
inf_ttrace_disable_syscall_events (pid_t pid)
|
||||
{
|
||||
ttevent_t tte;
|
||||
|
||||
gdb_assert (inf_ttrace_page_dict.count == 0);
|
||||
|
||||
if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
|
||||
(uintptr_t)&tte, sizeof tte, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
tte.tte_events &= ~(TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
|
||||
|
||||
if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
|
||||
(uintptr_t)&tte, sizeof tte, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
inf_ttrace_num_threads_in_syscall = 0;
|
||||
}
|
||||
|
||||
/* Get information about the page at address ADDR for process PID from
|
||||
the dictionary. */
|
||||
|
||||
static struct inf_ttrace_page *
|
||||
inf_ttrace_get_page (pid_t pid, CORE_ADDR addr)
|
||||
{
|
||||
const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
int bucket;
|
||||
struct inf_ttrace_page *page;
|
||||
|
||||
bucket = (addr / pagesize) % num_buckets;
|
||||
page = &inf_ttrace_page_dict.buckets[bucket];
|
||||
while (page)
|
||||
{
|
||||
if (page->addr == addr)
|
||||
break;
|
||||
|
||||
page = page->next;
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/* Add the page at address ADDR for process PID to the dictionary. */
|
||||
|
||||
static struct inf_ttrace_page *
|
||||
inf_ttrace_add_page (pid_t pid, CORE_ADDR addr)
|
||||
{
|
||||
const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
int bucket;
|
||||
struct inf_ttrace_page *page;
|
||||
struct inf_ttrace_page *prev = NULL;
|
||||
|
||||
bucket = (addr / pagesize) % num_buckets;
|
||||
page = &inf_ttrace_page_dict.buckets[bucket];
|
||||
while (page)
|
||||
{
|
||||
if (page->addr == addr)
|
||||
break;
|
||||
|
||||
prev = page;
|
||||
page = page->next;
|
||||
}
|
||||
|
||||
if (!page)
|
||||
{
|
||||
int prot;
|
||||
|
||||
if (ttrace (TT_PROC_GET_MPROTECT, pid, 0,
|
||||
addr, 0, (uintptr_t)&prot) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
page = XMALLOC (struct inf_ttrace_page);
|
||||
page->addr = addr;
|
||||
page->prot = prot;
|
||||
page->refcount = 0;
|
||||
page->next = NULL;
|
||||
|
||||
page->prev = prev;
|
||||
prev->next = page;
|
||||
|
||||
inf_ttrace_page_dict.count++;
|
||||
if (inf_ttrace_page_dict.count == 1)
|
||||
inf_ttrace_enable_syscall_events (pid);
|
||||
|
||||
if (inf_ttrace_num_threads_in_syscall == 0)
|
||||
{
|
||||
if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
|
||||
addr, pagesize, prot & ~PROT_WRITE) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
}
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/* Insert the page at address ADDR of process PID to the dictionary. */
|
||||
|
||||
static void
|
||||
inf_ttrace_insert_page (pid_t pid, CORE_ADDR addr)
|
||||
{
|
||||
struct inf_ttrace_page *page;
|
||||
|
||||
page = inf_ttrace_get_page (pid, addr);
|
||||
if (!page)
|
||||
page = inf_ttrace_add_page (pid, addr);
|
||||
|
||||
page->refcount++;
|
||||
}
|
||||
|
||||
/* Remove the page at address ADDR of process PID from the dictionary. */
|
||||
|
||||
static void
|
||||
inf_ttrace_remove_page (pid_t pid, CORE_ADDR addr)
|
||||
{
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
struct inf_ttrace_page *page;
|
||||
|
||||
page = inf_ttrace_get_page (pid, addr);
|
||||
page->refcount--;
|
||||
|
||||
gdb_assert (page->refcount >= 0);
|
||||
|
||||
if (page->refcount == 0)
|
||||
{
|
||||
if (inf_ttrace_num_threads_in_syscall == 0)
|
||||
{
|
||||
if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
|
||||
addr, pagesize, page->prot) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
}
|
||||
|
||||
inf_ttrace_page_dict.count--;
|
||||
if (inf_ttrace_page_dict.count == 0)
|
||||
inf_ttrace_disable_syscall_events (pid);
|
||||
|
||||
page->prev->next = page->next;
|
||||
if (page->next)
|
||||
page->next->prev = page->prev;
|
||||
|
||||
xfree (page);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mask the bits in PROT from the page protections that are currently
|
||||
in the dictionary for process PID. */
|
||||
|
||||
static void
|
||||
inf_ttrace_mask_page_protections (pid_t pid, int prot)
|
||||
{
|
||||
const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
int bucket;
|
||||
|
||||
for (bucket = 0; bucket < num_buckets; bucket++)
|
||||
{
|
||||
struct inf_ttrace_page *page;
|
||||
|
||||
page = inf_ttrace_page_dict.buckets[bucket].next;
|
||||
while (page)
|
||||
{
|
||||
if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
|
||||
page->addr, pagesize, page->prot & ~prot) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
page = page->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write-protect the pages in the dictionary for process PID. */
|
||||
|
||||
static void
|
||||
inf_ttrace_enable_page_protections (pid_t pid)
|
||||
{
|
||||
inf_ttrace_mask_page_protections (pid, PROT_WRITE);
|
||||
}
|
||||
|
||||
/* Restore the protection of the pages in the dictionary for process
|
||||
PID. */
|
||||
|
||||
static void
|
||||
inf_ttrace_disable_page_protections (pid_t pid)
|
||||
{
|
||||
inf_ttrace_mask_page_protections (pid, 0);
|
||||
}
|
||||
|
||||
/* Insert a "hardware" watchpoint for LEN bytes at address ADDR of
|
||||
type TYPE. */
|
||||
|
||||
static int
|
||||
inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type)
|
||||
{
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
pid_t pid = ptid_get_pid (inferior_ptid);
|
||||
CORE_ADDR page_addr;
|
||||
int num_pages;
|
||||
int page;
|
||||
|
||||
gdb_assert (type == hw_write);
|
||||
|
||||
page_addr = (addr / pagesize) * pagesize;
|
||||
num_pages = (len + pagesize - 1) / pagesize;
|
||||
|
||||
for (page = 0; page < num_pages; page++, page_addr += pagesize)
|
||||
inf_ttrace_insert_page (pid, page_addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Remove a "hardware" watchpoint for LEN bytes at address ADDR of
|
||||
type TYPE. */
|
||||
|
||||
static int
|
||||
inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type)
|
||||
{
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
pid_t pid = ptid_get_pid (inferior_ptid);
|
||||
CORE_ADDR page_addr;
|
||||
int num_pages;
|
||||
int page;
|
||||
|
||||
gdb_assert (type == hw_write);
|
||||
|
||||
page_addr = (addr / pagesize) * pagesize;
|
||||
num_pages = (len + pagesize - 1) / pagesize;
|
||||
|
||||
for (page = 0; page < num_pages; page++, page_addr += pagesize)
|
||||
inf_ttrace_remove_page (pid, page_addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
inf_ttrace_can_use_hw_breakpoint (int type, int len, int ot)
|
||||
{
|
||||
return (type == bp_hardware_watchpoint);
|
||||
}
|
||||
|
||||
static int
|
||||
inf_ttrace_region_size_ok_for_hw_watchpoint (int len)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return non-zero if the current inferior was (potentially) stopped
|
||||
by hitting a "hardware" watchpoint. */
|
||||
|
||||
static int
|
||||
inf_ttrace_stopped_by_watchpoint (void)
|
||||
{
|
||||
pid_t pid = ptid_get_pid (inferior_ptid);
|
||||
lwpid_t lwpid = ptid_get_lwp (inferior_ptid);
|
||||
ttstate_t tts;
|
||||
|
||||
if (inf_ttrace_page_dict.count > 0)
|
||||
{
|
||||
if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
|
||||
(uintptr_t)&tts, sizeof tts, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
if (tts.tts_event == TTEVT_SIGNAL
|
||||
&& tts.tts_u.tts_signal.tts_signo == SIGBUS)
|
||||
{
|
||||
const int pagesize = inf_ttrace_page_dict.pagesize;
|
||||
void *addr = tts.tts_u.tts_signal.tts_siginfo.si_addr;
|
||||
CORE_ADDR page_addr = ((uintptr_t)addr / pagesize) * pagesize;
|
||||
|
||||
if (inf_ttrace_get_page (pid, page_addr))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* File descriptors for pipes used as semaphores during initial
|
||||
startup of an inferior. */
|
||||
|
@ -99,7 +441,6 @@ inf_ttrace_him (int pid)
|
|||
{
|
||||
struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
|
||||
ttevent_t tte;
|
||||
ttstate_t tts;
|
||||
char c;
|
||||
|
||||
/* Wait until our child is ready to be traced. */
|
||||
|
@ -143,6 +484,10 @@ static void
|
|||
inf_ttrace_create_inferior (char *exec_file, char *allargs, char **env,
|
||||
int from_tty)
|
||||
{
|
||||
gdb_assert (inf_ttrace_page_dict.count == 0);
|
||||
gdb_assert (inf_ttrace_num_threads_in_syscall == 0);
|
||||
gdb_assert (inf_ttrace_reenable_page_protections == 0);
|
||||
|
||||
fork_inferior (exec_file, allargs, env, inf_ttrace_me, inf_ttrace_him,
|
||||
inf_ttrace_prepare, NULL);
|
||||
|
||||
|
@ -170,6 +515,26 @@ inf_ttrace_kill_inferior (void)
|
|||
static void
|
||||
inf_ttrace_mourn_inferior (void)
|
||||
{
|
||||
const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
|
||||
int bucket;
|
||||
|
||||
inf_ttrace_num_threads_in_syscall = 0;
|
||||
|
||||
for (bucket = 0; bucket < num_buckets; bucket++)
|
||||
{
|
||||
struct inf_ttrace_page *page;
|
||||
struct inf_ttrace_page *next;
|
||||
|
||||
page = inf_ttrace_page_dict.buckets[bucket].next;
|
||||
while (page)
|
||||
{
|
||||
next = page->next;
|
||||
xfree (page);
|
||||
page = next;
|
||||
}
|
||||
}
|
||||
inf_ttrace_page_dict.count = 0;
|
||||
|
||||
unpush_target (ttrace_ops_hack);
|
||||
generic_mourn_inferior ();
|
||||
}
|
||||
|
@ -180,6 +545,7 @@ inf_ttrace_attach (char *args, int from_tty)
|
|||
char *exec_file;
|
||||
pid_t pid;
|
||||
char *dummy;
|
||||
ttevent_t tte;
|
||||
|
||||
if (!args)
|
||||
error_no_arg ("process-id to attach");
|
||||
|
@ -210,6 +576,15 @@ inf_ttrace_attach (char *args, int from_tty)
|
|||
perror_with_name ("ttrace");
|
||||
attach_flag = 1;
|
||||
|
||||
/* Set the initial event mask. */
|
||||
gdb_assert (inf_ttrace_num_threads_in_syscall == 0);
|
||||
memset (&tte, 0, sizeof (tte));
|
||||
tte.tte_events = TTEVT_EXEC | TTEVT_EXIT;
|
||||
tte.tte_opts = TTEO_NOSTRCCHLD;
|
||||
if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
|
||||
(uintptr_t)&tte, sizeof tte, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
inferior_ptid = pid_to_ptid (pid);
|
||||
push_target (ttrace_ops_hack);
|
||||
|
||||
|
@ -241,8 +616,10 @@ inf_ttrace_detach (char *args, int from_tty)
|
|||
if (ttrace (TT_PROC_DETACH, pid, 0, 0, sig, 0) == -1)
|
||||
perror_with_name ("ttrace");
|
||||
|
||||
inferior_ptid = null_ptid;
|
||||
inf_ttrace_num_threads_in_syscall = 0;
|
||||
|
||||
unpush_target (ttrace_ops_hack);
|
||||
inferior_ptid = null_ptid;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -277,6 +654,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
|
|||
lwpid_t lwpid = ptid_get_lwp (ptid);
|
||||
ttstate_t tts;
|
||||
|
||||
/* Until proven otherwise. */
|
||||
ourstatus->kind = TARGET_WAITKIND_IGNORE;
|
||||
|
||||
if (pid == -1)
|
||||
|
@ -297,6 +675,14 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
|
|||
}
|
||||
while (tts.tts_event == TTEVT_NONE);
|
||||
|
||||
/* Now that we've waited, we can re-enable the page protections. */
|
||||
if (inf_ttrace_reenable_page_protections)
|
||||
{
|
||||
gdb_assert (inf_ttrace_num_threads_in_syscall == 0);
|
||||
inf_ttrace_enable_page_protections (tts.tts_pid);
|
||||
inf_ttrace_reenable_page_protections = 0;
|
||||
}
|
||||
|
||||
switch (tts.tts_event)
|
||||
{
|
||||
case TTEVT_EXEC:
|
||||
|
@ -304,14 +690,44 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
|
|||
ourstatus->kind = TARGET_WAITKIND_STOPPED;
|
||||
ourstatus->value.sig = TARGET_SIGNAL_TRAP;
|
||||
break;
|
||||
|
||||
case TTEVT_EXIT:
|
||||
store_waitstatus (ourstatus, tts.tts_u.tts_exit.tts_exitcode);
|
||||
break;
|
||||
|
||||
case TTEVT_SIGNAL:
|
||||
ourstatus->kind = TARGET_WAITKIND_STOPPED;
|
||||
ourstatus->value.sig =
|
||||
target_signal_from_host (tts.tts_u.tts_signal.tts_signo);
|
||||
break;
|
||||
|
||||
case TTEVT_SYSCALL_ENTRY:
|
||||
gdb_assert (inf_ttrace_reenable_page_protections == 0);
|
||||
inf_ttrace_num_threads_in_syscall++;
|
||||
if (inf_ttrace_num_threads_in_syscall == 1)
|
||||
{
|
||||
/* A thread has just entered a system call. Disable any
|
||||
page protections as the kernel can't deal with them. */
|
||||
inf_ttrace_disable_page_protections (tts.tts_pid);
|
||||
}
|
||||
ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
|
||||
ourstatus->value.syscall_id = tts.tts_scno;
|
||||
break;
|
||||
|
||||
case TTEVT_SYSCALL_RETURN:
|
||||
if (inf_ttrace_num_threads_in_syscall > 0)
|
||||
{
|
||||
/* If the last thread has just left the system call, this
|
||||
would be a logical place to re-enable the page
|
||||
protections, but that doesn't work. We can't re-enable
|
||||
them until we've done another wait. */
|
||||
inf_ttrace_reenable_page_protections =
|
||||
(inf_ttrace_num_threads_in_syscall == 1);
|
||||
inf_ttrace_num_threads_in_syscall--;
|
||||
}
|
||||
ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
|
||||
ourstatus->value.syscall_id = tts.tts_scno;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure all threads within the process are stopped. */
|
||||
|
@ -405,9 +821,24 @@ inf_ttrace_target (void)
|
|||
t->to_wait = inf_ttrace_wait;
|
||||
t->to_xfer_partial = inf_ttrace_xfer_partial;
|
||||
t->to_files_info = inf_ttrace_files_info;
|
||||
t->to_can_use_hw_breakpoint = inf_ttrace_can_use_hw_breakpoint;
|
||||
t->to_region_size_ok_for_hw_watchpoint =
|
||||
inf_ttrace_region_size_ok_for_hw_watchpoint;
|
||||
t->to_insert_watchpoint = inf_ttrace_insert_watchpoint;
|
||||
t->to_remove_watchpoint = inf_ttrace_remove_watchpoint;
|
||||
t->to_stopped_by_watchpoint = inf_ttrace_stopped_by_watchpoint;
|
||||
|
||||
ttrace_ops_hack = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/* Prevent warning from -Wmissing-prototypes. */
|
||||
void _initialize_hppa_hpux_nat (void);
|
||||
|
||||
void
|
||||
_initialize_inf_ttrace (void)
|
||||
{
|
||||
inf_ttrace_page_dict.pagesize = getpagesize();
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue