infttrace.c revision 46283
146283Sdfr/* Low level Unix child interface to ttrace, for GDB when running under HP-UX. 246283Sdfr Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 346283Sdfr Free Software Foundation, Inc. 446283Sdfr 546283SdfrThis file is part of GDB. 646283Sdfr 746283SdfrThis program is free software; you can redistribute it and/or modify 846283Sdfrit under the terms of the GNU General Public License as published by 946283Sdfrthe Free Software Foundation; either version 2 of the License, or 1046283Sdfr(at your option) any later version. 1146283Sdfr 1246283SdfrThis program is distributed in the hope that it will be useful, 1346283Sdfrbut WITHOUT ANY WARRANTY; without even the implied warranty of 1446283SdfrMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1546283SdfrGNU General Public License for more details. 1646283Sdfr 1746283SdfrYou should have received a copy of the GNU General Public License 1846283Sdfralong with this program; if not, write to the Free Software 1946283SdfrFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2046283Sdfr 2146283Sdfr#include "defs.h" 2246283Sdfr#include "frame.h" 2346283Sdfr#include "inferior.h" 2446283Sdfr#include "target.h" 2546283Sdfr#include "gdb_string.h" 2646283Sdfr#include "wait.h" 2746283Sdfr#include "command.h" 2846283Sdfr 2946283Sdfr/* Some hackery to work around a use of the #define name NO_FLAGS 3046283Sdfr * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h). 3146283Sdfr */ 3246283Sdfr#ifdef NO_FLAGS 3346283Sdfr#define INFTTRACE_TEMP_HACK NO_FLAGS 3446283Sdfr#undef NO_FLAGS 3546283Sdfr#endif 3646283Sdfr 3746283Sdfr#ifdef USG 3846283Sdfr#include <sys/types.h> 3946283Sdfr#endif 4046283Sdfr 4146283Sdfr#include <sys/param.h> 4246283Sdfr#include <sys/dir.h> 4346283Sdfr#include <signal.h> 4446283Sdfr#include <sys/ioctl.h> 4546283Sdfr 4646283Sdfr#include <sys/ttrace.h> 4746283Sdfr#ifdef HAVE_UNISTD_H 4846283Sdfr#include <unistd.h> 4946283Sdfr#endif 5046283Sdfr#include <sys/mman.h> 5146283Sdfr 5246283Sdfr#ifndef NO_PTRACE_H 5346283Sdfr#ifdef PTRACE_IN_WRONG_PLACE 5446283Sdfr#include <ptrace.h> 5546283Sdfr#else 5646283Sdfr#include <sys/ptrace.h> 5746283Sdfr#endif 5846283Sdfr#endif /* NO_PTRACE_H */ 5946283Sdfr 6046283Sdfr/* Second half of the hackery above. Non-ANSI C, so 6146283Sdfr * we can't use "#error", alas. 6246283Sdfr */ 6346283Sdfr#ifdef NO_FLAGS 6446283Sdfr#if (NO_FLAGS != INFTTRACE_TEMP_HACK ) 6546283Sdfr /* #error "Hackery to remove warning didn't work right" */ 6646283Sdfr#else 6746283Sdfr /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */ 6846283Sdfr#endif 6946283Sdfr#else 7046283Sdfr /* #error "Didn't get expected re-definition of NO_FLAGS" */ 7146283Sdfr#define NO_FLAGS INFTTRACE_TEMP_HACK 7246283Sdfr#endif 7346283Sdfr 7446283Sdfr#if !defined (PT_SETTRC) 7546283Sdfr#define PT_SETTRC 0 /* Make process traceable by parent */ 7646283Sdfr#endif 7746283Sdfr#if !defined (PT_READ_I) 7846283Sdfr#define PT_READ_I 1 /* Read word from text space */ 7946283Sdfr#endif 8046283Sdfr#if !defined (PT_READ_D) 8146283Sdfr#define PT_READ_D 2 /* Read word from data space */ 8246283Sdfr#endif 8346283Sdfr#if !defined (PT_READ_U) 8446283Sdfr#define PT_READ_U 3 /* Read word from kernel user struct */ 8546283Sdfr#endif 8646283Sdfr#if !defined (PT_WRITE_I) 8746283Sdfr#define PT_WRITE_I 4 /* Write word to text space */ 8846283Sdfr#endif 8946283Sdfr#if !defined (PT_WRITE_D) 9046283Sdfr#define PT_WRITE_D 5 /* Write word to data space */ 9146283Sdfr#endif 9246283Sdfr#if !defined (PT_WRITE_U) 9346283Sdfr#define PT_WRITE_U 6 /* Write word to kernel user struct */ 9446283Sdfr#endif 9546283Sdfr#if !defined (PT_CONTINUE) 9646283Sdfr#define PT_CONTINUE 7 /* Continue after signal */ 9746283Sdfr#endif 9846283Sdfr#if !defined (PT_STEP) 9946283Sdfr#define PT_STEP 9 /* Set flag for single stepping */ 10046283Sdfr#endif 10146283Sdfr#if !defined (PT_KILL) 10246283Sdfr#define PT_KILL 8 /* Send child a SIGKILL signal */ 10346283Sdfr#endif 10446283Sdfr 10546283Sdfr#ifndef PT_ATTACH 10646283Sdfr#define PT_ATTACH PTRACE_ATTACH 10746283Sdfr#endif 10846283Sdfr#ifndef PT_DETACH 10946283Sdfr#define PT_DETACH PTRACE_DETACH 11046283Sdfr#endif 11146283Sdfr 11246283Sdfr#include "gdbcore.h" 11346283Sdfr#ifndef NO_SYS_FILE 11446283Sdfr#include <sys/file.h> 11546283Sdfr#endif 11646283Sdfr 11746283Sdfr/* This semaphore is used to coordinate the child and parent processes 11846283Sdfr after a fork(), and before an exec() by the child. See parent_attach_all 11946283Sdfr for details. 12046283Sdfr */ 12146283Sdfrtypedef struct { 12246283Sdfr int parent_channel[2]; /* Parent "talks" to [1], child "listens" to [0] */ 12346283Sdfr int child_channel[2]; /* Child "talks" to [1], parent "listens" to [0] */ 12446283Sdfr} startup_semaphore_t; 12546283Sdfr 12646283Sdfr#define SEM_TALK (1) 12746283Sdfr#define SEM_LISTEN (0) 12846283Sdfr 12946283Sdfrstatic startup_semaphore_t startup_semaphore; 13046283Sdfr 13146283Sdfr/* See can_touch_threads_of_process for details. */ 13246283Sdfrstatic int vforking_child_pid = 0; 13346283Sdfrstatic int vfork_in_flight = 0; 13446283Sdfr 13546283Sdfr/* To support PREPARE_TO_PROCEED (hppa_prepare_to_proceed). 13646283Sdfr */ 13746283Sdfrstatic pid_t old_gdb_pid = 0; 13846283Sdfrstatic pid_t reported_pid = 0; 13946283Sdfrstatic int reported_bpt = 0; 14046283Sdfr 14146283Sdfr/* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise. 14246283Sdfr */ 14346283Sdfr#define TT_OK( _status, _errno ) \ 14446283Sdfr (((_status) == 1) && ((_errno) == 0)) 14546283Sdfr 14646283Sdfr#define TTRACE_ARG_TYPE uint64_t 14746283Sdfr 14846283Sdfr/* When supplied as the "addr" operand, ttrace interprets this 14946283Sdfr to mean, "from the current address". 15046283Sdfr */ 15146283Sdfr#define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC) 15246283Sdfr 15346283Sdfr/* When supplied as the "addr", "data" or "addr2" operand for most 15446283Sdfr requests, ttrace interprets this to mean, "pay no heed to this 15546283Sdfr argument". 15646283Sdfr */ 15746283Sdfr#define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG) 15846283Sdfr 15946283Sdfr/* This is capable of holding the value of a 32-bit register. The 16046283Sdfr value is always left-aligned in the buffer; i.e., [0] contains 16146283Sdfr the most-significant byte of the register's value, and [sizeof(reg)] 16246283Sdfr contains the least-significant value. 16346283Sdfr 16446283Sdfr ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and 16546283Sdfr that registers are 32-bits on HP-UX. The latter assumption changes 16646283Sdfr with PA2.0. 16746283Sdfr */ 16846283Sdfrtypedef int register_value_t; 16946283Sdfr 17046283Sdfr/******************************************************************** 17146283Sdfr 17246283Sdfr How this works: 17346283Sdfr 17446283Sdfr 1. Thread numbers 17546283Sdfr 17646283Sdfr The rest of GDB sees threads as being things with different 17746283Sdfr "pid" (process id) values. See "thread.c" for details. The 17846283Sdfr separate threads will be seen and reacted to if infttrace passes 17946283Sdfr back different pid values (for _events_). See wait_for_inferior 18046283Sdfr in inftarg.c. 18146283Sdfr 18246283Sdfr So infttrace is going to use thread ids externally, pretending 18346283Sdfr they are process ids, and keep track internally so that it can 18446283Sdfr use the real process id (and thread id) when calling ttrace. 18546283Sdfr 18646283Sdfr The data structure that supports this is a linked list of the 18746283Sdfr current threads. Since at some date infttrace will have to 18846283Sdfr deal with multiple processes, each list element records its 18946283Sdfr corresponding pid, rather than having a single global. 19046283Sdfr 19146283Sdfr Note that the list is only approximately current; that's ok, as 19246283Sdfr it's up to date when we need it (we hope!). Also, it can contain 19346283Sdfr dead threads, as there's no harm if it does. 19446283Sdfr 19546283Sdfr The approach taken here is to bury the translation from external 19646283Sdfr to internal inside "call_ttrace" and a few other places. 19746283Sdfr 19846283Sdfr There are some wrinkles: 19946283Sdfr 20046283Sdfr o When GDB forks itself to create the debug target process, 20146283Sdfr there's only a pid of 0 around in the child, so the 20246283Sdfr TT_PROC_SETTRC operation uses a more direct call to ttrace; 20346283Sdfr Similiarly, the initial setting of the event mask happens 20446283Sdfr early as well, and so is also special-cased, and an attach 20546283Sdfr uses a real pid; 20646283Sdfr 20746283Sdfr o We define an unthreaded application as having a "pseudo" 20846283Sdfr thread; 20946283Sdfr 21046283Sdfr o To keep from confusing the rest of GDB, we don't switch 21146283Sdfr the PID for the pseudo thread to a TID. A table will help: 21246283Sdfr 21346283Sdfr Rest of GDB sees these PIDs: pid tid1 tid2 tid3 ... 21446283Sdfr 21546283Sdfr Our thread list stores: pid pid pid pid ... 21646283Sdfr tid0 tid1 tid2 tid3 21746283Sdfr 21846283Sdfr Ttrace sees these TIDS: tid0 tid1 tid2 tid3 ... 21946283Sdfr 22046283Sdfr Both pid and tid0 will map to tid0, as there are infttrace.c-internal 22146283Sdfr calls to ttrace using tid0. 22246283Sdfr 22346283Sdfr 2. Step and Continue 22446283Sdfr 22546283Sdfr Since we're implementing the "stop the world" model, sub-model 22646283Sdfr "other threads run during step", we have some stuff to do: 22746283Sdfr 22846283Sdfr o User steps require continuing all threads other than the 22946283Sdfr one the user is stepping; 23046283Sdfr 23146283Sdfr o Internal debugger steps (such as over a breakpoint or watchpoint, 23246283Sdfr but not out of a library load thunk) require stepping only 23346283Sdfr the selected thread; this means that we have to report the 23446283Sdfr step finish on that thread, which can lead to complications; 23546283Sdfr 23646283Sdfr o When a thread is created, it is created running, rather 23746283Sdfr than stopped--so we have to stop it. 23846283Sdfr 23946283Sdfr The OS doesn't guarantee the stopped thread list will be stable, 24046283Sdfr no does it guarantee where on the stopped thread list a thread 24146283Sdfr that is single-stepped will wind up: it's possible that it will 24246283Sdfr be off the list for a while, it's possible the step will complete 24346283Sdfr and it will be re-posted to the end... 24446283Sdfr 24546283Sdfr This means we have to scan the stopped thread list, build up 24646283Sdfr a work-list, and then run down the work list; we can't do the 24746283Sdfr step/continue during the scan. 24846283Sdfr 24946283Sdfr 3. Buffering events 25046283Sdfr 25146283Sdfr Then there's the issue of waiting for an event. We do this by 25246283Sdfr noticing how many events are reported at the end of each wait. 25346283Sdfr From then on, we "fake" all resumes and steps, returning instantly, 25446283Sdfr and don't do another wait. Once all pending events are reported, 25546283Sdfr we can really resume again. 25646283Sdfr 25746283Sdfr To keep this hidden, all the routines which know about tids and 25846283Sdfr pids or real events and simulated ones are static (file-local). 25946283Sdfr 26046283Sdfr This code can make lots of calls to ttrace, in particular it 26146283Sdfr can spin down the list of thread states more than once. If this 26246283Sdfr becomes a performance hit, the spin could be done once and the 26346283Sdfr various "tsp" blocks saved, keeping all later spins in this 26446283Sdfr process. 26546283Sdfr 26646283Sdfr The O/S doesn't promise to keep the list straight, and so we must 26746283Sdfr re-scan a lot. By observation, it looks like a single-step/wait 26846283Sdfr puts the stepped thread at the end of the list but doesn't change 26946283Sdfr it otherwise. 27046283Sdfr 27146283Sdfr**************************************************************** 27246283Sdfr*/ 27346283Sdfr 27446283Sdfr/* Uncomment these to turn on various debugging output */ 27546283Sdfr/* #define THREAD_DEBUG */ 27646283Sdfr/* #define WAIT_BUFFER_DEBUG */ 27746283Sdfr/* #define PARANOIA */ 27846283Sdfr 27946283Sdfr 28046283Sdfr#define INFTTRACE_ALL_THREADS (-1) 28146283Sdfr#define INFTTRACE_STEP (1) 28246283Sdfr#define INFTTRACE_CONTINUE (0) 28346283Sdfr 28446283Sdfr/* FIX: this is used in inftarg.c/child_wait, in a hack. 28546283Sdfr */ 28646283Sdfrextern int not_same_real_pid; 28746283Sdfr 28846283Sdfr/* This is used to count buffered events. 28946283Sdfr */ 29046283Sdfrstatic unsigned int more_events_left = 0; 29146283Sdfr 29246283Sdfr/* Process state. 29346283Sdfr */ 29446283Sdfrtypedef enum process_state_enum { 29546283Sdfr STOPPED, 29646283Sdfr FAKE_STEPPING, 29746283Sdfr FAKE_CONTINUE, /* For later use */ 29846283Sdfr RUNNING, 29946283Sdfr FORKING, 30046283Sdfr VFORKING 30146283Sdfr} process_state_t; 30246283Sdfr 30346283Sdfrstatic process_state_t process_state = STOPPED; 30446283Sdfr 30546283Sdfr/* User-specified stepping modality. 30646283Sdfr */ 30746283Sdfrtypedef enum stepping_mode_enum { 30846283Sdfr DO_DEFAULT, /* ...which is a continue! */ 30946283Sdfr DO_STEP, 31046283Sdfr DO_CONTINUE 31146283Sdfr} stepping_mode_t; 31246283Sdfr 31346283Sdfr/* Action to take on an attach, depends on 31446283Sdfr * what kind (user command, fork, vfork). 31546283Sdfr * 31646283Sdfr * At the moment, this is either: 31746283Sdfr * 31846283Sdfr * o continue with a SIGTRAP signal, or 31946283Sdfr * 32046283Sdfr * o leave stopped. 32146283Sdfr */ 32246283Sdfrtypedef enum attach_continue_enum { 32346283Sdfr DO_ATTACH_CONTINUE, 32446283Sdfr DONT_ATTACH_CONTINUE 32546283Sdfr} attach_continue_t; 32646283Sdfr 32746283Sdfr/* This flag is true if we are doing a step-over-bpt 32846283Sdfr * with buffered events. We will have to be sure to 32946283Sdfr * report the right thread, as otherwise the spaghetti 33046283Sdfr * code in "infrun.c/wait_for_inferior" will get 33146283Sdfr * confused. 33246283Sdfr */ 33346283Sdfrstatic int doing_fake_step = 0; 33446283Sdfrstatic lwpid_t fake_step_tid = 0; 33546283Sdfr 33646283Sdfr 33746283Sdfr/**************************************************** 33846283Sdfr * Thread information structure routines and types. * 33946283Sdfr **************************************************** 34046283Sdfr */ 34146283Sdfrtypedef 34246283Sdfrstruct thread_info_struct 34346283Sdfr{ 34446283Sdfr int am_pseudo; /* This is a pseudo-thread for the process. */ 34546283Sdfr int pid; /* Process ID */ 34646283Sdfr lwpid_t tid; /* Thread ID */ 34746283Sdfr int handled; /* 1 if a buffered event was handled. */ 34846283Sdfr int seen; /* 1 if this thread was seen on a traverse. */ 34946283Sdfr int terminated; /* 1 if thread has terminated. */ 35046283Sdfr int have_signal; /* 1 if signal to be sent */ 35146283Sdfr enum target_signal signal_value; /* Signal to send */ 35246283Sdfr int have_start; /* 1 if alternate starting address */ 35346283Sdfr stepping_mode_t stepping_mode; /* Whether to step or continue */ 35446283Sdfr CORE_ADDR start; /* Where to start */ 35546283Sdfr int have_state; /* 1 if the event state has been set */ 35646283Sdfr ttstate_t last_stop_state;/* The most recently-waited event for this thread. */ 35746283Sdfr struct thread_info_struct 35846283Sdfr *next; /* All threads are linked via this field. */ 35946283Sdfr struct thread_info_struct 36046283Sdfr *next_pseudo; /* All pseudo-threads are linked via this field. */ 36146283Sdfr} thread_info; 36246283Sdfr 36346283Sdfrtypedef 36446283Sdfrstruct thread_info_header_struct 36546283Sdfr{ 36646283Sdfr int count; 36746283Sdfr thread_info *head; 36846283Sdfr thread_info *head_pseudo; 36946283Sdfr 37046283Sdfr} thread_info_header; 37146283Sdfr 37246283Sdfrstatic thread_info_header thread_head = { 0, NULL, NULL }; 37346283Sdfrstatic thread_info_header deleted_threads = { 0, NULL, NULL }; 37446283Sdfr 37546283Sdfrstatic saved_real_pid = 0; 37646283Sdfr 37746283Sdfr 37846283Sdfr/************************************************* 37946283Sdfr * Debugging support functions * 38046283Sdfr ************************************************* 38146283Sdfr */ 38246283SdfrCORE_ADDR 38346283Sdfrget_raw_pc( ttid ) 38446283Sdfr lwpid_t ttid; 38546283Sdfr{ 38646283Sdfr unsigned long pc_val; 38746283Sdfr int offset; 38846283Sdfr int res; 38946283Sdfr 39046283Sdfr offset = register_addr( PC_REGNUM, U_REGS_OFFSET ); 39146283Sdfr res = read_from_register_save_state( 39246283Sdfr ttid, 39346283Sdfr (TTRACE_ARG_TYPE) offset, 39446283Sdfr (char *) &pc_val, 39546283Sdfr sizeof( pc_val )); 39646283Sdfr if( res <= 0 ) { 39746283Sdfr return (CORE_ADDR) pc_val; 39846283Sdfr } 39946283Sdfr else { 40046283Sdfr return (CORE_ADDR) 0; 40146283Sdfr } 40246283Sdfr} 40346283Sdfr 40446283Sdfrstatic char * 40546283Sdfrget_printable_name_of_stepping_mode( mode ) 40646283Sdfr stepping_mode_t mode; 40746283Sdfr{ 40846283Sdfr switch( mode ) { 40946283Sdfr case DO_DEFAULT: return "DO_DEFAULT"; 41046283Sdfr case DO_STEP: return "DO_STEP"; 41146283Sdfr case DO_CONTINUE: return "DO_CONTINUE"; 41246283Sdfr default: return "?unknown mode?"; 41346283Sdfr } 41446283Sdfr} 41546283Sdfr 41646283Sdfr/* This function returns a pointer to a string describing the 41746283Sdfr * ttrace event being reported. 41846283Sdfr */ 41946283Sdfrchar * 42046283Sdfrget_printable_name_of_ttrace_event (event) 42146283Sdfr ttevents_t event; 42246283Sdfr{ 42346283Sdfr /* This enumeration is "gappy", so don't use a table. */ 42446283Sdfr switch (event) { 42546283Sdfr 42646283Sdfr case TTEVT_NONE: 42746283Sdfr return "TTEVT_NONE"; 42846283Sdfr case TTEVT_SIGNAL: 42946283Sdfr return "TTEVT_SIGNAL"; 43046283Sdfr case TTEVT_FORK: 43146283Sdfr return "TTEVT_FORK"; 43246283Sdfr case TTEVT_EXEC: 43346283Sdfr return "TTEVT_EXEC"; 43446283Sdfr case TTEVT_EXIT: 43546283Sdfr return "TTEVT_EXIT"; 43646283Sdfr case TTEVT_VFORK: 43746283Sdfr return "TTEVT_VFORK"; 43846283Sdfr case TTEVT_SYSCALL_RETURN: 43946283Sdfr return "TTEVT_SYSCALL_RETURN"; 44046283Sdfr case TTEVT_LWP_CREATE: 44146283Sdfr return "TTEVT_LWP_CREATE"; 44246283Sdfr case TTEVT_LWP_TERMINATE: 44346283Sdfr return "TTEVT_LWP_TERMINATE"; 44446283Sdfr case TTEVT_LWP_EXIT: 44546283Sdfr return "TTEVT_LWP_EXIT"; 44646283Sdfr case TTEVT_LWP_ABORT_SYSCALL: 44746283Sdfr return "TTEVT_LWP_ABORT_SYSCALL"; 44846283Sdfr case TTEVT_SYSCALL_ENTRY: 44946283Sdfr return "TTEVT_SYSCALL_ENTRY"; 45046283Sdfr case TTEVT_SYSCALL_RESTART: 45146283Sdfr return "TTEVT_SYSCALL_RESTART"; 45246283Sdfr default : 45346283Sdfr return "?new event?"; 45446283Sdfr } 45546283Sdfr} 45646283Sdfr 45746283Sdfr 45846283Sdfr/* This function translates the ttrace request enumeration into 45946283Sdfr * a character string that is its printable (aka "human readable") 46046283Sdfr * name. 46146283Sdfr */ 46246283Sdfrchar * 46346283Sdfrget_printable_name_of_ttrace_request (request) 46446283Sdfr ttreq_t request; 46546283Sdfr{ 46646283Sdfr if (!IS_TTRACE_REQ (request)) 46746283Sdfr return "?bad req?"; 46846283Sdfr 46946283Sdfr /* This enumeration is "gappy", so don't use a table. */ 47046283Sdfr switch (request) { 47146283Sdfr case TT_PROC_SETTRC : 47246283Sdfr return "TT_PROC_SETTRC"; 47346283Sdfr case TT_PROC_ATTACH : 47446283Sdfr return "TT_PROC_ATTACH"; 47546283Sdfr case TT_PROC_DETACH : 47646283Sdfr return "TT_PROC_DETACH"; 47746283Sdfr case TT_PROC_RDTEXT : 47846283Sdfr return "TT_PROC_RDTEXT"; 47946283Sdfr case TT_PROC_WRTEXT : 48046283Sdfr return "TT_PROC_WRTEXT"; 48146283Sdfr case TT_PROC_RDDATA : 48246283Sdfr return "TT_PROC_RDDATA"; 48346283Sdfr case TT_PROC_WRDATA : 48446283Sdfr return "TT_PROC_WRDATA"; 48546283Sdfr case TT_PROC_STOP : 48646283Sdfr return "TT_PROC_STOP"; 48746283Sdfr case TT_PROC_CONTINUE : 48846283Sdfr return "TT_PROC_CONTINUE"; 48946283Sdfr case TT_PROC_GET_PATHNAME : 49046283Sdfr return "TT_PROC_GET_PATHNAME"; 49146283Sdfr case TT_PROC_GET_EVENT_MASK : 49246283Sdfr return "TT_PROC_GET_EVENT_MASK"; 49346283Sdfr case TT_PROC_SET_EVENT_MASK : 49446283Sdfr return "TT_PROC_SET_EVENT_MASK"; 49546283Sdfr case TT_PROC_GET_FIRST_LWP_STATE : 49646283Sdfr return "TT_PROC_GET_FIRST_LWP_STATE"; 49746283Sdfr case TT_PROC_GET_NEXT_LWP_STATE : 49846283Sdfr return "TT_PROC_GET_NEXT_LWP_STATE"; 49946283Sdfr case TT_PROC_EXIT : 50046283Sdfr return "TT_PROC_EXIT"; 50146283Sdfr case TT_PROC_GET_MPROTECT : 50246283Sdfr return "TT_PROC_GET_MPROTECT"; 50346283Sdfr case TT_PROC_SET_MPROTECT : 50446283Sdfr return "TT_PROC_SET_MPROTECT"; 50546283Sdfr case TT_PROC_SET_SCBM : 50646283Sdfr return "TT_PROC_SET_SCBM"; 50746283Sdfr case TT_LWP_STOP : 50846283Sdfr return "TT_LWP_STOP"; 50946283Sdfr case TT_LWP_CONTINUE : 51046283Sdfr return "TT_LWP_CONTINUE"; 51146283Sdfr case TT_LWP_SINGLE : 51246283Sdfr return "TT_LWP_SINGLE"; 51346283Sdfr case TT_LWP_RUREGS : 51446283Sdfr return "TT_LWP_RUREGS"; 51546283Sdfr case TT_LWP_WUREGS : 51646283Sdfr return "TT_LWP_WUREGS"; 51746283Sdfr case TT_LWP_GET_EVENT_MASK : 51846283Sdfr return "TT_LWP_GET_EVENT_MASK"; 51946283Sdfr case TT_LWP_SET_EVENT_MASK : 52046283Sdfr return "TT_LWP_SET_EVENT_MASK"; 52146283Sdfr case TT_LWP_GET_STATE : 52246283Sdfr return "TT_LWP_GET_STATE"; 52346283Sdfr default : 52446283Sdfr return "?new req?"; 52546283Sdfr } 52646283Sdfr} 52746283Sdfr 52846283Sdfr 52946283Sdfr/* This function translates the process state enumeration into 53046283Sdfr * a character string that is its printable (aka "human readable") 53146283Sdfr * name. 53246283Sdfr */ 53346283Sdfrstatic char * 53446283Sdfrget_printable_name_of_process_state (process_state) 53546283Sdfr process_state_t process_state; 53646283Sdfr{ 53746283Sdfr switch (process_state) { 53846283Sdfr case STOPPED: 53946283Sdfr return "STOPPED"; 54046283Sdfr case FAKE_STEPPING: 54146283Sdfr return "FAKE_STEPPING"; 54246283Sdfr case RUNNING: 54346283Sdfr return "RUNNING"; 54446283Sdfr case FORKING: 54546283Sdfr return "FORKING"; 54646283Sdfr case VFORKING: 54746283Sdfr return "VFORKING"; 54846283Sdfr default: 54946283Sdfr return "?some unknown state?"; 55046283Sdfr } 55146283Sdfr} 55246283Sdfr 55346283Sdfr/* Set a ttrace thread state to a safe, initial state. 55446283Sdfr */ 55546283Sdfrstatic void 55646283Sdfrclear_ttstate_t (tts) 55746283Sdfr ttstate_t * tts; 55846283Sdfr{ 55946283Sdfr tts->tts_pid = 0; 56046283Sdfr tts->tts_lwpid = 0; 56146283Sdfr tts->tts_user_tid = 0; 56246283Sdfr tts->tts_event = TTEVT_NONE; 56346283Sdfr} 56446283Sdfr 56546283Sdfr/* Copy ttrace thread state TTS_FROM into TTS_TO. 56646283Sdfr */ 56746283Sdfrstatic void 56846283Sdfrcopy_ttstate_t (tts_to, tts_from) 56946283Sdfr ttstate_t * tts_to; 57046283Sdfr ttstate_t * tts_from; 57146283Sdfr{ 57246283Sdfr memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to)); 57346283Sdfr} 57446283Sdfr 57546283Sdfr/* Are there any live threads we know about? 57646283Sdfr */ 57746283Sdfrstatic int 57846283Sdfrany_thread_records() 57946283Sdfr{ 58046283Sdfr return( thread_head.count > 0 ); 58146283Sdfr} 58246283Sdfr 58346283Sdfr/* Create, fill in and link in a thread descriptor. 58446283Sdfr */ 58546283Sdfrstatic thread_info * 58646283Sdfrcreate_thread_info (pid, tid) 58746283Sdfr int pid; 58846283Sdfr lwpid_t tid; 58946283Sdfr{ 59046283Sdfr thread_info * new_p; 59146283Sdfr thread_info * p; 59246283Sdfr int thread_count_of_pid; 59346283Sdfr 59446283Sdfr new_p = malloc( sizeof( thread_info )); 59546283Sdfr new_p->pid = pid; 59646283Sdfr new_p->tid = tid; 59746283Sdfr new_p->have_signal = 0; 59846283Sdfr new_p->have_start = 0; 59946283Sdfr new_p->have_state = 0; 60046283Sdfr clear_ttstate_t( &new_p->last_stop_state ); 60146283Sdfr new_p->am_pseudo = 0; 60246283Sdfr new_p->handled = 0; 60346283Sdfr new_p->seen = 0; 60446283Sdfr new_p->terminated = 0; 60546283Sdfr new_p->next = NULL; 60646283Sdfr new_p->next_pseudo = NULL; 60746283Sdfr new_p->stepping_mode = DO_DEFAULT; 60846283Sdfr 60946283Sdfr if( 0 == thread_head.count ) { 61046283Sdfr#ifdef THREAD_DEBUG 61146283Sdfr if( debug_on ) 61246283Sdfr printf( "First thread, pid %d tid %d!\n", pid, tid ); 61346283Sdfr#endif 61446283Sdfr saved_real_pid = inferior_pid; 61546283Sdfr } 61646283Sdfr else { 61746283Sdfr#ifdef THREAD_DEBUG 61846283Sdfr if( debug_on ) 61946283Sdfr printf( "Subsequent thread, pid %d tid %d\n", pid, tid ); 62046283Sdfr#endif 62146283Sdfr } 62246283Sdfr 62346283Sdfr /* Another day, another thread... 62446283Sdfr */ 62546283Sdfr thread_head.count++; 62646283Sdfr 62746283Sdfr /* The new thread always goes at the head of the list. 62846283Sdfr */ 62946283Sdfr new_p->next = thread_head.head; 63046283Sdfr thread_head.head = new_p; 63146283Sdfr 63246283Sdfr /* Is this the "pseudo" thread of a process? It is if there's 63346283Sdfr * no other thread for this process on the list. (Note that this 63446283Sdfr * accomodates multiple processes, such as we see even for simple 63546283Sdfr * cases like forking "non-threaded" programs.) 63646283Sdfr */ 63746283Sdfr p = thread_head.head; 63846283Sdfr thread_count_of_pid = 0; 63946283Sdfr while (p) 64046283Sdfr { 64146283Sdfr if (p->pid == new_p->pid) 64246283Sdfr thread_count_of_pid++; 64346283Sdfr p = p->next; 64446283Sdfr } 64546283Sdfr 64646283Sdfr /* Did we see any other threads for this pid? (Recall that we just 64746283Sdfr * added this thread to the list...) 64846283Sdfr */ 64946283Sdfr if (thread_count_of_pid == 1) 65046283Sdfr { 65146283Sdfr new_p->am_pseudo = 1; 65246283Sdfr new_p->next_pseudo = thread_head.head_pseudo; 65346283Sdfr thread_head.head_pseudo = new_p; 65446283Sdfr } 65546283Sdfr 65646283Sdfr return new_p; 65746283Sdfr} 65846283Sdfr 65946283Sdfr/* Get rid of our thread info. 66046283Sdfr */ 66146283Sdfrstatic void 66246283Sdfrclear_thread_info () 66346283Sdfr{ 66446283Sdfr thread_info *p; 66546283Sdfr thread_info *q; 66646283Sdfr 66746283Sdfr#ifdef THREAD_DEBUG 66846283Sdfr if( debug_on ) 66946283Sdfr printf( "Clearing all thread info\n" ); 67046283Sdfr#endif 67146283Sdfr 67246283Sdfr p = thread_head.head; 67346283Sdfr while( p ) { 67446283Sdfr q = p; 67546283Sdfr p = p->next; 67646283Sdfr free( q ); 67746283Sdfr } 67846283Sdfr 67946283Sdfr thread_head.head = NULL; 68046283Sdfr thread_head.head_pseudo = NULL; 68146283Sdfr thread_head.count = 0; 68246283Sdfr 68346283Sdfr p = deleted_threads.head; 68446283Sdfr while( p ) { 68546283Sdfr q = p; 68646283Sdfr p = p->next; 68746283Sdfr free( q ); 68846283Sdfr } 68946283Sdfr 69046283Sdfr deleted_threads.head = NULL; 69146283Sdfr deleted_threads.head_pseudo = NULL; 69246283Sdfr deleted_threads.count = 0; 69346283Sdfr 69446283Sdfr /* No threads, so can't have pending events. 69546283Sdfr */ 69646283Sdfr more_events_left = 0; 69746283Sdfr} 69846283Sdfr 69946283Sdfr/* Given a tid, find the thread block for it. 70046283Sdfr */ 70146283Sdfrstatic thread_info * 70246283Sdfrfind_thread_info (tid) 70346283Sdfr lwpid_t tid; 70446283Sdfr{ 70546283Sdfr thread_info *p; 70646283Sdfr 70746283Sdfr for( p = thread_head.head; p; p = p->next ) { 70846283Sdfr if( p->tid == tid ) { 70946283Sdfr return p; 71046283Sdfr } 71146283Sdfr } 71246283Sdfr 71346283Sdfr for( p = deleted_threads.head; p; p = p->next ) { 71446283Sdfr if( p->tid == tid ) { 71546283Sdfr return p; 71646283Sdfr } 71746283Sdfr } 71846283Sdfr 71946283Sdfr return NULL; 72046283Sdfr} 72146283Sdfr 72246283Sdfr/* For any but the pseudo thread, this maps to the 72346283Sdfr * thread ID. For the pseudo thread, if you pass either 72446283Sdfr * the thread id or the PID, you get the pseudo thread ID. 72546283Sdfr * 72646283Sdfr * We have to be prepared for core gdb to ask about 72746283Sdfr * deleted threads. We do the map, but we don't like it. 72846283Sdfr */ 72946283Sdfrstatic lwpid_t 73046283Sdfrmap_from_gdb_tid( gdb_tid ) 73146283Sdfr lwpid_t gdb_tid; 73246283Sdfr{ 73346283Sdfr thread_info *p; 73446283Sdfr 73546283Sdfr /* First assume gdb_tid really is a tid, and try to find a 73646283Sdfr * matching entry on the threads list. 73746283Sdfr */ 73846283Sdfr for( p = thread_head.head; p; p = p->next ) { 73946283Sdfr if( p->tid == gdb_tid ) 74046283Sdfr return gdb_tid; 74146283Sdfr } 74246283Sdfr 74346283Sdfr /* It doesn't appear to be a tid; perhaps it's really a pid? 74446283Sdfr * Try to find a "pseudo" thread entry on the threads list. 74546283Sdfr */ 74646283Sdfr for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo) 74746283Sdfr { 74846283Sdfr if (p->pid == gdb_tid) 74946283Sdfr return p->tid; 75046283Sdfr } 75146283Sdfr 75246283Sdfr /* Perhaps it's the tid of a deleted thread we may still 75346283Sdfr * have some knowledge of? 75446283Sdfr */ 75546283Sdfr for( p = deleted_threads.head; p; p = p-> next ) { 75646283Sdfr if( p->tid == gdb_tid ) 75746283Sdfr return gdb_tid; 75846283Sdfr } 75946283Sdfr 76046283Sdfr /* Or perhaps it's the pid of a deleted process we may still 76146283Sdfr * have knowledge of? 76246283Sdfr */ 76346283Sdfr for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo) 76446283Sdfr { 76546283Sdfr if (p->pid == gdb_tid) 76646283Sdfr return p->tid; 76746283Sdfr } 76846283Sdfr 76946283Sdfr return 0; /* Error? */ 77046283Sdfr} 77146283Sdfr 77246283Sdfr/* Map the other way: from a real tid to the 77346283Sdfr * "pid" known by core gdb. This tid may be 77446283Sdfr * for a thread that just got deleted, so we 77546283Sdfr * also need to consider deleted threads. 77646283Sdfr */ 77746283Sdfrstatic lwpid_t 77846283Sdfrmap_to_gdb_tid( real_tid ) 77946283Sdfr lwpid_t real_tid; 78046283Sdfr{ 78146283Sdfr thread_info *p; 78246283Sdfr 78346283Sdfr for( p = thread_head.head; p; p = p->next ) { 78446283Sdfr if( p->tid == real_tid ) { 78546283Sdfr if( p->am_pseudo ) 78646283Sdfr return p->pid; 78746283Sdfr else 78846283Sdfr return real_tid; 78946283Sdfr } 79046283Sdfr } 79146283Sdfr 79246283Sdfr for( p = deleted_threads.head; p; p = p-> next ) { 79346283Sdfr if( p->tid == real_tid ) 79446283Sdfr if( p->am_pseudo ) 79546283Sdfr return p->pid; /* Error? */ 79646283Sdfr else 79746283Sdfr return real_tid; 79846283Sdfr } 79946283Sdfr 80046283Sdfr return 0; /* Error? Never heard of this thread! */ 80146283Sdfr} 80246283Sdfr 80346283Sdfr/* Do any threads have saved signals? 80446283Sdfr */ 80546283Sdfrstatic int 80646283Sdfrsaved_signals_exist () 80746283Sdfr{ 80846283Sdfr thread_info *p; 80946283Sdfr 81046283Sdfr for( p = thread_head.head; p; p = p->next ) { 81146283Sdfr if( p->have_signal ) { 81246283Sdfr return 1; 81346283Sdfr } 81446283Sdfr } 81546283Sdfr 81646283Sdfr return 0; 81746283Sdfr} 81846283Sdfr 81946283Sdfr/* Is this the tid for the zero-th thread? 82046283Sdfr */ 82146283Sdfrstatic int 82246283Sdfris_pseudo_thread (tid) 82346283Sdfr lwpid_t tid; 82446283Sdfr{ 82546283Sdfr thread_info *p = find_thread_info( tid ); 82646283Sdfr if( NULL == p || p->terminated ) 82746283Sdfr return 0; 82846283Sdfr else 82946283Sdfr return p->am_pseudo; 83046283Sdfr} 83146283Sdfr 83246283Sdfr/* Is this thread terminated? 83346283Sdfr */ 83446283Sdfrstatic int 83546283Sdfris_terminated (tid) 83646283Sdfr lwpid_t tid; 83746283Sdfr{ 83846283Sdfr thread_info *p = find_thread_info( tid ); 83946283Sdfr 84046283Sdfr if( NULL != p ) 84146283Sdfr return p->terminated; 84246283Sdfr 84346283Sdfr return 0; 84446283Sdfr} 84546283Sdfr 84646283Sdfr/* Is this pid a real PID or a TID? 84746283Sdfr */ 84846283Sdfrstatic int 84946283Sdfris_process_id (pid) 85046283Sdfr int pid; 85146283Sdfr{ 85246283Sdfr lwpid_t tid; 85346283Sdfr thread_info * tinfo; 85446283Sdfr pid_t this_pid; 85546283Sdfr int this_pid_count; 85646283Sdfr 85746283Sdfr /* What does PID really represent? 85846283Sdfr */ 85946283Sdfr tid = map_from_gdb_tid (pid); 86046283Sdfr if (tid <= 0) 86146283Sdfr return 0; /* Actually, is probably an error... */ 86246283Sdfr 86346283Sdfr tinfo = find_thread_info (tid); 86446283Sdfr 86546283Sdfr /* Does it appear to be a true thread? 86646283Sdfr */ 86746283Sdfr if (! tinfo->am_pseudo) 86846283Sdfr return 0; 86946283Sdfr 87046283Sdfr /* Else, it looks like it may be a process. See if there's any other 87146283Sdfr * threads with the same process ID, though. If there are, then TID 87246283Sdfr * just happens to be the first thread of several for this process. 87346283Sdfr */ 87446283Sdfr this_pid = tinfo->pid; 87546283Sdfr this_pid_count = 0; 87646283Sdfr for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next) 87746283Sdfr { 87846283Sdfr if (tinfo->pid == this_pid) 87946283Sdfr this_pid_count++; 88046283Sdfr } 88146283Sdfr 88246283Sdfr return (this_pid_count == 1); 88346283Sdfr} 88446283Sdfr 88546283Sdfr 88646283Sdfr/* Add a thread to our info. Prevent duplicate entries. 88746283Sdfr */ 88846283Sdfrstatic thread_info * 88946283Sdfradd_tthread (pid, tid) 89046283Sdfr int pid; 89146283Sdfr lwpid_t tid; 89246283Sdfr{ 89346283Sdfr thread_info *p; 89446283Sdfr 89546283Sdfr p = find_thread_info( tid ); 89646283Sdfr if( NULL == p ) 89746283Sdfr p = create_thread_info( pid, tid ); 89846283Sdfr 89946283Sdfr return p; 90046283Sdfr} 90146283Sdfr 90246283Sdfr/* Notice that a thread was deleted. 90346283Sdfr */ 90446283Sdfrstatic void 90546283Sdfrdel_tthread (tid) 90646283Sdfr lwpid_t tid; 90746283Sdfr{ 90846283Sdfr thread_info *p; 90946283Sdfr thread_info *chase; 91046283Sdfr 91146283Sdfr if( thread_head.count <= 0 ) { 91246283Sdfr error( "Internal error in thread database." ); 91346283Sdfr return; 91446283Sdfr } 91546283Sdfr 91646283Sdfr chase = NULL; 91746283Sdfr for( p = thread_head.head; p; p = p->next ) { 91846283Sdfr if( p->tid == tid ) { 91946283Sdfr 92046283Sdfr#ifdef THREAD_DEBUG 92146283Sdfr if( debug_on ) 92246283Sdfr printf( "Delete here: %d \n", tid ); 92346283Sdfr#endif 92446283Sdfr 92546283Sdfr if( p->am_pseudo ) { 92646283Sdfr /* 92746283Sdfr * Deleting a main thread is ok if we're doing 92846283Sdfr * a parent-follow on a child; this is odd but 92946283Sdfr * not wrong. It apparently _doesn't_ happen 93046283Sdfr * on the child-follow, as we don't just delete 93146283Sdfr * the pseudo while keeping the rest of the 93246283Sdfr * threads around--instead, we clear out the whole 93346283Sdfr * thread list at once. 93446283Sdfr */ 93546283Sdfr thread_info *q; 93646283Sdfr thread_info *q_chase; 93746283Sdfr 93846283Sdfr q_chase = NULL; 93946283Sdfr for( q = thread_head.head_pseudo; q; q = q -> next ) { 94046283Sdfr if( q == p ) { 94146283Sdfr /* Remove from pseudo list. 94246283Sdfr */ 94346283Sdfr if( q_chase == NULL ) 94446283Sdfr thread_head.head_pseudo = p->next_pseudo; 94546283Sdfr else 94646283Sdfr q_chase-> next = p->next_pseudo; 94746283Sdfr } 94846283Sdfr else 94946283Sdfr q_chase = q; 95046283Sdfr } 95146283Sdfr } 95246283Sdfr 95346283Sdfr /* Remove from live list. 95446283Sdfr */ 95546283Sdfr thread_head.count--; 95646283Sdfr 95746283Sdfr if( NULL == chase ) 95846283Sdfr thread_head.head = p->next; 95946283Sdfr else 96046283Sdfr chase->next = p->next; 96146283Sdfr 96246283Sdfr /* Add to deleted thread list. 96346283Sdfr */ 96446283Sdfr p->next = deleted_threads.head; 96546283Sdfr deleted_threads.head = p; 96646283Sdfr deleted_threads.count++; 96746283Sdfr if( p->am_pseudo ) { 96846283Sdfr p->next_pseudo = deleted_threads.head_pseudo; 96946283Sdfr deleted_threads.head_pseudo = p; 97046283Sdfr } 97146283Sdfr p->terminated = 1; 97246283Sdfr 97346283Sdfr return; 97446283Sdfr } 97546283Sdfr 97646283Sdfr else 97746283Sdfr chase = p; 97846283Sdfr } 97946283Sdfr} 98046283Sdfr 98146283Sdfr/* Get the pid for this tid. (Has to be a real TID!). 98246283Sdfr */ 98346283Sdfrstatic int 98446283Sdfrget_pid_for (tid) 98546283Sdfr lwpid_t tid; 98646283Sdfr{ 98746283Sdfr thread_info *p; 98846283Sdfr 98946283Sdfr for( p = thread_head.head; p; p = p->next ) { 99046283Sdfr if( p->tid == tid ) { 99146283Sdfr return p->pid; 99246283Sdfr } 99346283Sdfr } 99446283Sdfr 99546283Sdfr for( p = deleted_threads.head; p; p = p->next ) { 99646283Sdfr if( p->tid == tid ) { 99746283Sdfr return p->pid; 99846283Sdfr } 99946283Sdfr } 100046283Sdfr 100146283Sdfr return 0; 100246283Sdfr} 100346283Sdfr 100446283Sdfr/* Note that this thread's current event has been handled. 100546283Sdfr */ 100646283Sdfrstatic void 100746283Sdfrset_handled( pid, tid ) 100846283Sdfr int pid; 100946283Sdfr lwpid_t tid; 101046283Sdfr{ 101146283Sdfr thread_info *p; 101246283Sdfr 101346283Sdfr p = find_thread_info( tid ); 101446283Sdfr if( NULL == p ) 101546283Sdfr p = add_tthread( pid, tid ); 101646283Sdfr 101746283Sdfr p->handled = 1; 101846283Sdfr} 101946283Sdfr 102046283Sdfr/* Was this thread's current event handled? 102146283Sdfr */ 102246283Sdfrstatic int 102346283Sdfrwas_handled( tid ) 102446283Sdfr lwpid_t tid; 102546283Sdfr{ 102646283Sdfr thread_info *p; 102746283Sdfr 102846283Sdfr p = find_thread_info( tid ); 102946283Sdfr if( NULL != p ) 103046283Sdfr return p->handled; 103146283Sdfr 103246283Sdfr return 0; /* New threads have not been handled */ 103346283Sdfr} 103446283Sdfr 103546283Sdfr/* Set this thread to unhandled. 103646283Sdfr */ 103746283Sdfrstatic void 103846283Sdfrclear_handled( tid ) 103946283Sdfr lwpid_t tid; 104046283Sdfr{ 104146283Sdfr thread_info * p; 104246283Sdfr 104346283Sdfr#ifdef WAIT_BUFFER_DEBUG 104446283Sdfr if( debug_on ) 104546283Sdfr printf( "clear_handled %d\n", (int) tid ); 104646283Sdfr#endif 104746283Sdfr 104846283Sdfr p = find_thread_info (tid); 104946283Sdfr if (p == NULL) 105046283Sdfr error ("Internal error: No thread state to clear?"); 105146283Sdfr 105246283Sdfr p->handled = 0; 105346283Sdfr} 105446283Sdfr 105546283Sdfr/* Set all threads to unhandled. 105646283Sdfr */ 105746283Sdfrstatic void 105846283Sdfrclear_all_handled () 105946283Sdfr{ 106046283Sdfr thread_info *p; 106146283Sdfr 106246283Sdfr#ifdef WAIT_BUFFER_DEBUG 106346283Sdfr if( debug_on ) 106446283Sdfr printf( "clear_all_handled\n" ); 106546283Sdfr#endif 106646283Sdfr 106746283Sdfr for( p = thread_head.head; p; p = p->next ) { 106846283Sdfr p->handled = 0; 106946283Sdfr } 107046283Sdfr 107146283Sdfr for( p = deleted_threads.head; p; p = p->next ) { 107246283Sdfr p->handled = 0; 107346283Sdfr } 107446283Sdfr} 107546283Sdfr 107646283Sdfr/* Set this thread to default stepping mode. 107746283Sdfr */ 107846283Sdfrstatic void 107946283Sdfrclear_stepping_mode( tid ) 108046283Sdfr lwpid_t tid; 108146283Sdfr{ 108246283Sdfr thread_info * p; 108346283Sdfr 108446283Sdfr#ifdef WAIT_BUFFER_DEBUG 108546283Sdfr if( debug_on ) 108646283Sdfr printf( "clear_stepping_mode %d\n", (int) tid ); 108746283Sdfr#endif 108846283Sdfr 108946283Sdfr p = find_thread_info (tid); 109046283Sdfr if (p == NULL) 109146283Sdfr error ("Internal error: No thread state to clear?"); 109246283Sdfr 109346283Sdfr p->stepping_mode = DO_DEFAULT; 109446283Sdfr} 109546283Sdfr 109646283Sdfr/* Set all threads to do default continue on resume. 109746283Sdfr */ 109846283Sdfrstatic void 109946283Sdfrclear_all_stepping_mode () 110046283Sdfr{ 110146283Sdfr thread_info *p; 110246283Sdfr 110346283Sdfr#ifdef WAIT_BUFFER_DEBUG 110446283Sdfr if( debug_on ) 110546283Sdfr printf( "clear_all_stepping_mode\n" ); 110646283Sdfr#endif 110746283Sdfr 110846283Sdfr for( p = thread_head.head; p; p = p->next ) { 110946283Sdfr p->stepping_mode = DO_DEFAULT; 111046283Sdfr } 111146283Sdfr 111246283Sdfr for( p = deleted_threads.head; p; p = p->next ) { 111346283Sdfr p->stepping_mode = DO_DEFAULT; 111446283Sdfr } 111546283Sdfr} 111646283Sdfr 111746283Sdfr/* Set all threads to unseen on this pass. 111846283Sdfr */ 111946283Sdfrstatic void 112046283Sdfrset_all_unseen () 112146283Sdfr{ 112246283Sdfr thread_info *p; 112346283Sdfr 112446283Sdfr for( p = thread_head.head; p; p = p->next ) { 112546283Sdfr p->seen = 0; 112646283Sdfr } 112746283Sdfr} 112846283Sdfr 112946283Sdfr#if (defined( THREAD_DEBUG ) || defined( PARANOIA )) 113046283Sdfr/* debugging routine. 113146283Sdfr */ 113246283Sdfrstatic void 113346283Sdfrprint_tthread (p) 113446283Sdfr thread_info * p; 113546283Sdfr{ 113646283Sdfr printf( " Thread pid %d, tid %d", p->pid, p->tid ); 113746283Sdfr if( p->have_state ) 113846283Sdfr printf( ", event is %s", 113946283Sdfr get_printable_name_of_ttrace_event( p->last_stop_state.tts_event )); 114046283Sdfr 114146283Sdfr if( p->am_pseudo ) 114246283Sdfr printf( ", pseudo thread" ); 114346283Sdfr 114446283Sdfr if( p->have_signal ) 114546283Sdfr printf( ", have signal 0x%x", p->signal_value ); 114646283Sdfr 114746283Sdfr if( p->have_start ) 114846283Sdfr printf( ", have start at 0x%x", p->start ); 114946283Sdfr 115046283Sdfr printf( ", step is %s", get_printable_name_of_stepping_mode( p->stepping_mode )); 115146283Sdfr 115246283Sdfr if( p->handled ) 115346283Sdfr printf( ", handled" ); 115446283Sdfr else 115546283Sdfr printf( ", not handled" ); 115646283Sdfr 115746283Sdfr if( p->seen ) 115846283Sdfr printf( ", seen" ); 115946283Sdfr else 116046283Sdfr printf( ", not seen" ); 116146283Sdfr 116246283Sdfr printf( "\n" ); 116346283Sdfr} 116446283Sdfr 116546283Sdfrstatic void 116646283Sdfrprint_tthreads () 116746283Sdfr{ 116846283Sdfr thread_info *p; 116946283Sdfr 117046283Sdfr if( thread_head.count == 0 ) 117146283Sdfr printf( "Thread list is empty\n" ); 117246283Sdfr else { 117346283Sdfr printf( "Thread list has " ); 117446283Sdfr if( thread_head.count == 1 ) 117546283Sdfr printf( "1 entry:\n" ); 117646283Sdfr else 117746283Sdfr printf( "%d entries:\n", thread_head.count ); 117846283Sdfr for( p = thread_head.head; p; p = p->next ) { 117946283Sdfr print_tthread (p); 118046283Sdfr } 118146283Sdfr } 118246283Sdfr 118346283Sdfr if( deleted_threads.count == 0 ) 118446283Sdfr printf( "Deleted thread list is empty\n" ); 118546283Sdfr else { 118646283Sdfr printf( "Deleted thread list has " ); 118746283Sdfr if( deleted_threads.count == 1 ) 118846283Sdfr printf( "1 entry:\n" ); 118946283Sdfr else 119046283Sdfr printf( "%d entries:\n", deleted_threads.count ); 119146283Sdfr 119246283Sdfr for( p = deleted_threads.head; p; p = p->next ) { 119346283Sdfr print_tthread (p); 119446283Sdfr } 119546283Sdfr } 119646283Sdfr} 119746283Sdfr#endif 119846283Sdfr 119946283Sdfr/* Update the thread list based on the "seen" bits. 120046283Sdfr */ 120146283Sdfrstatic void 120246283Sdfrupdate_thread_list () 120346283Sdfr{ 120446283Sdfr thread_info *p; 120546283Sdfr thread_info *chase; 120646283Sdfr 120746283Sdfr chase = NULL; 120846283Sdfr for( p = thread_head.head; p; p = p->next ) { 120946283Sdfr /* Is this an "unseen" thread which really happens to be a process? 121046283Sdfr If so, is it inferior_pid and is a vfork in flight? If yes to 121146283Sdfr all, then DON'T REMOVE IT! We're in the midst of moving a vfork 121246283Sdfr operation, which is a multiple step thing, to the point where we 121346283Sdfr can touch the parent again. We've most likely stopped to examine 121446283Sdfr the child at a late stage in the vfork, and if we're not following 121546283Sdfr the child, we'd best not treat the parent as a dead "thread"... 121646283Sdfr */ 121746283Sdfr if( (!p->seen) && p->am_pseudo && vfork_in_flight 121846283Sdfr && (p->pid != vforking_child_pid)) 121946283Sdfr p->seen = 1; 122046283Sdfr 122146283Sdfr if( !p->seen ) { 122246283Sdfr /* Remove this one 122346283Sdfr */ 122446283Sdfr 122546283Sdfr#ifdef THREAD_DEBUG 122646283Sdfr if( debug_on ) 122746283Sdfr printf( "Delete unseen thread: %d \n", p->tid ); 122846283Sdfr#endif 122946283Sdfr del_tthread( p->tid ); 123046283Sdfr } 123146283Sdfr } 123246283Sdfr} 123346283Sdfr 123446283Sdfr 123546283Sdfr 123646283Sdfr/************************************************ 123746283Sdfr * O/S call wrappers * 123846283Sdfr ************************************************ 123946283Sdfr */ 124046283Sdfr 124146283Sdfr/* This function simply calls ttrace with the given arguments. 124246283Sdfr * It exists so that all calls to ttrace are isolated. All 124346283Sdfr * parameters should be as specified by "man 2 ttrace". 124446283Sdfr * 124546283Sdfr * No other "raw" calls to ttrace should exist in this module. 124646283Sdfr */ 124746283Sdfrstatic int 124846283Sdfrcall_real_ttrace( request, pid, tid, addr, data, addr2 ) 124946283Sdfr ttreq_t request; 125046283Sdfr pid_t pid; 125146283Sdfr lwpid_t tid; 125246283Sdfr TTRACE_ARG_TYPE addr, data, addr2; 125346283Sdfr{ 125446283Sdfr int tt_status; 125546283Sdfr 125646283Sdfr errno = 0; 125746283Sdfr tt_status = ttrace( request, pid, tid, addr, data, addr2 ); 125846283Sdfr 125946283Sdfr#ifdef THREAD_DEBUG 126046283Sdfr if (errno) { 126146283Sdfr /* Don't bother for a known benign error: if you ask for the 126246283Sdfr * first thread state, but there is only one thread and it's 126346283Sdfr * not stopped, ttrace complains. 126446283Sdfr * 126546283Sdfr * We have this inside the #ifdef because our caller will do 126646283Sdfr * this check for real. 126746283Sdfr */ 126846283Sdfr if( request != TT_PROC_GET_FIRST_LWP_STATE 126946283Sdfr || errno != EPROTO ) { 127046283Sdfr if( debug_on ) 127146283Sdfr printf( "TT fail for %s, with pid %d, tid %d, status %d \n", 127246283Sdfr get_printable_name_of_ttrace_request (request), 127346283Sdfr pid, tid, tt_status ); 127446283Sdfr } 127546283Sdfr } 127646283Sdfr#endif 127746283Sdfr 127846283Sdfr#if 0 127946283Sdfr /* ??rehrauer: It would probably be most robust to catch and report 128046283Sdfr * failed requests here. However, some clients of this interface 128146283Sdfr * seem to expect to catch & deal with them, so we'd best not. 128246283Sdfr */ 128346283Sdfr if (errno) { 128446283Sdfr strcpy (reason_for_failure, "ttrace ("); 128546283Sdfr strcat (reason_for_failure, get_printable_name_of_ttrace_request (request)); 128646283Sdfr strcat (reason_for_failure, ")"); 128746283Sdfr printf( "ttrace error, errno = %d\n", errno ); 128846283Sdfr perror_with_name (reason_for_failure); 128946283Sdfr } 129046283Sdfr#endif 129146283Sdfr 129246283Sdfr return tt_status; 129346283Sdfr} 129446283Sdfr 129546283Sdfr 129646283Sdfr/* This function simply calls ttrace_wait with the given arguments. 129746283Sdfr * It exists so that all calls to ttrace_wait are isolated. 129846283Sdfr * 129946283Sdfr * No "raw" calls to ttrace_wait should exist elsewhere. 130046283Sdfr */ 130146283Sdfrstatic int 130246283Sdfrcall_real_ttrace_wait( pid, tid, option, tsp, tsp_size ) 130346283Sdfr int pid; 130446283Sdfr lwpid_t tid; 130546283Sdfr ttwopt_t option; 130646283Sdfr ttstate_t *tsp; 130746283Sdfr size_t tsp_size; 130846283Sdfr{ 130946283Sdfr int ttw_status; 131046283Sdfr thread_info * tinfo = NULL; 131146283Sdfr 131246283Sdfr errno = 0; 131346283Sdfr ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size); 131446283Sdfr 131546283Sdfr if (errno) { 131646283Sdfr#ifdef THREAD_DEBUG 131746283Sdfr if( debug_on ) 131846283Sdfr printf( "TW fail with pid %d, tid %d \n", pid, tid ); 131946283Sdfr#endif 132046283Sdfr 132146283Sdfr perror_with_name ("ttrace wait"); 132246283Sdfr } 132346283Sdfr 132446283Sdfr return ttw_status; 132546283Sdfr} 132646283Sdfr 132746283Sdfr 132846283Sdfr/* A process may have one or more kernel threads, of which all or 132946283Sdfr none may be stopped. This function returns the ID of the first 133046283Sdfr kernel thread in a stopped state, or 0 if none are stopped. 133146283Sdfr 133246283Sdfr This function can be used with get_process_next_stopped_thread_id 133346283Sdfr to iterate over the IDs of all stopped threads of this process. 133446283Sdfr */ 133546283Sdfrstatic lwpid_t 133646283Sdfrget_process_first_stopped_thread_id (pid, thread_state) 133746283Sdfr int pid; 133846283Sdfr ttstate_t * thread_state; 133946283Sdfr{ 134046283Sdfr int tt_status; 134146283Sdfr 134246283Sdfr tt_status = call_real_ttrace ( 134346283Sdfr TT_PROC_GET_FIRST_LWP_STATE, 134446283Sdfr (pid_t) pid, 134546283Sdfr (lwpid_t) TT_NIL, 134646283Sdfr (TTRACE_ARG_TYPE) thread_state, 134746283Sdfr (TTRACE_ARG_TYPE) sizeof (*thread_state), 134846283Sdfr TT_NIL); 134946283Sdfr 135046283Sdfr if (errno) { 135146283Sdfr if( errno == EPROTO) { 135246283Sdfr /* This is an error we can handle: there isn't any stopped 135346283Sdfr * thread. This happens when we're re-starting the application 135446283Sdfr * and it has only one thread. GET_NEXT handles the case of 135546283Sdfr * no more stopped threads well; GET_FIRST doesn't. (A ttrace 135646283Sdfr * "feature".) 135746283Sdfr */ 135846283Sdfr tt_status = 1; 135946283Sdfr errno = 0; 136046283Sdfr return 0; 136146283Sdfr } 136246283Sdfr else 136346283Sdfr perror_with_name ("ttrace"); 136446283Sdfr } 136546283Sdfr 136646283Sdfr if( tt_status < 0 ) 136746283Sdfr /* Failed somehow. 136846283Sdfr */ 136946283Sdfr return 0; 137046283Sdfr 137146283Sdfr return thread_state->tts_lwpid; 137246283Sdfr} 137346283Sdfr 137446283Sdfr 137546283Sdfr/* This function returns the ID of the "next" kernel thread in a 137646283Sdfr stopped state, or 0 if there are none. "Next" refers to the 137746283Sdfr thread following that of the last successful call to this 137846283Sdfr function or to get_process_first_stopped_thread_id, using 137946283Sdfr the value of thread_state returned by that call. 138046283Sdfr 138146283Sdfr This function can be used with get_process_first_stopped_thread_id 138246283Sdfr to iterate over the IDs of all stopped threads of this process. 138346283Sdfr */ 138446283Sdfrstatic lwpid_t 138546283Sdfrget_process_next_stopped_thread_id (pid, thread_state) 138646283Sdfr int pid; 138746283Sdfr ttstate_t * thread_state; 138846283Sdfr{ 138946283Sdfr int tt_status; 139046283Sdfr 139146283Sdfr tt_status = call_real_ttrace ( 139246283Sdfr TT_PROC_GET_NEXT_LWP_STATE, 139346283Sdfr (pid_t) pid, 139446283Sdfr (lwpid_t) TT_NIL, 139546283Sdfr (TTRACE_ARG_TYPE) thread_state, 139646283Sdfr (TTRACE_ARG_TYPE) sizeof (*thread_state), 139746283Sdfr TT_NIL); 139846283Sdfr if (errno) 139946283Sdfr perror_with_name ("ttrace"); 140046283Sdfr 140146283Sdfr if (tt_status < 0) 140246283Sdfr /* Failed 140346283Sdfr */ 140446283Sdfr return 0; 140546283Sdfr 140646283Sdfr else if( tt_status == 0 ) { 140746283Sdfr /* End of list, no next state. Don't return the 140846283Sdfr * tts_lwpid, as it's a meaningless "240". 140946283Sdfr * 141046283Sdfr * This is an HPUX "feature". 141146283Sdfr */ 141246283Sdfr return 0; 141346283Sdfr } 141446283Sdfr 141546283Sdfr return thread_state->tts_lwpid; 141646283Sdfr} 141746283Sdfr 141846283Sdfr/* ??rehrauer: Eventually this function perhaps should be calling 141946283Sdfr pid_to_thread_id. However, that function currently does nothing 142046283Sdfr for HP-UX. Even then, I'm not clear whether that function 142146283Sdfr will return a "kernel" thread ID, or a "user" thread ID. If 142246283Sdfr the former, we can just call it here. If the latter, we must 142346283Sdfr map from the "user" tid to a "kernel" tid. 142446283Sdfr 142546283Sdfr NOTE: currently not called. 142646283Sdfr */ 142746283Sdfrstatic lwpid_t 142846283Sdfrget_active_tid_of_pid (pid) 142946283Sdfr int pid; 143046283Sdfr{ 143146283Sdfr ttstate_t thread_state; 143246283Sdfr 143346283Sdfr return get_process_first_stopped_thread_id (pid, &thread_state); 143446283Sdfr} 143546283Sdfr 143646283Sdfr/* This function returns 1 if tt_request is a ttrace request that 143746283Sdfr * operates upon all threads of a (i.e., the entire) process. 143846283Sdfr */ 143946283Sdfrint 144046283Sdfris_process_ttrace_request (tt_request) 144146283Sdfr ttreq_t tt_request; 144246283Sdfr{ 144346283Sdfr return IS_TTRACE_PROCREQ (tt_request); 144446283Sdfr} 144546283Sdfr 144646283Sdfr 144746283Sdfr/* This function translates a thread ttrace request into 144846283Sdfr * the equivalent process request for a one-thread process. 144946283Sdfr */ 145046283Sdfrstatic ttreq_t 145146283Sdfrmake_process_version( request ) 145246283Sdfr ttreq_t request; 145346283Sdfr{ 145446283Sdfr if (!IS_TTRACE_REQ (request)) { 145546283Sdfr error( "Internal error, bad ttrace request made\n" ); 145646283Sdfr return -1; 145746283Sdfr } 145846283Sdfr 145946283Sdfr switch (request) { 146046283Sdfr case TT_LWP_STOP : 146146283Sdfr return TT_PROC_STOP; 146246283Sdfr 146346283Sdfr case TT_LWP_CONTINUE : 146446283Sdfr return TT_PROC_CONTINUE; 146546283Sdfr 146646283Sdfr case TT_LWP_GET_EVENT_MASK : 146746283Sdfr return TT_PROC_GET_EVENT_MASK; 146846283Sdfr 146946283Sdfr case TT_LWP_SET_EVENT_MASK : 147046283Sdfr return TT_PROC_SET_EVENT_MASK; 147146283Sdfr 147246283Sdfr case TT_LWP_SINGLE : 147346283Sdfr case TT_LWP_RUREGS : 147446283Sdfr case TT_LWP_WUREGS : 147546283Sdfr case TT_LWP_GET_STATE : 147646283Sdfr return -1; /* No equivalent */ 147746283Sdfr 147846283Sdfr default : 147946283Sdfr return request; 148046283Sdfr } 148146283Sdfr} 148246283Sdfr 148346283Sdfr 148446283Sdfr/* This function translates the "pid" used by the rest of 148546283Sdfr * gdb to a real pid and a tid. It then calls "call_real_ttrace" 148646283Sdfr * with the given arguments. 148746283Sdfr * 148846283Sdfr * In general, other parts of this module should call this 148946283Sdfr * function when they are dealing with external users, who only 149046283Sdfr * have tids to pass (but they call it "pid" for historical 149146283Sdfr * reasons). 149246283Sdfr */ 149346283Sdfrstatic int 149446283Sdfrcall_ttrace( request, gdb_tid, addr, data, addr2 ) 149546283Sdfr ttreq_t request; 149646283Sdfr int gdb_tid; 149746283Sdfr TTRACE_ARG_TYPE addr, data, addr2; 149846283Sdfr{ 149946283Sdfr lwpid_t real_tid; 150046283Sdfr int real_pid; 150146283Sdfr ttreq_t new_request; 150246283Sdfr int tt_status; 150346283Sdfr char reason_for_failure [100]; /* Arbitrary size, should be big enough. */ 150446283Sdfr 150546283Sdfr#ifdef THREAD_DEBUG 150646283Sdfr int is_interesting = 0; 150746283Sdfr 150846283Sdfr if( TT_LWP_RUREGS == request ) { 150946283Sdfr is_interesting = 1; /* Adjust code here as desired */ 151046283Sdfr } 151146283Sdfr 151246283Sdfr if( is_interesting && 0 && debug_on ) { 151346283Sdfr if( !is_process_ttrace_request( request )) { 151446283Sdfr printf( "TT: Thread request, tid is %d", gdb_tid ); 151546283Sdfr printf( "== SINGLE at %x", addr ); 151646283Sdfr } 151746283Sdfr else { 151846283Sdfr printf( "TT: Process request, tid is %d\n", gdb_tid ); 151946283Sdfr printf( "==! SINGLE at %x", addr ); 152046283Sdfr } 152146283Sdfr } 152246283Sdfr#endif 152346283Sdfr 152446283Sdfr /* The initial SETTRC and SET_EVENT_MASK calls (and all others 152546283Sdfr * which happen before any threads get set up) should go 152646283Sdfr * directly to "call_real_ttrace", so they don't happen here. 152746283Sdfr * 152846283Sdfr * But hardware watchpoints do a SET_EVENT_MASK, so we can't 152946283Sdfr * rule them out.... 153046283Sdfr */ 153146283Sdfr#ifdef THREAD_DEBUG 153246283Sdfr if( request == TT_PROC_SETTRC && debug_on ) 153346283Sdfr printf( "Unexpected call for TT_PROC_SETTRC\n" ); 153446283Sdfr#endif 153546283Sdfr 153646283Sdfr /* Sometimes we get called with a bogus tid (e.g., if a 153746283Sdfr * thread has terminated, we return 0; inftarg later asks 153846283Sdfr * whether the thread has exited/forked/vforked). 153946283Sdfr */ 154046283Sdfr if( gdb_tid == 0 ) 154146283Sdfr { 154246283Sdfr errno = ESRCH; /* ttrace's response would probably be "No such process". */ 154346283Sdfr return -1; 154446283Sdfr } 154546283Sdfr 154646283Sdfr /* All other cases should be able to expect that there are 154746283Sdfr * thread records. 154846283Sdfr */ 154946283Sdfr if( !any_thread_records()) { 155046283Sdfr#ifdef THREAD_DEBUG 155146283Sdfr if( debug_on ) 155246283Sdfr warning ("No thread records for ttrace call"); 155346283Sdfr#endif 155446283Sdfr errno = ESRCH; /* ttrace's response would be "No such process". */ 155546283Sdfr return -1; 155646283Sdfr } 155746283Sdfr 155846283Sdfr /* OK, now the task is to translate the incoming tid into 155946283Sdfr * a pid/tid pair. 156046283Sdfr */ 156146283Sdfr real_tid = map_from_gdb_tid( gdb_tid ); 156246283Sdfr real_pid = get_pid_for( real_tid ); 156346283Sdfr 156446283Sdfr /* Now check the result. "Real_pid" is NULL if our list 156546283Sdfr * didn't find it. We have some tricks we can play to fix 156646283Sdfr * this, however. 156746283Sdfr */ 156846283Sdfr if( 0 == real_pid ) { 156946283Sdfr ttstate_t thread_state; 157046283Sdfr 157146283Sdfr#ifdef THREAD_DEBUG 157246283Sdfr if( debug_on ) 157346283Sdfr printf( "No saved pid for tid %d\n", gdb_tid ); 157446283Sdfr#endif 157546283Sdfr 157646283Sdfr if( is_process_ttrace_request( request )) { 157746283Sdfr 157846283Sdfr /* Ok, we couldn't get a tid. Try to translate to 157946283Sdfr * the equivalent process operation. We expect this 158046283Sdfr * NOT to happen, so this is a desparation-type 158146283Sdfr * move. It can happen if there is an internal 158246283Sdfr * error and so no "wait()" call is ever done. 158346283Sdfr */ 158446283Sdfr new_request = make_process_version( request ); 158546283Sdfr if( new_request == -1 ) { 158646283Sdfr 158746283Sdfr#ifdef THREAD_DEBUG 158846283Sdfr if( debug_on ) 158946283Sdfr printf( "...and couldn't make process version of thread operation\n" ); 159046283Sdfr#endif 159146283Sdfr 159246283Sdfr /* Use hacky saved pid, which won't always be correct 159346283Sdfr * in the multi-process future. Use tid as thread, 159446283Sdfr * probably dooming this to failure. FIX! 159546283Sdfr */ 159646283Sdfr if( saved_real_pid != 0 ) { 159746283Sdfr#ifdef THREAD_DEBUG 159846283Sdfr if( debug_on ) 159946283Sdfr printf( "...using saved pid %d\n", saved_real_pid ); 160046283Sdfr#endif 160146283Sdfr 160246283Sdfr real_pid = saved_real_pid; 160346283Sdfr real_tid = gdb_tid; 160446283Sdfr } 160546283Sdfr 160646283Sdfr else 160746283Sdfr error( "Unable to perform thread operation" ); 160846283Sdfr } 160946283Sdfr 161046283Sdfr else { 161146283Sdfr /* Sucessfully translated this to a process request, 161246283Sdfr * which needs no thread value. 161346283Sdfr */ 161446283Sdfr real_pid = gdb_tid; 161546283Sdfr real_tid = 0; 161646283Sdfr request = new_request; 161746283Sdfr 161846283Sdfr#ifdef THREAD_DEBUG 161946283Sdfr if( debug_on ) { 162046283Sdfr printf( "Translated thread request to process request\n" ); 162146283Sdfr if( saved_real_pid == 0 ) 162246283Sdfr printf( "...but there's no saved pid\n" ); 162346283Sdfr 162446283Sdfr else { 162546283Sdfr if( gdb_tid != saved_real_pid ) 162646283Sdfr printf( "...but have the wrong pid (%d rather than %d)\n", 162746283Sdfr gdb_tid, saved_real_pid ); 162846283Sdfr } 162946283Sdfr } 163046283Sdfr#endif 163146283Sdfr } /* Translated to a process request */ 163246283Sdfr } /* Is a process request */ 163346283Sdfr 163446283Sdfr else { 163546283Sdfr /* We have to have a thread. Ooops. 163646283Sdfr */ 163746283Sdfr error( "Thread request with no threads (%s)", 163846283Sdfr get_printable_name_of_ttrace_request( request )); 163946283Sdfr } 164046283Sdfr } 164146283Sdfr 164246283Sdfr /* Ttrace doesn't like to see tid values on process requests, 164346283Sdfr * even if we have the right one. 164446283Sdfr */ 164546283Sdfr if (is_process_ttrace_request (request)) { 164646283Sdfr real_tid = 0; 164746283Sdfr } 164846283Sdfr 164946283Sdfr#ifdef THREAD_DEBUG 165046283Sdfr if( is_interesting && 0 && debug_on ) { 165146283Sdfr printf( " now tid %d, pid %d\n", real_tid, real_pid ); 165246283Sdfr printf( " request is %s\n", get_printable_name_of_ttrace_request (request)); 165346283Sdfr } 165446283Sdfr#endif 165546283Sdfr 165646283Sdfr /* Finally, the (almost) real call. 165746283Sdfr */ 165846283Sdfr tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2); 165946283Sdfr 166046283Sdfr#ifdef THREAD_DEBUG 166146283Sdfr if(is_interesting && debug_on ) { 166246283Sdfr if( !TT_OK( tt_status, errno ) 166346283Sdfr && !(tt_status == 0 & errno == 0)) 166446283Sdfr printf( " got error (errno==%d, status==%d)\n", errno, tt_status ); 166546283Sdfr } 166646283Sdfr#endif 166746283Sdfr 166846283Sdfr return tt_status; 166946283Sdfr} 167046283Sdfr 167146283Sdfr 167246283Sdfr/* Stop all the threads of a process. 167346283Sdfr * 167446283Sdfr * NOTE: use of TT_PROC_STOP can cause a thread with a real event 167546283Sdfr * to get a TTEVT_NONE event, discarding the old event. Be 167646283Sdfr * very careful, and only call TT_PROC_STOP when you mean it! 167746283Sdfr */ 167846283Sdfrstatic void 167946283Sdfrstop_all_threads_of_process( real_pid ) 168046283Sdfr pid_t real_pid; 168146283Sdfr{ 168246283Sdfr int ttw_status; 168346283Sdfr 168446283Sdfr ttw_status = call_real_ttrace (TT_PROC_STOP, 168546283Sdfr (pid_t) real_pid, 168646283Sdfr (lwpid_t) TT_NIL, 168746283Sdfr (TTRACE_ARG_TYPE) TT_NIL, 168846283Sdfr (TTRACE_ARG_TYPE) TT_NIL, 168946283Sdfr TT_NIL ); 169046283Sdfr if (errno) 169146283Sdfr perror_with_name ("ttrace stop of other threads"); 169246283Sdfr} 169346283Sdfr 169446283Sdfr 169546283Sdfr/* Under some circumstances, it's unsafe to attempt to stop, or even 169646283Sdfr query the state of, a process' threads. 169746283Sdfr 169846283Sdfr In ttrace-based HP-UX, an example is a vforking child process. The 169946283Sdfr vforking parent and child are somewhat fragile, w/r/t what we can do 170046283Sdfr what we can do to them with ttrace, until after the child exits or 170146283Sdfr execs, or until the parent's vfork event is delivered. Until that 170246283Sdfr time, we must not try to stop the process' threads, or inquire how 170346283Sdfr many there are, or even alter its data segments, or it typically dies 170446283Sdfr with a SIGILL. Sigh. 170546283Sdfr 170646283Sdfr This function returns 1 if this stopped process, and the event that 170746283Sdfr we're told was responsible for its current stopped state, cannot safely 170846283Sdfr have its threads examined. 170946283Sdfr */ 171046283Sdfr#define CHILD_VFORKED(evt,pid) \ 171146283Sdfr (((evt) == TTEVT_VFORK) && ((pid) != inferior_pid)) 171246283Sdfr#define CHILD_URPED(evt,pid) \ 171346283Sdfr ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid)) 171446283Sdfr#define PARENT_VFORKED(evt,pid) \ 171546283Sdfr (((evt) == TTEVT_VFORK) && ((pid) == inferior_pid)) 171646283Sdfr 171746283Sdfrstatic int 171846283Sdfrcan_touch_threads_of_process (pid, stopping_event) 171946283Sdfr int pid; 172046283Sdfr ttevents_t stopping_event; 172146283Sdfr{ 172246283Sdfr if (CHILD_VFORKED (stopping_event, pid)) 172346283Sdfr { 172446283Sdfr vforking_child_pid = pid; 172546283Sdfr vfork_in_flight = 1; 172646283Sdfr } 172746283Sdfr 172846283Sdfr else if (vfork_in_flight && 172946283Sdfr (PARENT_VFORKED (stopping_event, pid) || 173046283Sdfr CHILD_URPED (stopping_event, pid))) 173146283Sdfr { 173246283Sdfr vfork_in_flight = 0; 173346283Sdfr vforking_child_pid = 0; 173446283Sdfr } 173546283Sdfr 173646283Sdfr return ! vfork_in_flight; 173746283Sdfr} 173846283Sdfr 173946283Sdfr 174046283Sdfr/* If we can find an as-yet-unhandled thread state of a 174146283Sdfr * stopped thread of this process return 1 and set "tsp". 174246283Sdfr * Return 0 if we can't. 174346283Sdfr * 174446283Sdfr * If this function is used when the threads of PIS haven't 174546283Sdfr * been stopped, undefined behaviour is guaranteed! 174646283Sdfr */ 174746283Sdfrstatic int 174846283Sdfrselect_stopped_thread_of_process (pid, tsp) 174946283Sdfr int pid; 175046283Sdfr ttstate_t * tsp; 175146283Sdfr{ 175246283Sdfr lwpid_t candidate_tid, tid; 175346283Sdfr ttstate_t candidate_tstate, tstate; 175446283Sdfr 175546283Sdfr /* If we're not allowed to touch the process now, then just 175646283Sdfr * return the current value of *TSP. 175746283Sdfr * 175846283Sdfr * This supports "vfork". It's ok, really, to double the 175946283Sdfr * current event (the child EXEC, we hope!). 176046283Sdfr */ 176146283Sdfr if (! can_touch_threads_of_process (pid, tsp->tts_event)) 176246283Sdfr return 1; 176346283Sdfr 176446283Sdfr /* Decide which of (possibly more than one) events to 176546283Sdfr * return as the first one. We scan them all so that 176646283Sdfr * we always return the result of a fake-step first. 176746283Sdfr */ 176846283Sdfr candidate_tid = 0; 176946283Sdfr for (tid = get_process_first_stopped_thread_id (pid, &tstate); 177046283Sdfr tid != 0; 177146283Sdfr tid = get_process_next_stopped_thread_id (pid, &tstate)) 177246283Sdfr { 177346283Sdfr /* TTEVT_NONE events are uninteresting to our clients. They're 177446283Sdfr * an artifact of our "stop the world" model--the thread is 177546283Sdfr * stopped because we stopped it. 177646283Sdfr */ 177746283Sdfr if (tstate.tts_event == TTEVT_NONE) { 177846283Sdfr set_handled( pid, tstate.tts_lwpid ); 177946283Sdfr } 178046283Sdfr 178146283Sdfr /* Did we just single-step a single thread, without letting any 178246283Sdfr * of the others run? Is this an event for that thread? 178346283Sdfr * 178446283Sdfr * If so, we believe our client would prefer to see this event 178546283Sdfr * over any others. (Typically the client wants to just push 178646283Sdfr * one thread a little farther forward, and then go around 178746283Sdfr * checking for what all threads are doing.) 178846283Sdfr */ 178946283Sdfr else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid)) 179046283Sdfr { 179146283Sdfr#ifdef WAIT_BUFFER_DEBUG 179246283Sdfr /* It's possible here to see either a SIGTRAP (due to 179346283Sdfr * successful completion of a step) or a SYSCALL_ENTRY 179446283Sdfr * (due to a step completion with active hardware 179546283Sdfr * watchpoints). 179646283Sdfr */ 179746283Sdfr if( debug_on ) 179846283Sdfr printf( "Ending fake step with tid %d, state %s\n", 179946283Sdfr tstate.tts_lwpid, 180046283Sdfr get_printable_name_of_ttrace_event( tstate.tts_event )); 180146283Sdfr#endif 180246283Sdfr 180346283Sdfr /* Remember this one, and throw away any previous 180446283Sdfr * candidate. 180546283Sdfr */ 180646283Sdfr candidate_tid = tstate.tts_lwpid; 180746283Sdfr candidate_tstate = tstate; 180846283Sdfr } 180946283Sdfr 181046283Sdfr#ifdef FORGET_DELETED_BPTS 181146283Sdfr 181246283Sdfr /* We can't just do this, as if we do, and then wind 181346283Sdfr * up the loop with no unhandled events, we need to 181446283Sdfr * handle that case--the appropriate reaction is to 181546283Sdfr * just continue, but there's no easy way to do that. 181646283Sdfr * 181746283Sdfr * Better to put this in the ttrace_wait call--if, when 181846283Sdfr * we fake a wait, we update our events based on the 181946283Sdfr * breakpoint_here_pc call and find there are no more events, 182046283Sdfr * then we better continue and so on. 182146283Sdfr * 182246283Sdfr * Or we could put it in the next/continue fake. 182346283Sdfr * But it has to go in the buffering code, not in the 182446283Sdfr * real go/wait code. 182546283Sdfr */ 182646283Sdfr else if( (TTEVT_SIGNAL == tstate.tts_event) 182746283Sdfr && (5 == tstate.tts_u.tts_signal.tts_signo) 182846283Sdfr && (0 != get_raw_pc( tstate.tts_lwpid )) 182946283Sdfr && ! breakpoint_here_p( get_raw_pc( tstate.tts_lwpid )) ) { 183046283Sdfr /* 183146283Sdfr * If the user deleted a breakpoint while this 183246283Sdfr * breakpoint-hit event was buffered, we can forget 183346283Sdfr * it now. 183446283Sdfr */ 183546283Sdfr#ifdef WAIT_BUFFER_DEBUG 183646283Sdfr if( debug_on ) 183746283Sdfr printf( "Forgetting deleted bp hit for thread %d\n", 183846283Sdfr tstate.tts_lwpid ); 183946283Sdfr#endif 184046283Sdfr 184146283Sdfr set_handled( pid, tstate.tts_lwpid ); 184246283Sdfr } 184346283Sdfr#endif 184446283Sdfr 184546283Sdfr /* Else, is this the first "unhandled" event? If so, 184646283Sdfr * we believe our client wants to see it (if we don't 184746283Sdfr * see a fake-step later on in the scan). 184846283Sdfr */ 184946283Sdfr else if( !was_handled( tstate.tts_lwpid ) && candidate_tid == 0 ) { 185046283Sdfr candidate_tid = tstate.tts_lwpid; 185146283Sdfr candidate_tstate = tstate; 185246283Sdfr } 185346283Sdfr 185446283Sdfr /* This is either an event that has already been "handled", 185546283Sdfr * and thus we believe is uninteresting to our client, or we 185646283Sdfr * already have a candidate event. Ignore it... 185746283Sdfr */ 185846283Sdfr } 185946283Sdfr 186046283Sdfr /* What do we report? 186146283Sdfr */ 186246283Sdfr if( doing_fake_step ) { 186346283Sdfr if( candidate_tid == fake_step_tid ) { 186446283Sdfr /* Fake step. 186546283Sdfr */ 186646283Sdfr tstate = candidate_tstate; 186746283Sdfr } 186846283Sdfr else { 186946283Sdfr warning( "Internal error: fake-step failed to complete." ); 187046283Sdfr return 0; 187146283Sdfr } 187246283Sdfr } 187346283Sdfr else if( candidate_tid != 0 ) { 187446283Sdfr /* Found a candidate unhandled event. 187546283Sdfr */ 187646283Sdfr tstate = candidate_tstate; 187746283Sdfr } 187846283Sdfr else if( tid != 0 ) { 187946283Sdfr warning( "Internal error in call of ttrace_wait." ); 188046283Sdfr return 0; 188146283Sdfr } 188246283Sdfr else { 188346283Sdfr warning ("Internal error: no unhandled thread event to select"); 188446283Sdfr return 0; 188546283Sdfr } 188646283Sdfr 188746283Sdfr copy_ttstate_t (tsp, &tstate); 188846283Sdfr return 1; 188946283Sdfr} /* End of select_stopped_thread_of_process */ 189046283Sdfr 189146283Sdfr#ifdef PARANOIA 189246283Sdfr/* Check our internal thread data against the real thing. 189346283Sdfr */ 189446283Sdfrstatic void 189546283Sdfrcheck_thread_consistency( real_pid ) 189646283Sdfr pid_t real_pid; 189746283Sdfr{ 189846283Sdfr int tid; /* really lwpid_t */ 189946283Sdfr ttstate_t tstate; 190046283Sdfr thread_info *p; 190146283Sdfr 190246283Sdfr /* Spin down the O/S list of threads, checking that they 190346283Sdfr * match what we've got. 190446283Sdfr */ 190546283Sdfr for (tid = get_process_first_stopped_thread_id( real_pid, &tstate ); 190646283Sdfr tid != 0; 190746283Sdfr tid = get_process_next_stopped_thread_id( real_pid, &tstate )) { 190846283Sdfr 190946283Sdfr p = find_thread_info( tid ); 191046283Sdfr 191146283Sdfr if( NULL == p ) { 191246283Sdfr warning( "No internal thread data for thread %d.", tid ); 191346283Sdfr continue; 191446283Sdfr } 191546283Sdfr 191646283Sdfr if( !p->seen ) { 191746283Sdfr warning( "Inconsistent internal thread data for thread %d.", tid ); 191846283Sdfr } 191946283Sdfr 192046283Sdfr if( p->terminated ) { 192146283Sdfr warning( "Thread %d is not terminated, internal error.", tid ); 192246283Sdfr continue; 192346283Sdfr } 192446283Sdfr 192546283Sdfr 192646283Sdfr#define TT_COMPARE( fld ) \ 192746283Sdfr tstate.fld != p->last_stop_state.fld 192846283Sdfr 192946283Sdfr if( p->have_state ) { 193046283Sdfr if( TT_COMPARE( tts_pid ) 193146283Sdfr || TT_COMPARE( tts_lwpid ) 193246283Sdfr || TT_COMPARE( tts_user_tid ) 193346283Sdfr || TT_COMPARE( tts_event ) 193446283Sdfr || TT_COMPARE( tts_flags ) 193546283Sdfr || TT_COMPARE( tts_scno ) 193646283Sdfr || TT_COMPARE( tts_scnargs )) { 193746283Sdfr warning( "Internal thread data for thread %d is wrong.", tid ); 193846283Sdfr continue; 193946283Sdfr } 194046283Sdfr } 194146283Sdfr } 194246283Sdfr} 194346283Sdfr#endif /* PARANOIA */ 194446283Sdfr 194546283Sdfr 194646283Sdfr/* This function wraps calls to "call_real_ttrace_wait" so 194746283Sdfr * that a actual wait is only done when all pending events 194846283Sdfr * have been reported. 194946283Sdfr * 195046283Sdfr * Note that typically it is called with a pid of "0", i.e. 195146283Sdfr * the "don't care" value. 195246283Sdfr * 195346283Sdfr * Return value is the status of the pseudo wait. 195446283Sdfr */ 195546283Sdfrstatic int 195646283Sdfrcall_ttrace_wait( pid, option, tsp, tsp_size ) 195746283Sdfr int pid; 195846283Sdfr ttwopt_t option; 195946283Sdfr ttstate_t *tsp; 196046283Sdfr size_t tsp_size; 196146283Sdfr{ 196246283Sdfr /* This holds the actual, for-real, true process ID. 196346283Sdfr */ 196446283Sdfr static int real_pid; 196546283Sdfr 196646283Sdfr /* As an argument to ttrace_wait, zero pid 196746283Sdfr * means "Any process", and zero tid means 196846283Sdfr * "Any thread of the specified process". 196946283Sdfr */ 197046283Sdfr int wait_pid = 0; 197146283Sdfr lwpid_t wait_tid = 0; 197246283Sdfr lwpid_t real_tid; 197346283Sdfr 197446283Sdfr int ttw_status = 0; /* To be returned */ 197546283Sdfr 197646283Sdfr thread_info * tinfo = NULL; 197746283Sdfr 197846283Sdfr if( pid != 0 ) { 197946283Sdfr /* Unexpected case. 198046283Sdfr */ 198146283Sdfr#ifdef THREAD_DEBUG 198246283Sdfr if( debug_on ) 198346283Sdfr printf( "TW: Pid to wait on is %d\n", pid ); 198446283Sdfr#endif 198546283Sdfr 198646283Sdfr if( !any_thread_records()) 198746283Sdfr error( "No thread records for ttrace call w. specific pid" ); 198846283Sdfr 198946283Sdfr /* OK, now the task is to translate the incoming tid into 199046283Sdfr * a pid/tid pair. 199146283Sdfr */ 199246283Sdfr real_tid = map_from_gdb_tid( pid ); 199346283Sdfr real_pid = get_pid_for( real_tid ); 199446283Sdfr#ifdef THREAD_DEBUG 199546283Sdfr if( debug_on ) 199646283Sdfr printf( "==TW: real pid %d, real tid %d\n", real_pid, real_tid ); 199746283Sdfr#endif 199846283Sdfr } 199946283Sdfr 200046283Sdfr 200146283Sdfr /* Sanity checks and set-up. 200246283Sdfr * Process State 200346283Sdfr * 200446283Sdfr * Stopped Running Fake-step (v)Fork 200546283Sdfr * \________________________________________ 200646283Sdfr * | 200746283Sdfr * No buffered events | error wait wait wait 200846283Sdfr * | 200946283Sdfr * Buffered events | debuffer error wait debuffer (?) 201046283Sdfr * 201146283Sdfr */ 201246283Sdfr if( more_events_left == 0 ) { 201346283Sdfr 201446283Sdfr if( process_state == RUNNING ) { 201546283Sdfr /* OK--normal call of ttrace_wait with no buffered events. 201646283Sdfr */ 201746283Sdfr ; 201846283Sdfr } 201946283Sdfr else if( process_state == FAKE_STEPPING ) { 202046283Sdfr /* Ok--call of ttrace_wait to support 202146283Sdfr * fake stepping with no buffered events. 202246283Sdfr * 202346283Sdfr * But we better be fake-stepping! 202446283Sdfr */ 202546283Sdfr if( !doing_fake_step ) { 202646283Sdfr warning( "Inconsistent thread state." ); 202746283Sdfr } 202846283Sdfr } 202946283Sdfr else if( (process_state == FORKING) 203046283Sdfr || (process_state == VFORKING)) { 203146283Sdfr /* Ok--there are two processes, so waiting 203246283Sdfr * for the second while the first is stopped 203346283Sdfr * is ok. Handled bits stay as they were. 203446283Sdfr */ 203546283Sdfr ; 203646283Sdfr } 203746283Sdfr else if( process_state == STOPPED ) { 203846283Sdfr warning( "Process not running at wait call." ); 203946283Sdfr } 204046283Sdfr else 204146283Sdfr /* No known state. 204246283Sdfr */ 204346283Sdfr warning( "Inconsistent process state." ); 204446283Sdfr } 204546283Sdfr 204646283Sdfr else { 204746283Sdfr /* More events left 204846283Sdfr */ 204946283Sdfr if( process_state == STOPPED ) { 205046283Sdfr /* OK--buffered events being unbuffered. 205146283Sdfr */ 205246283Sdfr ; 205346283Sdfr } 205446283Sdfr else if( process_state == RUNNING ) { 205546283Sdfr /* An error--shouldn't have buffered events 205646283Sdfr * when running. 205746283Sdfr */ 205846283Sdfr warning( "Trying to continue with buffered events:" ); 205946283Sdfr } 206046283Sdfr else if( process_state == FAKE_STEPPING ) { 206146283Sdfr /* 206246283Sdfr * Better be fake-stepping! 206346283Sdfr */ 206446283Sdfr if( !doing_fake_step ) { 206546283Sdfr warning( "Losing buffered thread events!\n" ); 206646283Sdfr } 206746283Sdfr } 206846283Sdfr else if( (process_state == FORKING) 206946283Sdfr || (process_state == VFORKING)) { 207046283Sdfr /* Ok--there are two processes, so waiting 207146283Sdfr * for the second while the first is stopped 207246283Sdfr * is ok. Handled bits stay as they were. 207346283Sdfr */ 207446283Sdfr ; 207546283Sdfr } 207646283Sdfr else 207746283Sdfr warning( "Process in unknown state with buffered events." ); 207846283Sdfr } 207946283Sdfr 208046283Sdfr /* Sometimes we have to wait for a particular thread 208146283Sdfr * (if we're stepping over a bpt). In that case, we 208246283Sdfr * _know_ it's going to complete the single-step we 208346283Sdfr * asked for (because we're only doing the step under 208446283Sdfr * certain very well-understood circumstances), so it 208546283Sdfr * can't block. 208646283Sdfr */ 208746283Sdfr if( doing_fake_step ) { 208846283Sdfr wait_tid = fake_step_tid; 208946283Sdfr wait_pid = get_pid_for( fake_step_tid ); 209046283Sdfr 209146283Sdfr#ifdef WAIT_BUFFER_DEBUG 209246283Sdfr if( debug_on ) 209346283Sdfr printf( "Doing a wait after a fake-step for %d, pid %d\n", 209446283Sdfr wait_tid, wait_pid ); 209546283Sdfr#endif 209646283Sdfr } 209746283Sdfr 209846283Sdfr if( more_events_left == 0 /* No buffered events, need real ones. */ 209946283Sdfr || process_state != STOPPED ) { 210046283Sdfr /* If there are no buffered events, and so we need 210146283Sdfr * real ones, or if we are FORKING, VFORKING, 210246283Sdfr * FAKE_STEPPING or RUNNING, and thus have to do 210346283Sdfr * a real wait, then do a real wait. 210446283Sdfr */ 210546283Sdfr 210646283Sdfr#ifdef WAIT_BUFFER_DEBUG 210746283Sdfr /* Normal case... */ 210846283Sdfr if( debug_on ) 210946283Sdfr printf( "TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid ); 211046283Sdfr#endif 211146283Sdfr 211246283Sdfr /* The actual wait call. 211346283Sdfr */ 211446283Sdfr ttw_status = call_real_ttrace_wait( wait_pid, wait_tid, option, tsp, tsp_size); 211546283Sdfr 211646283Sdfr /* Note that the routines we'll call will be using "call_real_ttrace", 211746283Sdfr * not "call_ttrace", and thus need the real pid rather than the pseudo-tid 211846283Sdfr * the rest of the world uses (which is actually the tid). 211946283Sdfr */ 212046283Sdfr real_pid = tsp->tts_pid; 212146283Sdfr 212246283Sdfr /* For most events: Stop the world! 212346283Sdfr * 212446283Sdfr * It's sometimes not safe to stop all threads of a process. 212546283Sdfr * Sometimes it's not even safe to ask for the thread state 212646283Sdfr * of a process! 212746283Sdfr */ 212846283Sdfr if (can_touch_threads_of_process (real_pid, tsp->tts_event)) 212946283Sdfr { 213046283Sdfr /* If we're really only stepping a single thread, then don't 213146283Sdfr * try to stop all the others -- we only do this single-stepping 213246283Sdfr * business when all others were already stopped...and the stop 213346283Sdfr * would mess up other threads' events. 213446283Sdfr * 213546283Sdfr * Similiarly, if there are other threads with events, 213646283Sdfr * don't do the stop. 213746283Sdfr */ 213846283Sdfr if( !doing_fake_step ) { 213946283Sdfr if( more_events_left > 0 ) 214046283Sdfr warning( "Internal error in stopping process" ); 214146283Sdfr 214246283Sdfr stop_all_threads_of_process (real_pid); 214346283Sdfr 214446283Sdfr /* At this point, we could scan and update_thread_list(), 214546283Sdfr * and only use the local list for the rest of the 214646283Sdfr * module! We'd get rid of the scans in the various 214746283Sdfr * continue routines (adding one in attach). It'd 214846283Sdfr * be great--UPGRADE ME! 214946283Sdfr */ 215046283Sdfr } 215146283Sdfr } 215246283Sdfr 215346283Sdfr#ifdef PARANOIA 215446283Sdfr else if( debug_on ) { 215546283Sdfr if( more_events_left > 0 ) 215646283Sdfr printf( "== Can't stop process; more events!\n" ); 215746283Sdfr else 215846283Sdfr printf( "== Can't stop process!\n" ); 215946283Sdfr } 216046283Sdfr#endif 216146283Sdfr 216246283Sdfr process_state = STOPPED; 216346283Sdfr 216446283Sdfr#ifdef WAIT_BUFFER_DEBUG 216546283Sdfr if( debug_on ) 216646283Sdfr printf( "Process set to STOPPED\n" ); 216746283Sdfr#endif 216846283Sdfr } 216946283Sdfr 217046283Sdfr else { 217146283Sdfr /* Fake a call to ttrace_wait. The process must be 217246283Sdfr * STOPPED, as we aren't going to do any wait. 217346283Sdfr */ 217446283Sdfr#ifdef WAIT_BUFFER_DEBUG 217546283Sdfr if( debug_on ) 217646283Sdfr printf( "TW: fake it\n" ); 217746283Sdfr#endif 217846283Sdfr 217946283Sdfr if( process_state != STOPPED ) { 218046283Sdfr warning( "Process not stopped at wait call, in state '%s'.\n", 218146283Sdfr get_printable_name_of_process_state( process_state )); 218246283Sdfr } 218346283Sdfr 218446283Sdfr if( doing_fake_step ) 218546283Sdfr error( "Internal error in stepping over breakpoint" ); 218646283Sdfr 218746283Sdfr ttw_status = 0; /* Faking it is always successful! */ 218846283Sdfr } /* End of fake or not? if */ 218946283Sdfr 219046283Sdfr /* Pick an event to pass to our caller. Be paranoid. 219146283Sdfr */ 219246283Sdfr if( !select_stopped_thread_of_process( real_pid, tsp )) 219346283Sdfr warning( "Can't find event, using previous event." ); 219446283Sdfr 219546283Sdfr else if( tsp->tts_event == TTEVT_NONE ) 219646283Sdfr warning( "Internal error: no thread has a real event." ); 219746283Sdfr 219846283Sdfr else if( doing_fake_step ) { 219946283Sdfr if( fake_step_tid != tsp->tts_lwpid ) 220046283Sdfr warning( "Internal error in stepping over breakpoint." ); 220146283Sdfr 220246283Sdfr /* This wait clears the (current) fake-step if there was one. 220346283Sdfr */ 220446283Sdfr doing_fake_step = 0; 220546283Sdfr fake_step_tid = 0; 220646283Sdfr } 220746283Sdfr 220846283Sdfr /* We now have a correct tsp and ttw_status for the thread 220946283Sdfr * which we want to report. So it's "handled"! This call 221046283Sdfr * will add it to our list if it's not there already. 221146283Sdfr */ 221246283Sdfr set_handled( real_pid, tsp->tts_lwpid ); 221346283Sdfr 221446283Sdfr /* Save a copy of the ttrace state of this thread, in our local 221546283Sdfr thread descriptor. 221646283Sdfr 221746283Sdfr This caches the state. The implementation of queries like 221846283Sdfr target_has_execd can then use this cached state, rather than 221946283Sdfr be forced to make an explicit ttrace call to get it. 222046283Sdfr 222146283Sdfr (Guard against the condition that this is the first time we've 222246283Sdfr waited on, i.e., seen this thread, and so haven't yet entered 222346283Sdfr it into our list of threads.) 222446283Sdfr */ 222546283Sdfr tinfo = find_thread_info (tsp->tts_lwpid); 222646283Sdfr if (tinfo != NULL) { 222746283Sdfr copy_ttstate_t (&tinfo->last_stop_state, tsp); 222846283Sdfr tinfo->have_state = 1; 222946283Sdfr } 223046283Sdfr 223146283Sdfr return ttw_status; 223246283Sdfr} /* call_ttrace_wait */ 223346283Sdfr 223446283Sdfr#if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL) 223546283Sdfrint 223646283Sdfrchild_reported_exec_events_per_exec_call () 223746283Sdfr{ 223846283Sdfr return 1; /* ttrace reports the event once per call. */ 223946283Sdfr} 224046283Sdfr#endif 224146283Sdfr 224246283Sdfr 224346283Sdfr 224446283Sdfr/* Our implementation of hardware watchpoints involves making memory 224546283Sdfr pages write-protected. We must remember a page's original permissions, 224646283Sdfr and we must also know when it is appropriate to restore a page's 224746283Sdfr permissions to its original state. 224846283Sdfr 224946283Sdfr We use a "dictionary" of hardware-watched pages to do this. Each 225046283Sdfr hardware-watched page is recorded in the dictionary. Each page's 225146283Sdfr dictionary entry contains the original permissions and a reference 225246283Sdfr count. Pages are hashed into the dictionary by their start address. 225346283Sdfr 225446283Sdfr When hardware watchpoint is set on page X for the first time, page X 225546283Sdfr is added to the dictionary with a reference count of 1. If other 225646283Sdfr hardware watchpoints are subsequently set on page X, its reference 225746283Sdfr count is incremented. When hardware watchpoints are removed from 225846283Sdfr page X, its reference count is decremented. If a page's reference 225946283Sdfr count drops to 0, it's permissions are restored and the page's entry 226046283Sdfr is thrown out of the dictionary. 226146283Sdfr */ 226246283Sdfrtypedef struct memory_page { 226346283Sdfr CORE_ADDR page_start; 226446283Sdfr int reference_count; 226546283Sdfr int original_permissions; 226646283Sdfr struct memory_page * next; 226746283Sdfr struct memory_page * previous; 226846283Sdfr} memory_page_t; 226946283Sdfr 227046283Sdfr#define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT 128 227146283Sdfr 227246283Sdfrstatic struct { 227346283Sdfr LONGEST page_count; 227446283Sdfr int page_size; 227546283Sdfr int page_protections_allowed; 227646283Sdfr /* These are just the heads of chains of actual page descriptors. */ 227746283Sdfr memory_page_t buckets [MEMORY_PAGE_DICTIONARY_BUCKET_COUNT]; 227846283Sdfr} memory_page_dictionary; 227946283Sdfr 228046283Sdfr 228146283Sdfrstatic void 228246283Sdfrrequire_memory_page_dictionary () 228346283Sdfr{ 228446283Sdfr int i; 228546283Sdfr 228646283Sdfr /* Is the memory page dictionary ready for use? If so, we're done. */ 228746283Sdfr if (memory_page_dictionary.page_count >= (LONGEST) 0) 228846283Sdfr return; 228946283Sdfr 229046283Sdfr /* Else, initialize it. */ 229146283Sdfr memory_page_dictionary.page_count = (LONGEST) 0; 229246283Sdfr 229346283Sdfr for (i=0; i<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++) 229446283Sdfr { 229546283Sdfr memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0; 229646283Sdfr memory_page_dictionary.buckets[i].reference_count = 0; 229746283Sdfr memory_page_dictionary.buckets[i].next = NULL; 229846283Sdfr memory_page_dictionary.buckets[i].previous = NULL; 229946283Sdfr } 230046283Sdfr} 230146283Sdfr 230246283Sdfr 230346283Sdfrstatic void 230446283Sdfrretire_memory_page_dictionary () 230546283Sdfr{ 230646283Sdfr memory_page_dictionary.page_count = (LONGEST) -1; 230746283Sdfr} 230846283Sdfr 230946283Sdfr 231046283Sdfr/* Write-protect the memory page that starts at this address. 231146283Sdfr 231246283Sdfr Returns the original permissions of the page. 231346283Sdfr */ 231446283Sdfrstatic int 231546283Sdfrwrite_protect_page (pid, page_start) 231646283Sdfr int pid; 231746283Sdfr CORE_ADDR page_start; 231846283Sdfr{ 231946283Sdfr int tt_status; 232046283Sdfr int original_permissions; 232146283Sdfr int new_permissions; 232246283Sdfr 232346283Sdfr tt_status = call_ttrace (TT_PROC_GET_MPROTECT, 232446283Sdfr pid, 232546283Sdfr (TTRACE_ARG_TYPE) page_start, 232646283Sdfr TT_NIL, 232746283Sdfr (TTRACE_ARG_TYPE) &original_permissions); 232846283Sdfr if (errno || (tt_status < 0)) 232946283Sdfr { 233046283Sdfr return 0; /* What else can we do? */ 233146283Sdfr } 233246283Sdfr 233346283Sdfr /* We'll also write-protect the page now, if that's allowed. */ 233446283Sdfr if (memory_page_dictionary.page_protections_allowed) 233546283Sdfr { 233646283Sdfr new_permissions = original_permissions & ~PROT_WRITE; 233746283Sdfr tt_status = call_ttrace (TT_PROC_SET_MPROTECT, 233846283Sdfr pid, 233946283Sdfr (TTRACE_ARG_TYPE) page_start, 234046283Sdfr (TTRACE_ARG_TYPE) memory_page_dictionary.page_size, 234146283Sdfr (TTRACE_ARG_TYPE) new_permissions); 234246283Sdfr if (errno || (tt_status < 0)) 234346283Sdfr { 234446283Sdfr return 0; /* What else can we do? */ 234546283Sdfr } 234646283Sdfr } 234746283Sdfr 234846283Sdfr return original_permissions; 234946283Sdfr} 235046283Sdfr 235146283Sdfr 235246283Sdfr/* Unwrite-protect the memory page that starts at this address, restoring 235346283Sdfr (what we must assume are) its original permissions. 235446283Sdfr */ 235546283Sdfrstatic void 235646283Sdfrunwrite_protect_page (pid, page_start, original_permissions) 235746283Sdfr int pid; 235846283Sdfr CORE_ADDR page_start; 235946283Sdfr int original_permissions; 236046283Sdfr{ 236146283Sdfr int tt_status; 236246283Sdfr 236346283Sdfr tt_status = call_ttrace (TT_PROC_SET_MPROTECT, 236446283Sdfr pid, 236546283Sdfr (TTRACE_ARG_TYPE) page_start, 236646283Sdfr (TTRACE_ARG_TYPE) memory_page_dictionary.page_size, 236746283Sdfr (TTRACE_ARG_TYPE) original_permissions); 236846283Sdfr if (errno || (tt_status < 0)) 236946283Sdfr { 237046283Sdfr return; /* What else can we do? */ 237146283Sdfr } 237246283Sdfr} 237346283Sdfr 237446283Sdfr 237546283Sdfr/* Memory page-protections are used to implement "hardware" watchpoints 237646283Sdfr on HP-UX. 237746283Sdfr 237846283Sdfr For every memory page that is currently being watched (i.e., that 237946283Sdfr presently should be write-protected), write-protect it. 238046283Sdfr */ 238146283Sdfrvoid 238246283Sdfrhppa_enable_page_protection_events (pid) 238346283Sdfr int pid; 238446283Sdfr{ 238546283Sdfr int bucket; 238646283Sdfr 238746283Sdfr memory_page_dictionary.page_protections_allowed = 1; 238846283Sdfr 238946283Sdfr for (bucket=0; bucket<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++) 239046283Sdfr { 239146283Sdfr memory_page_t * page; 239246283Sdfr 239346283Sdfr page = memory_page_dictionary.buckets[bucket].next; 239446283Sdfr while (page != NULL) 239546283Sdfr { 239646283Sdfr page->original_permissions = write_protect_page (pid, page->page_start); 239746283Sdfr page = page->next; 239846283Sdfr } 239946283Sdfr } 240046283Sdfr} 240146283Sdfr 240246283Sdfr 240346283Sdfr/* Memory page-protections are used to implement "hardware" watchpoints 240446283Sdfr on HP-UX. 240546283Sdfr 240646283Sdfr For every memory page that is currently being watched (i.e., that 240746283Sdfr presently is or should be write-protected), un-write-protect it. 240846283Sdfr */ 240946283Sdfrvoid 241046283Sdfrhppa_disable_page_protection_events (pid) 241146283Sdfr int pid; 241246283Sdfr{ 241346283Sdfr int bucket; 241446283Sdfr 241546283Sdfr for (bucket=0; bucket<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++) 241646283Sdfr { 241746283Sdfr memory_page_t * page; 241846283Sdfr 241946283Sdfr page = memory_page_dictionary.buckets[bucket].next; 242046283Sdfr while (page != NULL) 242146283Sdfr { 242246283Sdfr unwrite_protect_page (pid, page->page_start, page->original_permissions); 242346283Sdfr page = page->next; 242446283Sdfr } 242546283Sdfr } 242646283Sdfr 242746283Sdfr memory_page_dictionary.page_protections_allowed = 0; 242846283Sdfr} 242946283Sdfr 243046283Sdfr/* Count the number of outstanding events. At this 243146283Sdfr * point, we have selected one thread and its event 243246283Sdfr * as the one to be "reported" upwards to core gdb. 243346283Sdfr * That thread is already marked as "handled". 243446283Sdfr * 243546283Sdfr * Note: we could just scan our own thread list. FIXME! 243646283Sdfr */ 243746283Sdfrstatic int 243846283Sdfrcount_unhandled_events( real_pid, real_tid ) 243946283Sdfr int real_pid; 244046283Sdfr lwpid_t real_tid; 244146283Sdfr{ 244246283Sdfr ttstate_t tstate; 244346283Sdfr lwpid_t ttid; 244446283Sdfr int events_left; 244546283Sdfr 244646283Sdfr /* Ok, find out how many threads have real events to report. 244746283Sdfr */ 244846283Sdfr events_left = 0; 244946283Sdfr ttid = get_process_first_stopped_thread_id( real_pid, &tstate ); 245046283Sdfr 245146283Sdfr#ifdef THREAD_DEBUG 245246283Sdfr if( debug_on ) { 245346283Sdfr if( ttid == 0 ) 245446283Sdfr printf( "Process %d has no threads\n", real_pid ); 245546283Sdfr else 245646283Sdfr printf( "Process %d has these threads:\n", real_pid ); 245746283Sdfr } 245846283Sdfr#endif 245946283Sdfr 246046283Sdfr while (ttid > 0 ) { 246146283Sdfr if( tstate.tts_event != TTEVT_NONE 246246283Sdfr && !was_handled( ttid )) { 246346283Sdfr /* TTEVT_NONE implies we just stopped it ourselves 246446283Sdfr * because we're the stop-the-world guys, so it's 246546283Sdfr * not an event from our point of view. 246646283Sdfr * 246746283Sdfr * If "was_handled" is true, this is an event we 246846283Sdfr * already handled, so don't count it. 246946283Sdfr * 247046283Sdfr * Note that we don't count the thread with the 247146283Sdfr * currently-reported event, as it's already marked 247246283Sdfr * as handled. 247346283Sdfr */ 247446283Sdfr events_left++; 247546283Sdfr } 247646283Sdfr 247746283Sdfr#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG ) 247846283Sdfr if( debug_on ) { 247946283Sdfr if( ttid == real_tid ) 248046283Sdfr printf( "*" ); /* Thread we're reporting */ 248146283Sdfr else 248246283Sdfr printf( " " ); 248346283Sdfr 248446283Sdfr if( tstate.tts_event != TTEVT_NONE ) 248546283Sdfr printf( "+" ); /* Thread with a real event */ 248646283Sdfr else 248746283Sdfr printf( " " ); 248846283Sdfr 248946283Sdfr if( was_handled( ttid )) 249046283Sdfr printf( "h" ); /* Thread has been handled */ 249146283Sdfr else 249246283Sdfr printf( " " ); 249346283Sdfr 249446283Sdfr printf( " %d, with event %s", ttid, 249546283Sdfr get_printable_name_of_ttrace_event( tstate.tts_event )); 249646283Sdfr 249746283Sdfr if( tstate.tts_event == TTEVT_SIGNAL 249846283Sdfr && 5 == tstate.tts_u.tts_signal.tts_signo ) { 249946283Sdfr CORE_ADDR pc_val; 250046283Sdfr 250146283Sdfr pc_val = get_raw_pc( ttid ); 250246283Sdfr 250346283Sdfr if( pc_val > 0 ) 250446283Sdfr printf( " breakpoint at 0x%x\n", pc_val ); 250546283Sdfr else 250646283Sdfr printf( " bpt, can't fetch pc.\n" ); 250746283Sdfr } 250846283Sdfr else 250946283Sdfr printf( "\n" ); 251046283Sdfr } 251146283Sdfr#endif 251246283Sdfr 251346283Sdfr ttid = get_process_next_stopped_thread_id (real_pid, &tstate); 251446283Sdfr } 251546283Sdfr 251646283Sdfr#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG ) 251746283Sdfr if( debug_on ) 251846283Sdfr if( events_left > 0 ) 251946283Sdfr printf( "There are thus %d pending events\n", events_left ); 252046283Sdfr#endif 252146283Sdfr 252246283Sdfr return events_left; 252346283Sdfr} 252446283Sdfr 252546283Sdfr/* This function is provided as a sop to clients that are calling 252646283Sdfr * ptrace_wait to wait for a process to stop. (see the 252746283Sdfr * implementation of child_wait.) Return value is the pid for 252846283Sdfr * the event that ended the wait. 252946283Sdfr * 253046283Sdfr * Note: used by core gdb and so uses the pseudo-pid (really tid). 253146283Sdfr */ 253246283Sdfrint 253346283Sdfrptrace_wait (pid, status) 253446283Sdfr int pid; 253546283Sdfr int *status; 253646283Sdfr{ 253746283Sdfr ttstate_t tsp; 253846283Sdfr int ttwait_return; 253946283Sdfr int real_pid; 254046283Sdfr ttstate_t state; 254146283Sdfr lwpid_t real_tid; 254246283Sdfr int return_pid; 254346283Sdfr 254446283Sdfr /* The ptrace implementation of this also ignores pid. 254546283Sdfr */ 254646283Sdfr *status = 0; 254746283Sdfr 254846283Sdfr ttwait_return = call_ttrace_wait( 0, TTRACE_WAITOK, &tsp, sizeof (tsp) ); 254946283Sdfr if (ttwait_return < 0) 255046283Sdfr { 255146283Sdfr /* ??rehrauer: It appears that if our inferior exits and we 255246283Sdfr haven't asked for exit events, that we're not getting any 255346283Sdfr indication save a negative return from ttrace_wait and an 255446283Sdfr errno set to ESRCH? 255546283Sdfr */ 255646283Sdfr if (errno == ESRCH) 255746283Sdfr { 255846283Sdfr *status = 0; /* WIFEXITED */ 255946283Sdfr return inferior_pid; 256046283Sdfr } 256146283Sdfr 256246283Sdfr warning( "Call of ttrace_wait returned with errno %d.", 256346283Sdfr errno ); 256446283Sdfr *status = ttwait_return; 256546283Sdfr return inferior_pid; 256646283Sdfr } 256746283Sdfr 256846283Sdfr real_pid = tsp.tts_pid; 256946283Sdfr real_tid = tsp.tts_lwpid; 257046283Sdfr 257146283Sdfr /* One complication is that the "tts_event" structure has 257246283Sdfr * a set of flags, and more than one can be set. So we 257346283Sdfr * either have to force an order (as we do here), or handle 257446283Sdfr * more than one flag at a time. 257546283Sdfr */ 257646283Sdfr if (tsp.tts_event & TTEVT_LWP_CREATE) { 257746283Sdfr 257846283Sdfr /* Unlike what you might expect, this event is reported in 257946283Sdfr * the _creating_ thread, and the _created_ thread (whose tid 258046283Sdfr * we have) is still running. So we have to stop it. This 258146283Sdfr * has already been done in "call_ttrace_wait", but should we 258246283Sdfr * ever abandon the "stop-the-world" model, here's the command 258346283Sdfr * to use: 258446283Sdfr * 258546283Sdfr * call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL ); 258646283Sdfr * 258746283Sdfr * Note that this would depend on being called _after_ "add_tthread" 258846283Sdfr * below for the tid-to-pid translation to be done in "call_ttrace". 258946283Sdfr */ 259046283Sdfr 259146283Sdfr#ifdef THREAD_DEBUG 259246283Sdfr if( debug_on ) 259346283Sdfr printf( "New thread: pid %d, tid %d, creator tid %d\n", 259446283Sdfr real_pid, tsp.tts_u.tts_thread.tts_target_lwpid, 259546283Sdfr real_tid ); 259646283Sdfr#endif 259746283Sdfr 259846283Sdfr /* Now we have to return the tid of the created thread, not 259946283Sdfr * the creating thread, or "wait_for_inferior" won't know we 260046283Sdfr * have a new "process" (thread). Plus we should record it 260146283Sdfr * right, too. 260246283Sdfr */ 260346283Sdfr real_tid = tsp.tts_u.tts_thread.tts_target_lwpid; 260446283Sdfr 260546283Sdfr add_tthread( real_pid, real_tid ); 260646283Sdfr } 260746283Sdfr 260846283Sdfr else if( (tsp.tts_event & TTEVT_LWP_TERMINATE ) 260946283Sdfr || (tsp.tts_event & TTEVT_LWP_EXIT) ) { 261046283Sdfr 261146283Sdfr#ifdef THREAD_DEBUG 261246283Sdfr if( debug_on ) 261346283Sdfr printf( "Thread dies: %d\n", real_tid ); 261446283Sdfr#endif 261546283Sdfr 261646283Sdfr del_tthread( real_tid ); 261746283Sdfr } 261846283Sdfr 261946283Sdfr else if (tsp.tts_event & TTEVT_EXEC) { 262046283Sdfr 262146283Sdfr#ifdef THREAD_DEBUG 262246283Sdfr if( debug_on ) 262346283Sdfr printf( "Pid %d has zero'th thread %d; inferior pid is %d\n", 262446283Sdfr real_pid, real_tid, inferior_pid ); 262546283Sdfr#endif 262646283Sdfr 262746283Sdfr add_tthread( real_pid, real_tid ); 262846283Sdfr } 262946283Sdfr 263046283Sdfr#ifdef THREAD_DEBUG 263146283Sdfr else if( debug_on ) { 263246283Sdfr printf( "Process-level event %s, using tid %d\n", 263346283Sdfr get_printable_name_of_ttrace_event( tsp.tts_event ), 263446283Sdfr real_tid ); 263546283Sdfr 263646283Sdfr /* OK to do this, as "add_tthread" won't add 263746283Sdfr * duplicate entries. Also OK not to do it, 263846283Sdfr * as this event isn't one which can change the 263946283Sdfr * thread state. 264046283Sdfr */ 264146283Sdfr add_tthread( real_pid, real_tid ); 264246283Sdfr } 264346283Sdfr#endif 264446283Sdfr 264546283Sdfr 264646283Sdfr /* How many events are left to report later? 264746283Sdfr * In a non-stop-the-world model, this isn't needed. 264846283Sdfr * 264946283Sdfr * Note that it's not always safe to query the thread state of a process, 265046283Sdfr * which is what count_unhandled_events does. (If unsafe, we're left with 265146283Sdfr * no other resort than to assume that no more events remain...) 265246283Sdfr */ 265346283Sdfr if (can_touch_threads_of_process (real_pid, tsp.tts_event)) 265446283Sdfr more_events_left = count_unhandled_events( real_pid, real_tid ); 265546283Sdfr 265646283Sdfr else { 265746283Sdfr if( more_events_left > 0 ) 265846283Sdfr warning( "Vfork or fork causing loss of %d buffered events.", 265946283Sdfr more_events_left ); 266046283Sdfr 266146283Sdfr more_events_left = 0; 266246283Sdfr } 266346283Sdfr 266446283Sdfr /* Attempt to translate the ttrace_wait-returned status into the 266546283Sdfr ptrace equivalent. 266646283Sdfr 266746283Sdfr ??rehrauer: This is somewhat fragile. We really ought to rewrite 266846283Sdfr clients that expect to pick apart a ptrace wait status, to use 266946283Sdfr something a little more abstract. 267046283Sdfr */ 267146283Sdfr if ( (tsp.tts_event & TTEVT_EXEC) 267246283Sdfr || (tsp.tts_event & TTEVT_FORK) 267346283Sdfr || (tsp.tts_event & TTEVT_VFORK)) 267446283Sdfr { 267546283Sdfr /* Forks come in pairs (parent and child), so core gdb 267646283Sdfr * will do two waits. Be ready to notice this. 267746283Sdfr */ 267846283Sdfr if (tsp.tts_event & TTEVT_FORK) 267946283Sdfr { 268046283Sdfr process_state = FORKING; 268146283Sdfr 268246283Sdfr#ifdef WAIT_BUFFER_DEBUG 268346283Sdfr if( debug_on ) 268446283Sdfr printf( "Process set to FORKING\n" ); 268546283Sdfr#endif 268646283Sdfr } 268746283Sdfr else if (tsp.tts_event & TTEVT_VFORK) 268846283Sdfr { 268946283Sdfr process_state = VFORKING; 269046283Sdfr 269146283Sdfr#ifdef WAIT_BUFFER_DEBUG 269246283Sdfr if( debug_on ) 269346283Sdfr printf( "Process set to VFORKING\n" ); 269446283Sdfr#endif 269546283Sdfr } 269646283Sdfr 269746283Sdfr /* Make an exec or fork look like a breakpoint. Definitely a hack, 269846283Sdfr but I don't think non HP-UX-specific clients really carefully 269946283Sdfr inspect the first events they get after inferior startup, so 270046283Sdfr it probably almost doesn't matter what we claim this is. 270146283Sdfr */ 270246283Sdfr 270346283Sdfr#ifdef THREAD_DEBUG 270446283Sdfr if( debug_on ) 270546283Sdfr printf( "..a process 'event'\n" ); 270646283Sdfr#endif 270746283Sdfr 270846283Sdfr /* Also make fork and exec events look like bpts, so they can be caught. 270946283Sdfr */ 271046283Sdfr *status = 0177 | (_SIGTRAP << 8); 271146283Sdfr } 271246283Sdfr 271346283Sdfr /* Special-cases: We ask for syscall entry and exit events to implement 271446283Sdfr "fast" (aka "hardware") watchpoints. 271546283Sdfr 271646283Sdfr When we get a syscall entry, we want to disable page-protections, 271746283Sdfr and resume the inferior; this isn't an event we wish for 271846283Sdfr wait_for_inferior to see. Note that we must resume ONLY the 271946283Sdfr thread that reported the syscall entry; we don't want to allow 272046283Sdfr other threads to run with the page protections off, as they might 272146283Sdfr then be able to write to watch memory without it being caught. 272246283Sdfr 272346283Sdfr When we get a syscall exit, we want to reenable page-protections, 272446283Sdfr but we don't want to resume the inferior; this is an event we wish 272546283Sdfr wait_for_inferior to see. Make it look like the signal we normally 272646283Sdfr get for a single-step completion. This should cause wait_for_inferior 272746283Sdfr to evaluate whether any watchpoint triggered. 272846283Sdfr 272946283Sdfr Or rather, that's what we'd LIKE to do for syscall exit; we can't, 273046283Sdfr due to some HP-UX "features". Some syscalls have problems with 273146283Sdfr write-protections on some pages, and some syscalls seem to have 273246283Sdfr pending writes to those pages at the time we're getting the return 273346283Sdfr event. So, we'll single-step the inferior to get out of the syscall, 273446283Sdfr and then reenable protections. 273546283Sdfr 273646283Sdfr Note that we're intentionally allowing the syscall exit case to 273746283Sdfr fall through into the succeeding cases, as sometimes we single- 273846283Sdfr step out of one syscall only to immediately enter another... 273946283Sdfr */ 274046283Sdfr else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY) 274146283Sdfr || (tsp.tts_event & TTEVT_SYSCALL_RETURN)) 274246283Sdfr { 274346283Sdfr /* Make a syscall event look like a breakpoint. Same comments 274446283Sdfr as for exec & fork events. 274546283Sdfr */ 274646283Sdfr#ifdef THREAD_DEBUG 274746283Sdfr if( debug_on ) 274846283Sdfr printf( "..a syscall 'event'\n" ); 274946283Sdfr#endif 275046283Sdfr 275146283Sdfr /* Also make syscall events look like bpts, so they can be caught. 275246283Sdfr */ 275346283Sdfr *status = 0177 | (_SIGTRAP << 8); 275446283Sdfr } 275546283Sdfr 275646283Sdfr else if ((tsp.tts_event & TTEVT_LWP_CREATE) 275746283Sdfr || (tsp.tts_event & TTEVT_LWP_TERMINATE) 275846283Sdfr || (tsp.tts_event & TTEVT_LWP_EXIT)) 275946283Sdfr { 276046283Sdfr /* Make a thread event look like a breakpoint. Same comments 276146283Sdfr * as for exec & fork events. 276246283Sdfr */ 276346283Sdfr#ifdef THREAD_DEBUG 276446283Sdfr if( debug_on ) 276546283Sdfr printf( "..a thread 'event'\n" ); 276646283Sdfr#endif 276746283Sdfr 276846283Sdfr /* Also make thread events look like bpts, so they can be caught. 276946283Sdfr */ 277046283Sdfr *status = 0177 | (_SIGTRAP << 8); 277146283Sdfr } 277246283Sdfr 277346283Sdfr else if ((tsp.tts_event & TTEVT_EXIT)) 277446283Sdfr { /* WIFEXITED */ 277546283Sdfr 277646283Sdfr#ifdef THREAD_DEBUG 277746283Sdfr if( debug_on ) 277846283Sdfr printf( "..an exit\n" ); 277946283Sdfr#endif 278046283Sdfr 278146283Sdfr /* Prevent rest of gdb from thinking this is 278246283Sdfr * a new thread if for some reason it's never 278346283Sdfr * seen the main thread before. 278446283Sdfr */ 278546283Sdfr inferior_pid = map_to_gdb_tid( real_tid ); /* HACK, FIX */ 278646283Sdfr 278746283Sdfr *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode); 278846283Sdfr } 278946283Sdfr 279046283Sdfr else if (tsp.tts_event & TTEVT_SIGNAL) 279146283Sdfr { /* WIFSTOPPED */ 279246283Sdfr#ifdef THREAD_DEBUG 279346283Sdfr if( debug_on ) 279446283Sdfr printf( "..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo ); 279546283Sdfr#endif 279646283Sdfr 279746283Sdfr *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8); 279846283Sdfr } 279946283Sdfr 280046283Sdfr else 280146283Sdfr { /* !WIFSTOPPED */ 280246283Sdfr 280346283Sdfr /* This means the process or thread terminated. But we should've 280446283Sdfr caught an explicit exit/termination above. So warn (this is 280546283Sdfr really an internal error) and claim the process or thread 280646283Sdfr terminated with a SIGTRAP. 280746283Sdfr */ 280846283Sdfr 280946283Sdfr warning ("process_wait: unknown process state"); 281046283Sdfr 281146283Sdfr#ifdef THREAD_DEBUG 281246283Sdfr if( debug_on ) 281346283Sdfr printf( "Process-level event %s, using tid %d\n", 281446283Sdfr get_printable_name_of_ttrace_event( tsp.tts_event ), 281546283Sdfr real_tid ); 281646283Sdfr#endif 281746283Sdfr 281846283Sdfr *status = _SIGTRAP; 281946283Sdfr } 282046283Sdfr 282146283Sdfr target_post_wait (tsp.tts_pid, *status); 282246283Sdfr 282346283Sdfr 282446283Sdfr#ifdef THREAD_DEBUG 282546283Sdfr if( debug_on ) 282646283Sdfr printf( "Done waiting, pid is %d, tid %d\n", real_pid, real_tid ); 282746283Sdfr#endif 282846283Sdfr 282946283Sdfr /* All code external to this module uses the tid, but calls 283046283Sdfr * it "pid". There's some tweaking so that the outside sees 283146283Sdfr * the first thread as having the same number as the starting 283246283Sdfr * pid. 283346283Sdfr */ 283446283Sdfr return_pid = map_to_gdb_tid( real_tid ); 283546283Sdfr 283646283Sdfr /* Remember this for later use in "hppa_prepare_to_proceed". 283746283Sdfr */ 283846283Sdfr old_gdb_pid = inferior_pid; 283946283Sdfr reported_pid = return_pid; 284046283Sdfr reported_bpt = ((tsp.tts_event & TTEVT_SIGNAL) && (5 == tsp.tts_u.tts_signal.tts_signo)); 284146283Sdfr 284246283Sdfr if( real_tid == 0 || return_pid == 0 ) { 284346283Sdfr warning( "Internal error: process-wait failed." ); 284446283Sdfr } 284546283Sdfr 284646283Sdfr return return_pid; 284746283Sdfr} 284846283Sdfr 284946283Sdfr 285046283Sdfr/* This function causes the caller's process to be traced by its 285146283Sdfr parent. This is intended to be called after GDB forks itself, 285246283Sdfr and before the child execs the target. Despite the name, it 285346283Sdfr is called by the child. 285446283Sdfr 285546283Sdfr Note that HP-UX ttrace is rather funky in how this is done. 285646283Sdfr If the parent wants to get the initial exec event of a child, 285746283Sdfr it must set the ttrace event mask of the child to include execs. 285846283Sdfr (The child cannot do this itself.) This must be done after the 285946283Sdfr child is forked, but before it execs. 286046283Sdfr 286146283Sdfr To coordinate the parent and child, we implement a semaphore using 286246283Sdfr pipes. After SETTRC'ing itself, the child tells the parent that 286346283Sdfr it is now traceable by the parent, and waits for the parent's 286446283Sdfr acknowledgement. The parent can then set the child's event mask, 286546283Sdfr and notify the child that it can now exec. 286646283Sdfr 286746283Sdfr (The acknowledgement by parent happens as a result of a call to 286846283Sdfr child_acknowledge_created_inferior.) 286946283Sdfr */ 287046283Sdfrint 287146283Sdfrparent_attach_all () 287246283Sdfr{ 287346283Sdfr int tt_status; 287446283Sdfr 287546283Sdfr /* We need a memory home for a constant, to pass it to ttrace. 287646283Sdfr The value of the constant is arbitrary, so long as both 287746283Sdfr parent and child use the same value. Might as well use the 287846283Sdfr "magic" constant provided by ttrace... 287946283Sdfr */ 288046283Sdfr uint64_t tc_magic_child = TT_VERSION; 288146283Sdfr uint64_t tc_magic_parent = 0; 288246283Sdfr 288346283Sdfr tt_status = call_real_ttrace ( 288446283Sdfr TT_PROC_SETTRC, 288546283Sdfr (int) TT_NIL, 288646283Sdfr (lwpid_t) TT_NIL, 288746283Sdfr TT_NIL, 288846283Sdfr (TTRACE_ARG_TYPE) TT_VERSION, 288946283Sdfr TT_NIL ); 289046283Sdfr 289146283Sdfr if (tt_status < 0) 289246283Sdfr return tt_status; 289346283Sdfr 289446283Sdfr /* Notify the parent that we're potentially ready to exec(). */ 289546283Sdfr write (startup_semaphore.child_channel[SEM_TALK], 289646283Sdfr &tc_magic_child, 289746283Sdfr sizeof (tc_magic_child)); 289846283Sdfr 289946283Sdfr /* Wait for acknowledgement from the parent. */ 290046283Sdfr read (startup_semaphore.parent_channel[SEM_LISTEN], 290146283Sdfr &tc_magic_parent, 290246283Sdfr sizeof (tc_magic_parent)); 290346283Sdfr 290446283Sdfr if (tc_magic_child != tc_magic_parent) 290546283Sdfr warning ("mismatched semaphore magic"); 290646283Sdfr 290746283Sdfr /* Discard our copy of the semaphore. */ 290846283Sdfr (void) close (startup_semaphore.parent_channel[SEM_LISTEN]); 290946283Sdfr (void) close (startup_semaphore.parent_channel[SEM_TALK]); 291046283Sdfr (void) close (startup_semaphore.child_channel[SEM_LISTEN]); 291146283Sdfr (void) close (startup_semaphore.child_channel[SEM_TALK]); 291246283Sdfr 291346283Sdfr return tt_status; 291446283Sdfr} 291546283Sdfr 291646283Sdfr/* Despite being file-local, this routine is dealing with 291746283Sdfr * actual process IDs, not thread ids. That's because it's 291846283Sdfr * called before the first "wait" call, and there's no map 291946283Sdfr * yet from tids to pids. 292046283Sdfr * 292146283Sdfr * When it is called, a forked child is running, but waiting on 292246283Sdfr * the semaphore. If you stop the child and re-start it, 292346283Sdfr * things get confused, so don't do that! An attached child is 292446283Sdfr * stopped. 292546283Sdfr * 292646283Sdfr * Since this is called after either attach or run, we 292746283Sdfr * have to be the common part of both. 292846283Sdfr */ 292946283Sdfrstatic void 293046283Sdfrrequire_notification_of_events ( real_pid ) 293146283Sdfr int real_pid; 293246283Sdfr{ 293346283Sdfr int tt_status; 293446283Sdfr ttevent_t notifiable_events; 293546283Sdfr 293646283Sdfr lwpid_t tid; 293746283Sdfr ttstate_t thread_state; 293846283Sdfr 293946283Sdfr#ifdef THREAD_DEBUG 294046283Sdfr if( debug_on ) 294146283Sdfr printf( "Require notif, pid is %d\n", real_pid ); 294246283Sdfr#endif 294346283Sdfr 294446283Sdfr /* Temporary HACK: tell inftarg.c/child_wait to not 294546283Sdfr * loop until pids are the same. 294646283Sdfr */ 294746283Sdfr not_same_real_pid = 0; 294846283Sdfr 294946283Sdfr sigemptyset (¬ifiable_events.tte_signals); 295046283Sdfr notifiable_events.tte_opts = TTEO_NONE; 295146283Sdfr 295246283Sdfr /* This ensures that forked children inherit their parent's 295346283Sdfr * event mask, which we're setting here. 295446283Sdfr * 295546283Sdfr * NOTE: if you debug gdb with itself, then the ultimate 295646283Sdfr * debuggee gets flags set by the outermost gdb, as 295746283Sdfr * a child of a child will still inherit. 295846283Sdfr */ 295946283Sdfr notifiable_events.tte_opts |= TTEO_PROC_INHERIT; 296046283Sdfr 296146283Sdfr notifiable_events.tte_events = TTEVT_DEFAULT; 296246283Sdfr notifiable_events.tte_events |= TTEVT_SIGNAL; 296346283Sdfr notifiable_events.tte_events |= TTEVT_EXEC; 296446283Sdfr notifiable_events.tte_events |= TTEVT_EXIT; 296546283Sdfr notifiable_events.tte_events |= TTEVT_FORK; 296646283Sdfr notifiable_events.tte_events |= TTEVT_VFORK; 296746283Sdfr notifiable_events.tte_events |= TTEVT_LWP_CREATE; 296846283Sdfr notifiable_events.tte_events |= TTEVT_LWP_EXIT; 296946283Sdfr notifiable_events.tte_events |= TTEVT_LWP_TERMINATE; 297046283Sdfr 297146283Sdfr tt_status = call_real_ttrace ( 297246283Sdfr TT_PROC_SET_EVENT_MASK, 297346283Sdfr real_pid, 297446283Sdfr (lwpid_t) TT_NIL, 297546283Sdfr (TTRACE_ARG_TYPE) ¬ifiable_events, 297646283Sdfr (TTRACE_ARG_TYPE) sizeof (notifiable_events), 297746283Sdfr TT_NIL); 297846283Sdfr} 297946283Sdfr 298046283Sdfrstatic void 298146283Sdfrrequire_notification_of_exec_events ( real_pid ) 298246283Sdfr int real_pid; 298346283Sdfr{ 298446283Sdfr int tt_status; 298546283Sdfr ttevent_t notifiable_events; 298646283Sdfr 298746283Sdfr lwpid_t tid; 298846283Sdfr ttstate_t thread_state; 298946283Sdfr 299046283Sdfr#ifdef THREAD_DEBUG 299146283Sdfr if( debug_on ) 299246283Sdfr printf( "Require notif, pid is %d\n", real_pid ); 299346283Sdfr#endif 299446283Sdfr 299546283Sdfr /* Temporary HACK: tell inftarg.c/child_wait to not 299646283Sdfr * loop until pids are the same. 299746283Sdfr */ 299846283Sdfr not_same_real_pid = 0; 299946283Sdfr 300046283Sdfr sigemptyset (¬ifiable_events.tte_signals); 300146283Sdfr notifiable_events.tte_opts = TTEO_NOSTRCCHLD; 300246283Sdfr 300346283Sdfr /* This ensures that forked children don't inherit their parent's 300446283Sdfr * event mask, which we're setting here. 300546283Sdfr */ 300646283Sdfr notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT; 300746283Sdfr 300846283Sdfr notifiable_events.tte_events = TTEVT_DEFAULT; 300946283Sdfr notifiable_events.tte_events |= TTEVT_EXEC; 301046283Sdfr notifiable_events.tte_events |= TTEVT_EXIT; 301146283Sdfr 301246283Sdfr tt_status = call_real_ttrace ( 301346283Sdfr TT_PROC_SET_EVENT_MASK, 301446283Sdfr real_pid, 301546283Sdfr (lwpid_t) TT_NIL, 301646283Sdfr (TTRACE_ARG_TYPE) ¬ifiable_events, 301746283Sdfr (TTRACE_ARG_TYPE) sizeof (notifiable_events), 301846283Sdfr TT_NIL); 301946283Sdfr} 302046283Sdfr 302146283Sdfr 302246283Sdfr/* This function is called by the parent process, with pid being the 302346283Sdfr * ID of the child process, after the debugger has forked. 302446283Sdfr */ 302546283Sdfrvoid 302646283Sdfrchild_acknowledge_created_inferior (pid) 302746283Sdfr int pid; 302846283Sdfr{ 302946283Sdfr /* We need a memory home for a constant, to pass it to ttrace. 303046283Sdfr The value of the constant is arbitrary, so long as both 303146283Sdfr parent and child use the same value. Might as well use the 303246283Sdfr "magic" constant provided by ttrace... 303346283Sdfr */ 303446283Sdfr uint64_t tc_magic_parent = TT_VERSION; 303546283Sdfr uint64_t tc_magic_child = 0; 303646283Sdfr 303746283Sdfr /* Wait for the child to tell us that it has forked. */ 303846283Sdfr read (startup_semaphore.child_channel[SEM_LISTEN], 303946283Sdfr &tc_magic_child, 304046283Sdfr sizeof(tc_magic_child)); 304146283Sdfr 304246283Sdfr /* Clear thread info now. We'd like to do this in 304346283Sdfr * "require...", but that messes up attach. 304446283Sdfr */ 304546283Sdfr clear_thread_info(); 304646283Sdfr 304746283Sdfr /* Tell the "rest of gdb" that the initial thread exists. 304846283Sdfr * This isn't really a hack. Other thread-based versions 304946283Sdfr * of gdb (e.g. gnu-nat.c) seem to do the same thing. 305046283Sdfr * 305146283Sdfr * Q: Why don't we also add this thread to the local 305246283Sdfr * list via "add_tthread"? 305346283Sdfr * 305446283Sdfr * A: Because we don't know the tid, and can't stop the 305546283Sdfr * the process safely to ask what it is. Anyway, we'll 305646283Sdfr * add it when it gets the EXEC event. 305746283Sdfr */ 305846283Sdfr add_thread( pid ); /* in thread.c */ 305946283Sdfr 306046283Sdfr /* We can now set the child's ttrace event mask. 306146283Sdfr */ 306246283Sdfr require_notification_of_exec_events (pid); 306346283Sdfr 306446283Sdfr /* Tell ourselves that the process is running. 306546283Sdfr */ 306646283Sdfr process_state = RUNNING; 306746283Sdfr 306846283Sdfr /* Notify the child that it can exec. */ 306946283Sdfr write (startup_semaphore.parent_channel[SEM_TALK], 307046283Sdfr &tc_magic_parent, 307146283Sdfr sizeof (tc_magic_parent)); 307246283Sdfr 307346283Sdfr /* Discard our copy of the semaphore. */ 307446283Sdfr (void) close (startup_semaphore.parent_channel[SEM_LISTEN]); 307546283Sdfr (void) close (startup_semaphore.parent_channel[SEM_TALK]); 307646283Sdfr (void) close (startup_semaphore.child_channel[SEM_LISTEN]); 307746283Sdfr (void) close (startup_semaphore.child_channel[SEM_TALK]); 307846283Sdfr} 307946283Sdfr 308046283Sdfr 308146283Sdfr/* 308246283Sdfr * arrange for notification of all events by 308346283Sdfr * calling require_notification_of_events. 308446283Sdfr */ 308546283Sdfrvoid 308646283Sdfrchild_post_startup_inferior ( real_pid) 308746283Sdfr int real_pid; 308846283Sdfr{ 308946283Sdfr require_notification_of_events (real_pid); 309046283Sdfr} 309146283Sdfr 309246283Sdfr/* From here on, we should expect tids rather than pids. 309346283Sdfr */ 309446283Sdfrstatic void 309546283Sdfrhppa_enable_catch_fork (tid) 309646283Sdfr int tid; 309746283Sdfr{ 309846283Sdfr int tt_status; 309946283Sdfr ttevent_t ttrace_events; 310046283Sdfr 310146283Sdfr /* Get the set of events that are currently enabled. 310246283Sdfr */ 310346283Sdfr tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK, 310446283Sdfr tid, 310546283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 310646283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 310746283Sdfr TT_NIL ); 310846283Sdfr if (errno) 310946283Sdfr perror_with_name ("ttrace"); 311046283Sdfr 311146283Sdfr /* Add forks to that set. */ 311246283Sdfr ttrace_events.tte_events |= TTEVT_FORK; 311346283Sdfr 311446283Sdfr#ifdef THREAD_DEBUG 311546283Sdfr if( debug_on ) 311646283Sdfr printf( "enable fork, tid is %d\n", tid ); 311746283Sdfr#endif 311846283Sdfr 311946283Sdfr tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK, 312046283Sdfr tid, 312146283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 312246283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 312346283Sdfr TT_NIL); 312446283Sdfr if (errno) 312546283Sdfr perror_with_name ("ttrace"); 312646283Sdfr} 312746283Sdfr 312846283Sdfr 312946283Sdfrstatic void 313046283Sdfrhppa_disable_catch_fork (tid) 313146283Sdfr int tid; 313246283Sdfr{ 313346283Sdfr int tt_status; 313446283Sdfr ttevent_t ttrace_events; 313546283Sdfr 313646283Sdfr /* Get the set of events that are currently enabled. 313746283Sdfr */ 313846283Sdfr tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK, 313946283Sdfr tid, 314046283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 314146283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 314246283Sdfr TT_NIL); 314346283Sdfr 314446283Sdfr if (errno) 314546283Sdfr perror_with_name ("ttrace"); 314646283Sdfr 314746283Sdfr /* Remove forks from that set. */ 314846283Sdfr ttrace_events.tte_events &= ~TTEVT_FORK; 314946283Sdfr 315046283Sdfr#ifdef THREAD_DEBUG 315146283Sdfr if( debug_on ) 315246283Sdfr printf("disable fork, tid is %d\n", tid ); 315346283Sdfr#endif 315446283Sdfr 315546283Sdfr tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK, 315646283Sdfr tid, 315746283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 315846283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 315946283Sdfr TT_NIL); 316046283Sdfr 316146283Sdfr if (errno) 316246283Sdfr perror_with_name ("ttrace"); 316346283Sdfr} 316446283Sdfr 316546283Sdfr 316646283Sdfr#if defined(CHILD_INSERT_FORK_CATCHPOINT) 316746283Sdfrint 316846283Sdfrchild_insert_fork_catchpoint (tid) 316946283Sdfr int tid; 317046283Sdfr{ 317146283Sdfr /* Enable reporting of fork events from the kernel. */ 317246283Sdfr /* ??rehrauer: For the moment, we're always enabling these events, 317346283Sdfr and just ignoring them if there's no catchpoint to catch them. 317446283Sdfr */ 317546283Sdfr return 0; 317646283Sdfr} 317746283Sdfr#endif 317846283Sdfr 317946283Sdfr 318046283Sdfr#if defined(CHILD_REMOVE_FORK_CATCHPOINT) 318146283Sdfrint 318246283Sdfrchild_remove_fork_catchpoint (tid) 318346283Sdfr int tid; 318446283Sdfr{ 318546283Sdfr /* Disable reporting of fork events from the kernel. */ 318646283Sdfr /* ??rehrauer: For the moment, we're always enabling these events, 318746283Sdfr and just ignoring them if there's no catchpoint to catch them. 318846283Sdfr */ 318946283Sdfr return 0; 319046283Sdfr} 319146283Sdfr#endif 319246283Sdfr 319346283Sdfr 319446283Sdfrstatic void 319546283Sdfrhppa_enable_catch_vfork (tid) 319646283Sdfr int tid; 319746283Sdfr{ 319846283Sdfr int tt_status; 319946283Sdfr ttevent_t ttrace_events; 320046283Sdfr 320146283Sdfr /* Get the set of events that are currently enabled. 320246283Sdfr */ 320346283Sdfr tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK, 320446283Sdfr tid, 320546283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 320646283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 320746283Sdfr TT_NIL); 320846283Sdfr 320946283Sdfr if (errno) 321046283Sdfr perror_with_name ("ttrace"); 321146283Sdfr 321246283Sdfr /* Add vforks to that set. */ 321346283Sdfr ttrace_events.tte_events |= TTEVT_VFORK; 321446283Sdfr 321546283Sdfr#ifdef THREAD_DEBUG 321646283Sdfr if( debug_on ) 321746283Sdfr printf("enable vfork, tid is %d\n", tid ); 321846283Sdfr#endif 321946283Sdfr 322046283Sdfr tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK, 322146283Sdfr tid, 322246283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 322346283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 322446283Sdfr TT_NIL); 322546283Sdfr 322646283Sdfr if (errno) 322746283Sdfr perror_with_name ("ttrace"); 322846283Sdfr} 322946283Sdfr 323046283Sdfr 323146283Sdfrstatic void 323246283Sdfrhppa_disable_catch_vfork (tid) 323346283Sdfr int tid; 323446283Sdfr{ 323546283Sdfr int tt_status; 323646283Sdfr ttevent_t ttrace_events; 323746283Sdfr 323846283Sdfr /* Get the set of events that are currently enabled. */ 323946283Sdfr tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK, 324046283Sdfr tid, 324146283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 324246283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 324346283Sdfr TT_NIL); 324446283Sdfr 324546283Sdfr if (errno) 324646283Sdfr perror_with_name ("ttrace"); 324746283Sdfr 324846283Sdfr /* Remove vforks from that set. */ 324946283Sdfr ttrace_events.tte_events &= ~TTEVT_VFORK; 325046283Sdfr 325146283Sdfr#ifdef THREAD_DEBUG 325246283Sdfr if( debug_on ) 325346283Sdfr printf("disable vfork, tid is %d\n", tid ); 325446283Sdfr#endif 325546283Sdfr tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK, 325646283Sdfr tid, 325746283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 325846283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 325946283Sdfr TT_NIL); 326046283Sdfr 326146283Sdfr if (errno) 326246283Sdfr perror_with_name ("ttrace"); 326346283Sdfr} 326446283Sdfr 326546283Sdfr 326646283Sdfr#if defined(CHILD_INSERT_VFORK_CATCHPOINT) 326746283Sdfrint 326846283Sdfrchild_insert_vfork_catchpoint (tid) 326946283Sdfr int tid; 327046283Sdfr{ 327146283Sdfr /* Enable reporting of vfork events from the kernel. */ 327246283Sdfr /* ??rehrauer: For the moment, we're always enabling these events, 327346283Sdfr and just ignoring them if there's no catchpoint to catch them. 327446283Sdfr */ 327546283Sdfr return 0; 327646283Sdfr} 327746283Sdfr#endif 327846283Sdfr 327946283Sdfr 328046283Sdfr#if defined(CHILD_REMOVE_VFORK_CATCHPOINT) 328146283Sdfrint 328246283Sdfrchild_remove_vfork_catchpoint (tid) 328346283Sdfr int tid; 328446283Sdfr{ 328546283Sdfr /* Disable reporting of vfork events from the kernel. */ 328646283Sdfr /* ??rehrauer: For the moment, we're always enabling these events, 328746283Sdfr and just ignoring them if there's no catchpoint to catch them. 328846283Sdfr */ 328946283Sdfr return 0; 329046283Sdfr} 329146283Sdfr#endif 329246283Sdfr 329346283Sdfr#if defined(CHILD_HAS_FORKED) 329446283Sdfr 329546283Sdfr/* Q: Do we need to map the returned process ID to a thread ID? 329646283Sdfr * 329746283Sdfr * A: I don't think so--here we want a _real_ pid. Any later 329846283Sdfr * operations will call "require_notification_of_events" and 329946283Sdfr * start the mapping. 330046283Sdfr */ 330146283Sdfrint 330246283Sdfrchild_has_forked (tid, childpid) 330346283Sdfr int tid; 330446283Sdfr int *childpid; 330546283Sdfr{ 330646283Sdfr int tt_status; 330746283Sdfr ttstate_t ttrace_state; 330846283Sdfr thread_info * tinfo; 330946283Sdfr 331046283Sdfr /* Do we have cached thread state that we can consult? If so, use it. */ 331146283Sdfr tinfo = find_thread_info (map_from_gdb_tid (tid)); 331246283Sdfr if (tinfo != NULL) { 331346283Sdfr copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state); 331446283Sdfr } 331546283Sdfr 331646283Sdfr /* Nope, must read the thread's current state */ 331746283Sdfr else 331846283Sdfr { 331946283Sdfr tt_status = call_ttrace (TT_LWP_GET_STATE, 332046283Sdfr tid, 332146283Sdfr (TTRACE_ARG_TYPE) &ttrace_state, 332246283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_state), 332346283Sdfr TT_NIL); 332446283Sdfr 332546283Sdfr if (errno) 332646283Sdfr perror_with_name ("ttrace"); 332746283Sdfr 332846283Sdfr if (tt_status < 0) 332946283Sdfr return 0; 333046283Sdfr } 333146283Sdfr 333246283Sdfr if (ttrace_state.tts_event & TTEVT_FORK) 333346283Sdfr { 333446283Sdfr *childpid = ttrace_state.tts_u.tts_fork.tts_fpid; 333546283Sdfr return 1; 333646283Sdfr } 333746283Sdfr 333846283Sdfr return 0; 333946283Sdfr} 334046283Sdfr#endif 334146283Sdfr 334246283Sdfr 334346283Sdfr#if defined(CHILD_HAS_VFORKED) 334446283Sdfr 334546283Sdfr/* See child_has_forked for pid discussion. 334646283Sdfr */ 334746283Sdfrint 334846283Sdfrchild_has_vforked (tid, childpid) 334946283Sdfr int tid; 335046283Sdfr int * childpid; 335146283Sdfr{ 335246283Sdfr int tt_status; 335346283Sdfr ttstate_t ttrace_state; 335446283Sdfr thread_info * tinfo; 335546283Sdfr 335646283Sdfr /* Do we have cached thread state that we can consult? If so, use it. */ 335746283Sdfr tinfo = find_thread_info (map_from_gdb_tid (tid)); 335846283Sdfr if (tinfo != NULL) 335946283Sdfr copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state); 336046283Sdfr 336146283Sdfr /* Nope, must read the thread's current state */ 336246283Sdfr else 336346283Sdfr { 336446283Sdfr tt_status = call_ttrace (TT_LWP_GET_STATE, 336546283Sdfr tid, 336646283Sdfr (TTRACE_ARG_TYPE) &ttrace_state, 336746283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_state), 336846283Sdfr TT_NIL); 336946283Sdfr 337046283Sdfr if (errno) 337146283Sdfr perror_with_name ("ttrace"); 337246283Sdfr 337346283Sdfr if (tt_status < 0) 337446283Sdfr return 0; 337546283Sdfr } 337646283Sdfr 337746283Sdfr if (ttrace_state.tts_event & TTEVT_VFORK) 337846283Sdfr { 337946283Sdfr *childpid = ttrace_state.tts_u.tts_fork.tts_fpid; 338046283Sdfr return 1; 338146283Sdfr } 338246283Sdfr 338346283Sdfr return 0; 338446283Sdfr} 338546283Sdfr#endif 338646283Sdfr 338746283Sdfr 338846283Sdfr#if defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC) 338946283Sdfrint 339046283Sdfrchild_can_follow_vfork_prior_to_exec () 339146283Sdfr{ 339246283Sdfr /* ttrace does allow this. 339346283Sdfr 339446283Sdfr ??rehrauer: However, I had major-league problems trying to 339546283Sdfr convince wait_for_inferior to handle that case. Perhaps when 339646283Sdfr it is rewritten to grok multiple processes in an explicit way... 339746283Sdfr */ 339846283Sdfr return 0; 339946283Sdfr} 340046283Sdfr#endif 340146283Sdfr 340246283Sdfr 340346283Sdfr#if defined(CHILD_INSERT_EXEC_CATCHPOINT) 340446283Sdfrint 340546283Sdfrchild_insert_exec_catchpoint (tid) 340646283Sdfr int tid; 340746283Sdfr{ 340846283Sdfr /* Enable reporting of exec events from the kernel. */ 340946283Sdfr /* ??rehrauer: For the moment, we're always enabling these events, 341046283Sdfr and just ignoring them if there's no catchpoint to catch them. 341146283Sdfr */ 341246283Sdfr return 0; 341346283Sdfr} 341446283Sdfr#endif 341546283Sdfr 341646283Sdfr 341746283Sdfr#if defined(CHILD_REMOVE_EXEC_CATCHPOINT) 341846283Sdfrint 341946283Sdfrchild_remove_exec_catchpoint (tid) 342046283Sdfr int tid; 342146283Sdfr{ 342246283Sdfr /* Disable reporting of execevents from the kernel. */ 342346283Sdfr /* ??rehrauer: For the moment, we're always enabling these events, 342446283Sdfr and just ignoring them if there's no catchpoint to catch them. 342546283Sdfr */ 342646283Sdfr return 0; 342746283Sdfr} 342846283Sdfr#endif 342946283Sdfr 343046283Sdfr 343146283Sdfr#if defined(CHILD_HAS_EXECD) 343246283Sdfrint 343346283Sdfrchild_has_execd (tid, execd_pathname) 343446283Sdfr int tid; 343546283Sdfr char ** execd_pathname; 343646283Sdfr{ 343746283Sdfr int tt_status; 343846283Sdfr ttstate_t ttrace_state; 343946283Sdfr thread_info * tinfo; 344046283Sdfr 344146283Sdfr /* Do we have cached thread state that we can consult? If so, use it. */ 344246283Sdfr tinfo = find_thread_info (map_from_gdb_tid (tid)); 344346283Sdfr if (tinfo != NULL) 344446283Sdfr copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state); 344546283Sdfr 344646283Sdfr /* Nope, must read the thread's current state */ 344746283Sdfr else 344846283Sdfr { 344946283Sdfr tt_status = call_ttrace (TT_LWP_GET_STATE, 345046283Sdfr tid, 345146283Sdfr (TTRACE_ARG_TYPE) &ttrace_state, 345246283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_state), 345346283Sdfr TT_NIL); 345446283Sdfr 345546283Sdfr if (errno) 345646283Sdfr perror_with_name ("ttrace"); 345746283Sdfr 345846283Sdfr if (tt_status < 0) 345946283Sdfr return 0; 346046283Sdfr } 346146283Sdfr 346246283Sdfr if (ttrace_state.tts_event & TTEVT_EXEC) 346346283Sdfr { 346446283Sdfr /* See child_pid_to_exec_file in this file: this is a macro. 346546283Sdfr */ 346646283Sdfr char * exec_file = target_pid_to_exec_file (tid); 346746283Sdfr 346846283Sdfr *execd_pathname = savestring (exec_file, strlen (exec_file)); 346946283Sdfr return 1; 347046283Sdfr } 347146283Sdfr 347246283Sdfr return 0; 347346283Sdfr} 347446283Sdfr#endif 347546283Sdfr 347646283Sdfr 347746283Sdfr#if defined(CHILD_HAS_SYSCALL_EVENT) 347846283Sdfrint 347946283Sdfrchild_has_syscall_event (pid, kind, syscall_id) 348046283Sdfr int pid; 348146283Sdfr enum target_waitkind * kind; 348246283Sdfr int * syscall_id; 348346283Sdfr{ 348446283Sdfr int tt_status; 348546283Sdfr ttstate_t ttrace_state; 348646283Sdfr thread_info * tinfo; 348746283Sdfr 348846283Sdfr /* Do we have cached thread state that we can consult? If so, use it. */ 348946283Sdfr tinfo = find_thread_info (map_from_gdb_tid (pid)); 349046283Sdfr if (tinfo != NULL) 349146283Sdfr copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state); 349246283Sdfr 349346283Sdfr /* Nope, must read the thread's current state */ 349446283Sdfr else 349546283Sdfr { 349646283Sdfr tt_status = call_ttrace (TT_LWP_GET_STATE, 349746283Sdfr pid, 349846283Sdfr (TTRACE_ARG_TYPE) &ttrace_state, 349946283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_state), 350046283Sdfr TT_NIL); 350146283Sdfr 350246283Sdfr if (errno) 350346283Sdfr perror_with_name ("ttrace"); 350446283Sdfr 350546283Sdfr if (tt_status < 0) 350646283Sdfr return 0; 350746283Sdfr } 350846283Sdfr 350946283Sdfr *kind = TARGET_WAITKIND_SPURIOUS; /* Until proven otherwise... */ 351046283Sdfr *syscall_id = -1; 351146283Sdfr 351246283Sdfr if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY) 351346283Sdfr *kind = TARGET_WAITKIND_SYSCALL_ENTRY; 351446283Sdfr else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN) 351546283Sdfr *kind = TARGET_WAITKIND_SYSCALL_RETURN; 351646283Sdfr else 351746283Sdfr return 0; 351846283Sdfr 351946283Sdfr *syscall_id = ttrace_state.tts_scno; 352046283Sdfr return 1; 352146283Sdfr} 352246283Sdfr#endif 352346283Sdfr 352446283Sdfr 352546283Sdfr 352646283Sdfr#if defined(CHILD_THREAD_ALIVE) 352746283Sdfr 352846283Sdfr/* Check to see if the given thread is alive. 352946283Sdfr * 353046283Sdfr * We'll trust the thread list, as the more correct 353146283Sdfr * approach of stopping the process and spinning down 353246283Sdfr * the OS's thread list is _very_ expensive. 353346283Sdfr * 353446283Sdfr * May need a FIXME for that reason. 353546283Sdfr */ 353646283Sdfrint 353746283Sdfrchild_thread_alive (gdb_tid) 353846283Sdfr lwpid_t gdb_tid; 353946283Sdfr{ 354046283Sdfr lwpid_t tid; 354146283Sdfr 354246283Sdfr /* This spins down the lists twice. 354346283Sdfr * Possible peformance improvement here! 354446283Sdfr */ 354546283Sdfr tid = map_from_gdb_tid( gdb_tid ); 354646283Sdfr return !is_terminated( tid ); 354746283Sdfr} 354846283Sdfr 354946283Sdfr#endif 355046283Sdfr 355146283Sdfr 355246283Sdfr 355346283Sdfr/* This function attempts to read the specified number of bytes from the 355446283Sdfr save_state_t that is our view into the hardware registers, starting at 355546283Sdfr ss_offset, and ending at ss_offset + sizeof_buf - 1 355646283Sdfr 355746283Sdfr If this function succeeds, it deposits the fetched bytes into buf, 355846283Sdfr and returns 0. 355946283Sdfr 356046283Sdfr If it fails, it returns a negative result. The contents of buf are 356146283Sdfr undefined it this function fails. 356246283Sdfr */ 356346283Sdfrint 356446283Sdfrread_from_register_save_state (tid, ss_offset, buf, sizeof_buf) 356546283Sdfr int tid; 356646283Sdfr TTRACE_ARG_TYPE ss_offset; 356746283Sdfr char * buf; 356846283Sdfr int sizeof_buf; 356946283Sdfr{ 357046283Sdfr int tt_status; 357146283Sdfr register_value_t register_value = 0; 357246283Sdfr 357346283Sdfr tt_status = call_ttrace (TT_LWP_RUREGS, 357446283Sdfr tid, 357546283Sdfr ss_offset, 357646283Sdfr (TTRACE_ARG_TYPE) sizeof_buf, 357746283Sdfr (TTRACE_ARG_TYPE) buf); 357846283Sdfr 357946283Sdfr if( tt_status == 1 ) 358046283Sdfr /* Map ttrace's version of success to our version. 358146283Sdfr * Sometime ttrace returns 0, but that's ok here. 358246283Sdfr */ 358346283Sdfr return 0; 358446283Sdfr 358546283Sdfr return tt_status; 358646283Sdfr} 358746283Sdfr 358846283Sdfr 358946283Sdfr/* This function attempts to write the specified number of bytes to the 359046283Sdfr save_state_t that is our view into the hardware registers, starting at 359146283Sdfr ss_offset, and ending at ss_offset + sizeof_buf - 1 359246283Sdfr 359346283Sdfr If this function succeeds, it deposits the bytes in buf, and returns 0. 359446283Sdfr 359546283Sdfr If it fails, it returns a negative result. The contents of the save_state_t 359646283Sdfr are undefined it this function fails. 359746283Sdfr */ 359846283Sdfrint 359946283Sdfrwrite_to_register_save_state (tid, ss_offset, buf, sizeof_buf) 360046283Sdfr int tid; 360146283Sdfr TTRACE_ARG_TYPE ss_offset; 360246283Sdfr char * buf; 360346283Sdfr int sizeof_buf; 360446283Sdfr{ 360546283Sdfr int tt_status; 360646283Sdfr register_value_t register_value = 0; 360746283Sdfr 360846283Sdfr tt_status = call_ttrace (TT_LWP_WUREGS, 360946283Sdfr tid, 361046283Sdfr ss_offset, 361146283Sdfr (TTRACE_ARG_TYPE) sizeof_buf, 361246283Sdfr (TTRACE_ARG_TYPE) buf); 361346283Sdfr return tt_status; 361446283Sdfr} 361546283Sdfr 361646283Sdfr 361746283Sdfr/* This function is a sop to the largeish number of direct calls 361846283Sdfr to call_ptrace that exist in other files. Rather than create 361946283Sdfr functions whose name abstracts away from ptrace, and change all 362046283Sdfr the present callers of call_ptrace, we'll do the expedient (and 362146283Sdfr perhaps only practical) thing. 362246283Sdfr 362346283Sdfr Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced 362446283Sdfr process. Thus, we must translate all ptrace requests into their 362546283Sdfr process-specific, ttrace equivalents. 362646283Sdfr */ 362746283Sdfrint 362846283Sdfrcall_ptrace (pt_request, gdb_tid, addr, data) 362946283Sdfr int pt_request; 363046283Sdfr int gdb_tid; 363146283Sdfr PTRACE_ARG3_TYPE addr; 363246283Sdfr int data; 363346283Sdfr{ 363446283Sdfr ttreq_t tt_request; 363546283Sdfr TTRACE_ARG_TYPE tt_addr = (TTRACE_ARG_TYPE) addr; 363646283Sdfr TTRACE_ARG_TYPE tt_data = (TTRACE_ARG_TYPE) data; 363746283Sdfr TTRACE_ARG_TYPE tt_addr2 = TT_NIL; 363846283Sdfr int tt_status; 363946283Sdfr register_value_t register_value; 364046283Sdfr int read_buf; 364146283Sdfr 364246283Sdfr /* Perform the necessary argument translation. Note that some 364346283Sdfr cases are funky enough in the ttrace realm that we handle them 364446283Sdfr very specially. 364546283Sdfr */ 364646283Sdfr switch (pt_request) { 364746283Sdfr /* The following cases cannot conveniently be handled conveniently 364846283Sdfr by merely adjusting the ptrace arguments and feeding into the 364946283Sdfr generic call to ttrace at the bottom of this function. 365046283Sdfr 365146283Sdfr Note that because all branches of this switch end in "return", 365246283Sdfr there's no need for any "break" statements. 365346283Sdfr */ 365446283Sdfr case PT_SETTRC : 365546283Sdfr return parent_attach_all (); 365646283Sdfr 365746283Sdfr case PT_RUREGS : 365846283Sdfr tt_status = read_from_register_save_state (gdb_tid, 365946283Sdfr tt_addr, 366046283Sdfr ®ister_value, 366146283Sdfr sizeof (register_value)); 366246283Sdfr if (tt_status < 0) 366346283Sdfr return tt_status; 366446283Sdfr return register_value; 366546283Sdfr 366646283Sdfr case PT_WUREGS : 366746283Sdfr register_value = (int) tt_data; 366846283Sdfr tt_status = write_to_register_save_state (gdb_tid, 366946283Sdfr tt_addr, 367046283Sdfr ®ister_value, 367146283Sdfr sizeof (register_value)); 367246283Sdfr return tt_status; 367346283Sdfr break; 367446283Sdfr 367546283Sdfr case PT_READ_I : 367646283Sdfr tt_status = call_ttrace (TT_PROC_RDTEXT, /* Implicit 4-byte xfer becomes block-xfer. */ 367746283Sdfr gdb_tid, 367846283Sdfr tt_addr, 367946283Sdfr (TTRACE_ARG_TYPE) 4, 368046283Sdfr (TTRACE_ARG_TYPE) &read_buf); 368146283Sdfr if (tt_status < 0) 368246283Sdfr return tt_status; 368346283Sdfr return read_buf; 368446283Sdfr 368546283Sdfr case PT_READ_D : 368646283Sdfr tt_status = call_ttrace (TT_PROC_RDDATA, /* Implicit 4-byte xfer becomes block-xfer. */ 368746283Sdfr gdb_tid, 368846283Sdfr tt_addr, 368946283Sdfr (TTRACE_ARG_TYPE) 4, 369046283Sdfr (TTRACE_ARG_TYPE) &read_buf); 369146283Sdfr if (tt_status < 0) 369246283Sdfr return tt_status; 369346283Sdfr return read_buf; 369446283Sdfr 369546283Sdfr case PT_ATTACH : 369646283Sdfr tt_status = call_real_ttrace (TT_PROC_ATTACH, 369746283Sdfr map_from_gdb_tid (gdb_tid), 369846283Sdfr (lwpid_t) TT_NIL, 369946283Sdfr tt_addr, 370046283Sdfr (TTRACE_ARG_TYPE) TT_VERSION, 370146283Sdfr tt_addr2); 370246283Sdfr if (tt_status < 0) 370346283Sdfr return tt_status; 370446283Sdfr return tt_status; 370546283Sdfr 370646283Sdfr /* The following cases are handled by merely adjusting the ptrace 370746283Sdfr arguments and feeding into the generic call to ttrace. 370846283Sdfr */ 370946283Sdfr case PT_DETACH : 371046283Sdfr tt_request = TT_PROC_DETACH; 371146283Sdfr break; 371246283Sdfr 371346283Sdfr case PT_WRITE_I : 371446283Sdfr tt_request = TT_PROC_WRTEXT; /* Translates 4-byte xfer to block-xfer. */ 371546283Sdfr tt_data = 4; /* This many bytes. */ 371646283Sdfr tt_addr2 = (TTRACE_ARG_TYPE) &data; /* Address of xfer source. */ 371746283Sdfr break; 371846283Sdfr 371946283Sdfr case PT_WRITE_D : 372046283Sdfr tt_request = TT_PROC_WRDATA; /* Translates 4-byte xfer to block-xfer. */ 372146283Sdfr tt_data = 4; /* This many bytes. */ 372246283Sdfr tt_addr2 = (TTRACE_ARG_TYPE) &data; /* Address of xfer source. */ 372346283Sdfr break; 372446283Sdfr 372546283Sdfr case PT_RDTEXT : 372646283Sdfr tt_request = TT_PROC_RDTEXT; 372746283Sdfr break; 372846283Sdfr 372946283Sdfr case PT_RDDATA : 373046283Sdfr tt_request = TT_PROC_RDDATA; 373146283Sdfr break; 373246283Sdfr 373346283Sdfr case PT_WRTEXT : 373446283Sdfr tt_request = TT_PROC_WRTEXT; 373546283Sdfr break; 373646283Sdfr 373746283Sdfr case PT_WRDATA : 373846283Sdfr tt_request = TT_PROC_WRDATA; 373946283Sdfr break; 374046283Sdfr 374146283Sdfr case PT_CONTINUE : 374246283Sdfr tt_request = TT_PROC_CONTINUE; 374346283Sdfr break; 374446283Sdfr 374546283Sdfr case PT_STEP : 374646283Sdfr tt_request = TT_LWP_SINGLE; /* Should not be making this request? */ 374746283Sdfr break; 374846283Sdfr 374946283Sdfr case PT_KILL : 375046283Sdfr tt_request = TT_PROC_EXIT; 375146283Sdfr break; 375246283Sdfr 375346283Sdfr case PT_GET_PROCESS_PATHNAME : 375446283Sdfr tt_request = TT_PROC_GET_PATHNAME; 375546283Sdfr break; 375646283Sdfr 375746283Sdfr default : 375846283Sdfr tt_request = pt_request; /* Let ttrace be the one to complain. */ 375946283Sdfr break; 376046283Sdfr } 376146283Sdfr 376246283Sdfr return call_ttrace (tt_request, 376346283Sdfr gdb_tid, 376446283Sdfr tt_addr, 376546283Sdfr tt_data, 376646283Sdfr tt_addr2); 376746283Sdfr} 376846283Sdfr 376946283Sdfr/* Kill that pesky process! 377046283Sdfr */ 377146283Sdfrvoid 377246283Sdfrkill_inferior () 377346283Sdfr{ 377446283Sdfr int tid; 377546283Sdfr int wait_status; 377646283Sdfr thread_info * t; 377746283Sdfr thread_info **paranoia; 377846283Sdfr int para_count, i; 377946283Sdfr 378046283Sdfr if (inferior_pid == 0) 378146283Sdfr return; 378246283Sdfr 378346283Sdfr /* Walk the list of "threads", some of which are "pseudo threads", 378446283Sdfr aka "processes". For each that is NOT inferior_pid, stop it, 378546283Sdfr and detach it. 378646283Sdfr 378746283Sdfr You see, we may not have just a single process to kill. If we're 378846283Sdfr restarting or quitting or detaching just after the inferior has 378946283Sdfr forked, then we've actually two processes to clean up. 379046283Sdfr 379146283Sdfr But we can't just call target_mourn_inferior() for each, since that 379246283Sdfr zaps the target vector. 379346283Sdfr */ 379446283Sdfr 379546283Sdfr paranoia = (thread_info **) malloc( thread_head.count * 379646283Sdfr sizeof(thread_info *)); 379746283Sdfr para_count = 0; 379846283Sdfr 379946283Sdfr t = thread_head.head; 380046283Sdfr while (t) { 380146283Sdfr 380246283Sdfr paranoia[ para_count ] = t; 380346283Sdfr for( i = 0; i < para_count; i++ ){ 380446283Sdfr if( t->next == paranoia[i] ) { 380546283Sdfr warning( "Bad data in gdb's thread data; repairing." ); 380646283Sdfr t->next = 0; 380746283Sdfr } 380846283Sdfr } 380946283Sdfr para_count++; 381046283Sdfr 381146283Sdfr if (t->am_pseudo && (t->pid != inferior_pid)) 381246283Sdfr { 381346283Sdfr /* TT_PROC_STOP doesn't require a subsequent ttrace_wait, as it 381446283Sdfr * generates no event. 381546283Sdfr */ 381646283Sdfr call_ttrace (TT_PROC_STOP, 381746283Sdfr t->pid, 381846283Sdfr TT_NIL, 381946283Sdfr TT_NIL, 382046283Sdfr TT_NIL); 382146283Sdfr 382246283Sdfr call_ttrace (TT_PROC_DETACH, 382346283Sdfr t->pid, 382446283Sdfr TT_NIL, 382546283Sdfr (TTRACE_ARG_TYPE) TARGET_SIGNAL_0, 382646283Sdfr TT_NIL); 382746283Sdfr } 382846283Sdfr t = t->next; 382946283Sdfr } 383046283Sdfr 383146283Sdfr free( paranoia ); 383246283Sdfr 383346283Sdfr call_ttrace (TT_PROC_STOP, 383446283Sdfr inferior_pid, 383546283Sdfr TT_NIL, 383646283Sdfr TT_NIL, 383746283Sdfr TT_NIL); 383846283Sdfr target_mourn_inferior (); 383946283Sdfr clear_thread_info(); 384046283Sdfr} 384146283Sdfr 384246283Sdfr 384346283Sdfr#ifndef CHILD_RESUME 384446283Sdfr 384546283Sdfr/* Sanity check a thread about to be continued. 384646283Sdfr */ 384746283Sdfrstatic void 384846283Sdfrthread_dropping_event_check( p ) 384946283Sdfr thread_info *p; 385046283Sdfr{ 385146283Sdfr if( !p->handled ) { 385246283Sdfr /* 385346283Sdfr * This seems to happen when we "next" over a 385446283Sdfr * "fork()" while following the parent. If it's 385546283Sdfr * the FORK event, that's ok. If it's a SIGNAL 385646283Sdfr * in the unfollowed child, that's ok to--but 385746283Sdfr * how can we know that's what's going on? 385846283Sdfr * 385946283Sdfr * FIXME! 386046283Sdfr */ 386146283Sdfr if( p->have_state ) { 386246283Sdfr if( p->last_stop_state.tts_event == TTEVT_FORK ) { 386346283Sdfr /* Ok */ 386446283Sdfr ; 386546283Sdfr } 386646283Sdfr else if( p->last_stop_state.tts_event == TTEVT_SIGNAL ) { 386746283Sdfr /* Ok, close eyes and let it happen. 386846283Sdfr */ 386946283Sdfr ; 387046283Sdfr } 387146283Sdfr else { 387246283Sdfr /* This shouldn't happen--we're dropping a 387346283Sdfr * real event. 387446283Sdfr */ 387546283Sdfr warning( "About to continue process %d, thread %d with unhandled event %s.", 387646283Sdfr p->pid, p->tid, 387746283Sdfr get_printable_name_of_ttrace_event( 387846283Sdfr p->last_stop_state.tts_event )); 387946283Sdfr 388046283Sdfr#ifdef PARANOIA 388146283Sdfr if( debug_on ) 388246283Sdfr print_tthread( p ); 388346283Sdfr#endif 388446283Sdfr } 388546283Sdfr } 388646283Sdfr else { 388746283Sdfr /* No saved state, have to assume it failed. 388846283Sdfr */ 388946283Sdfr warning( "About to continue process %d, thread %d with unhandled event.", 389046283Sdfr p->pid, p->tid ); 389146283Sdfr#ifdef PARANOIA 389246283Sdfr if( debug_on ) 389346283Sdfr print_tthread( p ); 389446283Sdfr#endif 389546283Sdfr } 389646283Sdfr } 389746283Sdfr 389846283Sdfr} /* thread_dropping_event_check */ 389946283Sdfr 390046283Sdfr/* Use a loop over the threads to continue all the threads but 390146283Sdfr * the one specified, which is to be stepped. 390246283Sdfr */ 390346283Sdfrstatic void 390446283Sdfrthreads_continue_all_but_one( gdb_tid, signal ) 390546283Sdfr lwpid_t gdb_tid; 390646283Sdfr int signal; 390746283Sdfr{ 390846283Sdfr thread_info *p; 390946283Sdfr int thread_signal; 391046283Sdfr lwpid_t real_tid; 391146283Sdfr lwpid_t scan_tid; 391246283Sdfr ttstate_t state; 391346283Sdfr int real_pid; 391446283Sdfr 391546283Sdfr#ifdef THREAD_DEBUG 391646283Sdfr if( debug_on ) 391746283Sdfr printf( "Using loop over threads to step/resume with signals\n" ); 391846283Sdfr#endif 391946283Sdfr 392046283Sdfr /* First update the thread list. 392146283Sdfr */ 392246283Sdfr set_all_unseen(); 392346283Sdfr real_tid = map_from_gdb_tid( gdb_tid ); 392446283Sdfr real_pid = get_pid_for( real_tid ); 392546283Sdfr 392646283Sdfr scan_tid = get_process_first_stopped_thread_id( real_pid, &state ); 392746283Sdfr while ( 0 != scan_tid ) { 392846283Sdfr 392946283Sdfr#ifdef THREAD_DEBUG 393046283Sdfr /* FIX: later should check state is stopped; 393146283Sdfr * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED 393246283Sdfr */ 393346283Sdfr if( debug_on ) 393446283Sdfr if( state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED ) 393546283Sdfr printf( "About to continue non-stopped thread %d\n", scan_tid ); 393646283Sdfr#endif 393746283Sdfr 393846283Sdfr p = find_thread_info( scan_tid ); 393946283Sdfr if( NULL == p ) { 394046283Sdfr add_tthread( real_pid, scan_tid ); 394146283Sdfr p = find_thread_info( scan_tid ); 394246283Sdfr 394346283Sdfr /* This is either a newly-created thread or the 394446283Sdfr * result of a fork; in either case there's no 394546283Sdfr * actual event to worry about. 394646283Sdfr */ 394746283Sdfr p->handled = 1; 394846283Sdfr 394946283Sdfr if( state.tts_event != TTEVT_NONE ) { 395046283Sdfr /* Oops, do need to worry! 395146283Sdfr */ 395246283Sdfr warning( "Unexpected thread with \"%s\" event.", 395346283Sdfr get_printable_name_of_ttrace_event( state.tts_event )); 395446283Sdfr } 395546283Sdfr } 395646283Sdfr else if( scan_tid != p->tid ) 395746283Sdfr error( "Bad data in thread database." ); 395846283Sdfr 395946283Sdfr#ifdef THREAD_DEBUG 396046283Sdfr if( debug_on ) 396146283Sdfr if( p->terminated ) 396246283Sdfr printf( "Why are we continuing a dead thread?\n" ); 396346283Sdfr#endif 396446283Sdfr 396546283Sdfr p->seen = 1; 396646283Sdfr 396746283Sdfr scan_tid = get_process_next_stopped_thread_id( real_pid, &state ); 396846283Sdfr } 396946283Sdfr 397046283Sdfr /* Remove unseen threads. 397146283Sdfr */ 397246283Sdfr update_thread_list(); 397346283Sdfr 397446283Sdfr /* Now run down the thread list and continue or step. 397546283Sdfr */ 397646283Sdfr for( p = thread_head.head; p; p = p->next ) { 397746283Sdfr 397846283Sdfr /* Sanity check. 397946283Sdfr */ 398046283Sdfr thread_dropping_event_check( p ); 398146283Sdfr 398246283Sdfr /* Pass the correct signals along. 398346283Sdfr */ 398446283Sdfr if( p->have_signal ) { 398546283Sdfr thread_signal = p->signal_value; 398646283Sdfr p->have_signal = 0; 398746283Sdfr } 398846283Sdfr else 398946283Sdfr thread_signal = 0; 399046283Sdfr 399146283Sdfr if( p->tid != real_tid ) { 399246283Sdfr /* 399346283Sdfr * Not the thread of interest, so continue it 399446283Sdfr * as the user expects. 399546283Sdfr */ 399646283Sdfr if( p->stepping_mode == DO_STEP ) { 399746283Sdfr /* Just step this thread. 399846283Sdfr */ 399946283Sdfr call_ttrace( 400046283Sdfr TT_LWP_SINGLE, 400146283Sdfr p->tid, 400246283Sdfr TT_USE_CURRENT_PC, 400346283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host( signal ), 400446283Sdfr TT_NIL ); 400546283Sdfr } 400646283Sdfr else { 400746283Sdfr /* Regular continue (default case). 400846283Sdfr */ 400946283Sdfr call_ttrace( 401046283Sdfr TT_LWP_CONTINUE, 401146283Sdfr p->tid, 401246283Sdfr TT_USE_CURRENT_PC, 401346283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host( thread_signal ), 401446283Sdfr TT_NIL ); 401546283Sdfr } 401646283Sdfr } 401746283Sdfr else { 401846283Sdfr /* Step the thread of interest. 401946283Sdfr */ 402046283Sdfr call_ttrace( 402146283Sdfr TT_LWP_SINGLE, 402246283Sdfr real_tid, 402346283Sdfr TT_USE_CURRENT_PC, 402446283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host( signal ), 402546283Sdfr TT_NIL ); 402646283Sdfr } 402746283Sdfr } /* Loop over threads */ 402846283Sdfr} /* End threads_continue_all_but_one */ 402946283Sdfr 403046283Sdfr/* Use a loop over the threads to continue all the threads. 403146283Sdfr * This is done when a signal must be sent to any of the threads. 403246283Sdfr */ 403346283Sdfrstatic void 403446283Sdfrthreads_continue_all_with_signals( gdb_tid, signal ) 403546283Sdfr lwpid_t gdb_tid; 403646283Sdfr int signal; 403746283Sdfr{ 403846283Sdfr thread_info *p; 403946283Sdfr int thread_signal; 404046283Sdfr lwpid_t real_tid; 404146283Sdfr lwpid_t scan_tid; 404246283Sdfr ttstate_t state; 404346283Sdfr int real_pid; 404446283Sdfr 404546283Sdfr#ifdef THREAD_DEBUG 404646283Sdfr if( debug_on ) 404746283Sdfr printf( "Using loop over threads to resume with signals\n" ); 404846283Sdfr#endif 404946283Sdfr 405046283Sdfr /* Scan and update thread list. 405146283Sdfr */ 405246283Sdfr set_all_unseen(); 405346283Sdfr real_tid = map_from_gdb_tid( gdb_tid ); 405446283Sdfr real_pid = get_pid_for( real_tid ); 405546283Sdfr 405646283Sdfr scan_tid = get_process_first_stopped_thread_id( real_pid, &state ); 405746283Sdfr while ( 0 != scan_tid ) { 405846283Sdfr 405946283Sdfr#ifdef THREAD_DEBUG 406046283Sdfr if( debug_on ) 406146283Sdfr if( state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED ) 406246283Sdfr warning( "About to continue non-stopped thread %d\n", scan_tid ); 406346283Sdfr#endif 406446283Sdfr 406546283Sdfr p = find_thread_info( scan_tid ); 406646283Sdfr if( NULL == p ) { 406746283Sdfr add_tthread( real_pid, scan_tid ); 406846283Sdfr p = find_thread_info( scan_tid ); 406946283Sdfr 407046283Sdfr /* This is either a newly-created thread or the 407146283Sdfr * result of a fork; in either case there's no 407246283Sdfr * actual event to worry about. 407346283Sdfr */ 407446283Sdfr p->handled = 1; 407546283Sdfr 407646283Sdfr if( state.tts_event != TTEVT_NONE ) { 407746283Sdfr /* Oops, do need to worry! 407846283Sdfr */ 407946283Sdfr warning( "Unexpected thread with \"%s\" event.", 408046283Sdfr get_printable_name_of_ttrace_event( state.tts_event )); 408146283Sdfr } 408246283Sdfr } 408346283Sdfr 408446283Sdfr#ifdef THREAD_DEBUG 408546283Sdfr if( debug_on ) 408646283Sdfr if( p->terminated ) 408746283Sdfr printf( "Why are we continuing a dead thread? (1)\n" ); 408846283Sdfr#endif 408946283Sdfr 409046283Sdfr p->seen = 1; 409146283Sdfr 409246283Sdfr scan_tid = get_process_next_stopped_thread_id( real_pid, &state ); 409346283Sdfr } 409446283Sdfr 409546283Sdfr /* Remove unseen threads from our list. 409646283Sdfr */ 409746283Sdfr update_thread_list(); 409846283Sdfr 409946283Sdfr /* Continue the threads. 410046283Sdfr */ 410146283Sdfr for( p = thread_head.head; p; p = p->next ) { 410246283Sdfr 410346283Sdfr /* Sanity check. 410446283Sdfr */ 410546283Sdfr thread_dropping_event_check( p ); 410646283Sdfr 410746283Sdfr /* Pass the correct signals along. 410846283Sdfr */ 410946283Sdfr if( p->tid == real_tid ) { 411046283Sdfr thread_signal = signal; 411146283Sdfr p->have_signal = 0; 411246283Sdfr } 411346283Sdfr else if( p->have_signal ) { 411446283Sdfr thread_signal = p->signal_value; 411546283Sdfr p->have_signal = 0; 411646283Sdfr } 411746283Sdfr else 411846283Sdfr thread_signal = 0; 411946283Sdfr 412046283Sdfr if( p->stepping_mode == DO_STEP ) { 412146283Sdfr call_ttrace( 412246283Sdfr TT_LWP_SINGLE, 412346283Sdfr p->tid, 412446283Sdfr TT_USE_CURRENT_PC, 412546283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host( signal ), 412646283Sdfr TT_NIL ); 412746283Sdfr } 412846283Sdfr else { 412946283Sdfr /* Continue this thread (default case). 413046283Sdfr */ 413146283Sdfr call_ttrace( 413246283Sdfr TT_LWP_CONTINUE, 413346283Sdfr p->tid, 413446283Sdfr TT_USE_CURRENT_PC, 413546283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host( thread_signal ), 413646283Sdfr TT_NIL ); 413746283Sdfr } 413846283Sdfr } 413946283Sdfr} /* End threads_continue_all_with_signals */ 414046283Sdfr 414146283Sdfr/* Step one thread only. 414246283Sdfr */ 414346283Sdfrstatic void 414446283Sdfrthread_fake_step( tid, signal ) 414546283Sdfr lwpid_t tid; 414646283Sdfr enum target_signal signal; 414746283Sdfr{ 414846283Sdfr thread_info *p; 414946283Sdfr 415046283Sdfr#ifdef THREAD_DEBUG 415146283Sdfr if( debug_on ) { 415246283Sdfr printf( "Doing a fake-step over a bpt, etc. for %d\n", tid ); 415346283Sdfr 415446283Sdfr if( is_terminated( tid )) 415546283Sdfr printf( "Why are we continuing a dead thread? (4)\n" ); 415646283Sdfr } 415746283Sdfr#endif 415846283Sdfr 415946283Sdfr if( doing_fake_step ) 416046283Sdfr warning( "Step while step already in progress." ); 416146283Sdfr 416246283Sdfr /* See if there's a saved signal value for this 416346283Sdfr * thread to be passed on, but no current signal. 416446283Sdfr */ 416546283Sdfr p = find_thread_info( tid ); 416646283Sdfr if( p != NULL ) { 416746283Sdfr if( p->have_signal && signal == NULL ) { 416846283Sdfr /* Pass on a saved signal. 416946283Sdfr */ 417046283Sdfr signal = p->signal_value; 417146283Sdfr } 417246283Sdfr 417346283Sdfr p->have_signal = 0; 417446283Sdfr } 417546283Sdfr 417646283Sdfr if( !p->handled ) 417746283Sdfr warning( "Internal error: continuing unhandled thread." ); 417846283Sdfr 417946283Sdfr call_ttrace( TT_LWP_SINGLE, 418046283Sdfr tid, 418146283Sdfr TT_USE_CURRENT_PC, 418246283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host (signal), 418346283Sdfr TT_NIL ); 418446283Sdfr 418546283Sdfr /* Do bookkeeping so "call_ttrace_wait" knows it has to wait 418646283Sdfr * for this thread only, and clear any saved signal info. 418746283Sdfr */ 418846283Sdfr doing_fake_step = 1; 418946283Sdfr fake_step_tid = tid; 419046283Sdfr 419146283Sdfr} /* End thread_fake_step */ 419246283Sdfr 419346283Sdfr/* Continue one thread when a signal must be sent to it. 419446283Sdfr */ 419546283Sdfrstatic void 419646283Sdfrthreads_continue_one_with_signal( gdb_tid, signal ) 419746283Sdfr lwpid_t gdb_tid; 419846283Sdfr int signal; 419946283Sdfr{ 420046283Sdfr thread_info *p; 420146283Sdfr lwpid_t real_tid; 420246283Sdfr int real_pid; 420346283Sdfr 420446283Sdfr#ifdef THREAD_DEBUG 420546283Sdfr if( debug_on ) 420646283Sdfr printf( "Continuing one thread with a signal\n" ); 420746283Sdfr#endif 420846283Sdfr 420946283Sdfr real_tid = map_from_gdb_tid( gdb_tid ); 421046283Sdfr real_pid = get_pid_for( real_tid ); 421146283Sdfr 421246283Sdfr p = find_thread_info( real_tid ); 421346283Sdfr if( NULL == p ) { 421446283Sdfr add_tthread( real_pid, real_tid ); 421546283Sdfr } 421646283Sdfr 421746283Sdfr#ifdef THREAD_DEBUG 421846283Sdfr if( debug_on ) 421946283Sdfr if( p->terminated ) 422046283Sdfr printf( "Why are we continuing a dead thread? (2)\n" ); 422146283Sdfr#endif 422246283Sdfr 422346283Sdfr if( !p->handled ) 422446283Sdfr warning( "Internal error: continuing unhandled thread." ); 422546283Sdfr 422646283Sdfr p->have_signal = 0; 422746283Sdfr 422846283Sdfr call_ttrace( TT_LWP_CONTINUE, 422946283Sdfr gdb_tid, 423046283Sdfr TT_USE_CURRENT_PC, 423146283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host( signal ), 423246283Sdfr TT_NIL ); 423346283Sdfr} 423446283Sdfr#endif 423546283Sdfr 423646283Sdfr#ifndef CHILD_RESUME 423746283Sdfr 423846283Sdfr/* Resume execution of the inferior process. 423946283Sdfr * 424046283Sdfr * This routine is in charge of setting the "handled" bits. 424146283Sdfr * 424246283Sdfr * If STEP is zero, continue it. 424346283Sdfr * If STEP is nonzero, single-step it. 424446283Sdfr * 424546283Sdfr * If SIGNAL is nonzero, give it that signal. 424646283Sdfr * 424746283Sdfr * If TID is -1, apply to all threads. 424846283Sdfr * If TID is not -1, apply to specified thread. 424946283Sdfr * 425046283Sdfr * STEP 425146283Sdfr * \ !0 0 425246283Sdfr * TID \________________________________________________ 425346283Sdfr * | 425446283Sdfr * -1 | Step current Continue all threads 425546283Sdfr * | thread and (but which gets any 425646283Sdfr * | continue others signal?--We look at 425746283Sdfr * | "inferior_pid") 425846283Sdfr * | 425946283Sdfr * N | Step _this_ thread Continue _this_ thread 426046283Sdfr * | and leave others and leave others 426146283Sdfr * | stopped; internally stopped; used only for 426246283Sdfr * | used by gdb, never hardware watchpoints 426346283Sdfr * | a user command. and attach, never a 426446283Sdfr * | user command. 426546283Sdfr */ 426646283Sdfrvoid 426746283Sdfrchild_resume( gdb_tid, step, signal ) 426846283Sdfr lwpid_t gdb_tid; 426946283Sdfr int step; 427046283Sdfr enum target_signal signal; 427146283Sdfr{ 427246283Sdfr int resume_all_threads; 427346283Sdfr lwpid_t tid; 427446283Sdfr process_state_t new_process_state; 427546283Sdfr 427646283Sdfr resume_all_threads = 427746283Sdfr (gdb_tid == INFTTRACE_ALL_THREADS) || 427846283Sdfr (vfork_in_flight); 427946283Sdfr 428046283Sdfr if (resume_all_threads) { 428146283Sdfr /* Resume all threads, but first pick a tid value 428246283Sdfr * so we can get the pid when in call_ttrace doing 428346283Sdfr * the map. 428446283Sdfr */ 428546283Sdfr if (vfork_in_flight) 428646283Sdfr tid = vforking_child_pid; 428746283Sdfr else 428846283Sdfr tid = map_from_gdb_tid( inferior_pid ); 428946283Sdfr } 429046283Sdfr else 429146283Sdfr tid = map_from_gdb_tid( gdb_tid ); 429246283Sdfr 429346283Sdfr#ifdef THREAD_DEBUG 429446283Sdfr if( debug_on ) { 429546283Sdfr if( more_events_left ) 429646283Sdfr printf( "More events; " ); 429746283Sdfr 429846283Sdfr if( signal != 0 ) 429946283Sdfr printf( "Sending signal %d; ", signal ); 430046283Sdfr 430146283Sdfr if( resume_all_threads ) { 430246283Sdfr if( step == 0 ) 430346283Sdfr printf( "Continue process %d\n", tid ); 430446283Sdfr else 430546283Sdfr printf( "Step/continue thread %d\n", tid ); 430646283Sdfr } 430746283Sdfr else { 430846283Sdfr if( step == 0 ) 430946283Sdfr printf( "Continue thread %d\n", tid ); 431046283Sdfr else 431146283Sdfr printf( "Step just thread %d\n", tid ); 431246283Sdfr } 431346283Sdfr 431446283Sdfr if( vfork_in_flight ) 431546283Sdfr printf( "Vfork in flight\n" ); 431646283Sdfr } 431746283Sdfr#endif 431846283Sdfr 431946283Sdfr if( process_state == RUNNING ) 432046283Sdfr warning( "Internal error in resume logic; doing resume or step anyway." ); 432146283Sdfr 432246283Sdfr if( !step /* Asked to continue... */ 432346283Sdfr && resume_all_threads /* whole process.. */ 432446283Sdfr && signal != 0 /* with a signal... */ 432546283Sdfr && more_events_left > 0 ) { /* but we can't yet--save it! */ 432646283Sdfr 432746283Sdfr /* Continue with signal means we have to set the pending 432846283Sdfr * signal value for this thread. 432946283Sdfr */ 433046283Sdfr thread_info *k; 433146283Sdfr 433246283Sdfr#ifdef THREAD_DEBUG 433346283Sdfr if( debug_on ) 433446283Sdfr printf( "Saving signal %d for thread %d\n", signal, tid ); 433546283Sdfr#endif 433646283Sdfr 433746283Sdfr k = find_thread_info( tid ); 433846283Sdfr if( k != NULL ) { 433946283Sdfr k->have_signal = 1; 434046283Sdfr k->signal_value = signal; 434146283Sdfr 434246283Sdfr#ifdef THREAD_DEBUG 434346283Sdfr if( debug_on ) 434446283Sdfr if( k->terminated ) 434546283Sdfr printf( "Why are we continuing a dead thread? (3)\n" ); 434646283Sdfr#endif 434746283Sdfr 434846283Sdfr } 434946283Sdfr 435046283Sdfr#ifdef THREAD_DEBUG 435146283Sdfr else if( debug_on ) { 435246283Sdfr printf( "No thread info for tid %d\n", tid ); 435346283Sdfr } 435446283Sdfr#endif 435546283Sdfr } 435646283Sdfr 435746283Sdfr /* Are we faking this "continue" or "step"? 435846283Sdfr * 435946283Sdfr * We used to do steps by continuing all the threads for 436046283Sdfr * which the events had been handled already. While 436146283Sdfr * conceptually nicer (hides it all in a lower level), this 436246283Sdfr * can lead to starvation and a hang (e.g. all but one thread 436346283Sdfr * are unhandled at a breakpoint just before a "join" operation, 436446283Sdfr * and one thread is in the join, and the user wants to step that 436546283Sdfr * thread). 436646283Sdfr */ 436746283Sdfr if( resume_all_threads /* Whole process, therefore user command */ 436846283Sdfr && more_events_left > 0 ) { /* But we can't do this yet--fake it! */ 436946283Sdfr thread_info *p; 437046283Sdfr 437146283Sdfr if( !step ) { 437246283Sdfr /* No need to do any notes on a per-thread 437346283Sdfr * basis--we're done! 437446283Sdfr */ 437546283Sdfr#ifdef WAIT_BUFFER_DEBUG 437646283Sdfr if( debug_on ) 437746283Sdfr printf( "Faking a process resume.\n" ); 437846283Sdfr#endif 437946283Sdfr 438046283Sdfr return; 438146283Sdfr } 438246283Sdfr else { 438346283Sdfr 438446283Sdfr#ifdef WAIT_BUFFER_DEBUG 438546283Sdfr if( debug_on ) 438646283Sdfr printf( "Faking a process step.\n" ); 438746283Sdfr#endif 438846283Sdfr 438946283Sdfr } 439046283Sdfr 439146283Sdfr p = find_thread_info( tid ); 439246283Sdfr if( p == NULL ) { 439346283Sdfr warning( "No thread information for tid %d, 'next' command ignored.\n", tid ); 439446283Sdfr return; 439546283Sdfr } 439646283Sdfr else { 439746283Sdfr 439846283Sdfr#ifdef THREAD_DEBUG 439946283Sdfr if( debug_on ) 440046283Sdfr if( p->terminated ) 440146283Sdfr printf( "Why are we continuing a dead thread? (3.5)\n" ); 440246283Sdfr#endif 440346283Sdfr 440446283Sdfr if( p->stepping_mode != DO_DEFAULT ) { 440546283Sdfr warning( "Step or continue command applied to thread which is already stepping or continuing; command ignored." ); 440646283Sdfr 440746283Sdfr return; 440846283Sdfr } 440946283Sdfr 441046283Sdfr if( step ) 441146283Sdfr p->stepping_mode = DO_STEP; 441246283Sdfr else 441346283Sdfr p->stepping_mode = DO_CONTINUE; 441446283Sdfr 441546283Sdfr return; 441646283Sdfr } /* Have thread info */ 441746283Sdfr } /* Must fake step or go */ 441846283Sdfr 441946283Sdfr /* Execept for fake-steps, from here on we know we are 442046283Sdfr * going to wind up with a running process which will 442146283Sdfr * need a real wait. 442246283Sdfr */ 442346283Sdfr new_process_state = RUNNING; 442446283Sdfr 442546283Sdfr /* An address of TT_USE_CURRENT_PC tells ttrace to continue from where 442646283Sdfr * it was. (If GDB wanted it to start some other way, we have already 442746283Sdfr * written a new PC value to the child.) 442846283Sdfr * 442946283Sdfr * If this system does not support PT_STEP, a higher level function will 443046283Sdfr * have called single_step() to transmute the step request into a 443146283Sdfr * continue request (by setting breakpoints on all possible successor 443246283Sdfr * instructions), so we don't have to worry about that here. 443346283Sdfr */ 443446283Sdfr if (step) { 443546283Sdfr if( resume_all_threads ) { 443646283Sdfr /* 443746283Sdfr * Regular user step: other threads get a "continue". 443846283Sdfr */ 443946283Sdfr threads_continue_all_but_one( tid, signal ); 444046283Sdfr clear_all_handled(); 444146283Sdfr clear_all_stepping_mode(); 444246283Sdfr } 444346283Sdfr 444446283Sdfr else { 444546283Sdfr /* "Fake step": gdb is stepping one thread over a 444646283Sdfr * breakpoint, watchpoint, or out of a library load 444746283Sdfr * event, etc. The rest just stay where they are. 444846283Sdfr * 444946283Sdfr * Also used when there are pending events: we really 445046283Sdfr * step the current thread, but leave the rest stopped. 445146283Sdfr * Users can't request this, but "wait_for_inferior" 445246283Sdfr * does--a lot! 445346283Sdfr */ 445446283Sdfr thread_fake_step( tid, signal ); 445546283Sdfr 445646283Sdfr /* Clear the "handled" state of this thread, because 445746283Sdfr * we'll soon get a new event for it. Other events 445846283Sdfr * stay as they were. 445946283Sdfr */ 446046283Sdfr clear_handled( tid ); 446146283Sdfr clear_stepping_mode( tid ); 446246283Sdfr new_process_state = FAKE_STEPPING; 446346283Sdfr } 446446283Sdfr } 446546283Sdfr 446646283Sdfr else { 446746283Sdfr /* TT_LWP_CONTINUE can pass signals to threads, 446846283Sdfr * TT_PROC_CONTINUE can't. So if there are any 446946283Sdfr * signals to pass, we have to use the (slower) 447046283Sdfr * loop over the stopped threads. 447146283Sdfr * 447246283Sdfr * Equally, if we have to not continue some threads, 447346283Sdfr * due to saved events, we have to use the loop. 447446283Sdfr */ 447546283Sdfr if( (signal != 0) || saved_signals_exist()) { 447646283Sdfr if( resume_all_threads ) { 447746283Sdfr 447846283Sdfr#ifdef THREAD_DEBUG 447946283Sdfr if( debug_on ) 448046283Sdfr printf( "Doing a continue by loop of all threads\n" ); 448146283Sdfr#endif 448246283Sdfr 448346283Sdfr threads_continue_all_with_signals( tid, signal ); 448446283Sdfr 448546283Sdfr clear_all_handled(); 448646283Sdfr clear_all_stepping_mode(); 448746283Sdfr } 448846283Sdfr 448946283Sdfr else { 449046283Sdfr#ifdef THREAD_DEBUG 449146283Sdfr printf( "Doing a continue w/signal of just thread %d\n", tid ); 449246283Sdfr#endif 449346283Sdfr 449446283Sdfr threads_continue_one_with_signal( tid, signal ); 449546283Sdfr 449646283Sdfr /* Clear the "handled" state of this thread, because 449746283Sdfr * we'll soon get a new event for it. Other events 449846283Sdfr * can stay as they were. 449946283Sdfr */ 450046283Sdfr clear_handled( tid ); 450146283Sdfr clear_stepping_mode( tid ); 450246283Sdfr } 450346283Sdfr } 450446283Sdfr 450546283Sdfr else { 450646283Sdfr /* No signals to send. 450746283Sdfr */ 450846283Sdfr if( resume_all_threads ) { 450946283Sdfr#ifdef THREAD_DEBUG 451046283Sdfr if( debug_on ) 451146283Sdfr printf( "Doing a continue by process of process %d\n", tid ); 451246283Sdfr#endif 451346283Sdfr 451446283Sdfr if( more_events_left > 0 ) { 451546283Sdfr warning( "Losing buffered events on continue." ); 451646283Sdfr more_events_left = 0; 451746283Sdfr } 451846283Sdfr 451946283Sdfr call_ttrace( TT_PROC_CONTINUE, 452046283Sdfr tid, 452146283Sdfr TT_NIL, 452246283Sdfr TT_NIL, 452346283Sdfr TT_NIL ); 452446283Sdfr 452546283Sdfr clear_all_handled(); 452646283Sdfr clear_all_stepping_mode(); 452746283Sdfr } 452846283Sdfr 452946283Sdfr else { 453046283Sdfr#ifdef THREAD_DEBUG 453146283Sdfr if( debug_on ) { 453246283Sdfr printf( "Doing a continue of just thread %d\n", tid ); 453346283Sdfr if( is_terminated( tid )) 453446283Sdfr printf( "Why are we continuing a dead thread? (5)\n" ); 453546283Sdfr } 453646283Sdfr#endif 453746283Sdfr 453846283Sdfr call_ttrace( TT_LWP_CONTINUE, 453946283Sdfr tid, 454046283Sdfr TT_NIL, 454146283Sdfr TT_NIL, 454246283Sdfr TT_NIL ); 454346283Sdfr 454446283Sdfr /* Clear the "handled" state of this thread, because 454546283Sdfr * we'll soon get a new event for it. Other events 454646283Sdfr * can stay as they were. 454746283Sdfr */ 454846283Sdfr clear_handled( tid ); 454946283Sdfr clear_stepping_mode( tid ); 455046283Sdfr } 455146283Sdfr } 455246283Sdfr } 455346283Sdfr 455446283Sdfr process_state = new_process_state; 455546283Sdfr 455646283Sdfr#ifdef WAIT_BUFFER_DEBUG 455746283Sdfr if( debug_on ) 455846283Sdfr printf( "Process set to %s\n", 455946283Sdfr get_printable_name_of_process_state (process_state) ); 456046283Sdfr#endif 456146283Sdfr 456246283Sdfr} 456346283Sdfr#endif /* CHILD_RESUME */ 456446283Sdfr 456546283Sdfr 456646283Sdfr#ifdef ATTACH_DETACH 456746283Sdfr/* 456846283Sdfr * Like it says. 456946283Sdfr * 457046283Sdfr * One worry is that we may not be attaching to "inferior_pid" 457146283Sdfr * and thus may not want to clear out our data. FIXME? 457246283Sdfr * 457346283Sdfr */ 457446283Sdfrstatic void 457546283Sdfrupdate_thread_state_after_attach( pid, kind_of_go ) 457646283Sdfr int pid; 457746283Sdfr attach_continue_t kind_of_go; 457846283Sdfr{ 457946283Sdfr int tt_status; 458046283Sdfr ttstate_t thread_state; 458146283Sdfr lwpid_t a_thread; 458246283Sdfr lwpid_t tid; 458346283Sdfr 458446283Sdfr /* The process better be stopped. 458546283Sdfr */ 458646283Sdfr if( process_state != STOPPED 458746283Sdfr && process_state != VFORKING ) 458846283Sdfr warning( "Internal error attaching." ); 458946283Sdfr 459046283Sdfr /* Clear out old tthread info and start over. This has the 459146283Sdfr * side effect of ensuring that the TRAP is reported as being 459246283Sdfr * in the right thread (re-mapped from tid to pid). 459346283Sdfr * 459446283Sdfr * It's because we need to add the tthread _now_ that we 459546283Sdfr * need to call "clear_thread_info" _now_, and that's why 459646283Sdfr * "require_notification_of_events" doesn't clear the thread 459746283Sdfr * info (it's called later than this routine). 459846283Sdfr */ 459946283Sdfr clear_thread_info(); 460046283Sdfr a_thread = 0; 460146283Sdfr 460246283Sdfr for (tid = get_process_first_stopped_thread_id (pid, &thread_state); 460346283Sdfr tid != 0; 460446283Sdfr tid = get_process_next_stopped_thread_id (pid, &thread_state)) 460546283Sdfr { 460646283Sdfr thread_info *p; 460746283Sdfr 460846283Sdfr if (a_thread == 0) 460946283Sdfr { 461046283Sdfr a_thread = tid; 461146283Sdfr#ifdef THREAD_DEBUG 461246283Sdfr if( debug_on ) 461346283Sdfr printf( "Attaching to process %d, thread %d\n", 461446283Sdfr pid, a_thread ); 461546283Sdfr#endif 461646283Sdfr } 461746283Sdfr 461846283Sdfr /* Tell ourselves and the "rest of gdb" that this thread 461946283Sdfr * exists. 462046283Sdfr * 462146283Sdfr * This isn't really a hack. Other thread-based versions 462246283Sdfr * of gdb (e.g. gnu-nat.c) seem to do the same thing. 462346283Sdfr * 462446283Sdfr * We don't need to do mapping here, as we know this 462546283Sdfr * is the first thread and thus gets the real pid 462646283Sdfr * (and is "inferior_pid"). 462746283Sdfr * 462846283Sdfr * NOTE: it probably isn't the originating thread, 462946283Sdfr * but that doesn't matter (we hope!). 463046283Sdfr */ 463146283Sdfr add_tthread( pid, tid ); 463246283Sdfr p = find_thread_info( tid ); 463346283Sdfr if( NULL == p ) /* ?We just added it! */ 463446283Sdfr error( "Internal error adding a thread on attach." ); 463546283Sdfr 463646283Sdfr copy_ttstate_t( &p->last_stop_state, thread_state ); 463746283Sdfr p->have_state = 1; 463846283Sdfr 463946283Sdfr if( DO_ATTACH_CONTINUE == kind_of_go ) { 464046283Sdfr /* 464146283Sdfr * If we are going to CONTINUE afterwards, 464246283Sdfr * raising a SIGTRAP, don't bother trying to 464346283Sdfr * handle this event. But check first! 464446283Sdfr */ 464546283Sdfr switch( p->last_stop_state.tts_event ) { 464646283Sdfr 464746283Sdfr case TTEVT_NONE: 464846283Sdfr /* Ok to set this handled. 464946283Sdfr */ 465046283Sdfr break; 465146283Sdfr 465246283Sdfr default: 465346283Sdfr warning( "Internal error; skipping event %s on process %d, thread %d.", 465446283Sdfr get_printable_name_of_ttrace_event( 465546283Sdfr p->last_stop_state.tts_event ), 465646283Sdfr p->pid, p->tid); 465746283Sdfr } 465846283Sdfr 465946283Sdfr set_handled( pid, tid ); 466046283Sdfr 466146283Sdfr } 466246283Sdfr else { 466346283Sdfr /* There will be no "continue" opertion, so the 466446283Sdfr * process remains stopped. Don't set any events 466546283Sdfr * handled except the "gimmies". 466646283Sdfr */ 466746283Sdfr switch( p->last_stop_state.tts_event ) { 466846283Sdfr 466946283Sdfr case TTEVT_NONE: 467046283Sdfr /* Ok to ignore this. 467146283Sdfr */ 467246283Sdfr set_handled( pid, tid ); 467346283Sdfr break; 467446283Sdfr 467546283Sdfr case TTEVT_EXEC: 467646283Sdfr case TTEVT_FORK: 467746283Sdfr /* Expected "other" FORK or EXEC event from a 467846283Sdfr * fork or vfork. 467946283Sdfr */ 468046283Sdfr break; 468146283Sdfr 468246283Sdfr default: 468346283Sdfr printf( "Internal error: failed to handle event %s on process %d, thread %d.", 468446283Sdfr get_printable_name_of_ttrace_event( 468546283Sdfr p->last_stop_state.tts_event ), 468646283Sdfr p->pid, p->tid); 468746283Sdfr } 468846283Sdfr } 468946283Sdfr 469046283Sdfr add_thread( tid ); /* in thread.c */ 469146283Sdfr } 469246283Sdfr 469346283Sdfr#ifdef PARANOIA 469446283Sdfr if( debug_on ) 469546283Sdfr print_tthreads(); 469646283Sdfr#endif 469746283Sdfr 469846283Sdfr /* One mustn't call ttrace_wait() after attaching via ttrace, 469946283Sdfr 'cause the process is stopped already. 470046283Sdfr 470146283Sdfr However, the upper layers of gdb's execution control will 470246283Sdfr want to wait after attaching (but not after forks, in 470346283Sdfr which case they will be doing a "target_resume", anticipating 470446283Sdfr a later TTEVT_EXEC or TTEVT_FORK event). 470546283Sdfr 470646283Sdfr To make this attach() implementation more compatible with 470746283Sdfr others, we'll make the attached-to process raise a SIGTRAP. 470846283Sdfr 470946283Sdfr Issue: this continues only one thread. That could be 471046283Sdfr dangerous if the thread is blocked--the process won't run 471146283Sdfr and no trap will be raised. FIX! (check state.tts_flags? 471246283Sdfr need one that's either TTS_WASRUNNING--but we've stopped 471346283Sdfr it and made it TTS_WASSUSPENDED. Hum...FIXME!) 471446283Sdfr */ 471546283Sdfr if( DO_ATTACH_CONTINUE == kind_of_go ) { 471646283Sdfr tt_status = call_real_ttrace( 471746283Sdfr TT_LWP_CONTINUE, 471846283Sdfr pid, 471946283Sdfr a_thread, 472046283Sdfr TT_USE_CURRENT_PC, 472146283Sdfr (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP), 472246283Sdfr TT_NIL); 472346283Sdfr if (errno) 472446283Sdfr perror_with_name ("ttrace"); 472546283Sdfr 472646283Sdfr clear_handled( a_thread ); /* So TRAP will be reported. */ 472746283Sdfr 472846283Sdfr /* Now running. 472946283Sdfr */ 473046283Sdfr process_state = RUNNING; 473146283Sdfr } 473246283Sdfr 473346283Sdfr attach_flag = 1; 473446283Sdfr} 473546283Sdfr#endif /* ATTACH_DETACH */ 473646283Sdfr 473746283Sdfr 473846283Sdfr#ifdef ATTACH_DETACH 473946283Sdfr/* Start debugging the process whose number is PID. 474046283Sdfr * (A _real_ pid). 474146283Sdfr */ 474246283Sdfrint 474346283Sdfrattach( pid ) 474446283Sdfr int pid; 474546283Sdfr{ 474646283Sdfr int tt_status; 474746283Sdfr 474846283Sdfr tt_status = call_real_ttrace ( 474946283Sdfr TT_PROC_ATTACH, 475046283Sdfr pid, 475146283Sdfr (lwpid_t) TT_NIL, 475246283Sdfr TT_NIL, 475346283Sdfr (TTRACE_ARG_TYPE) TT_VERSION, 475446283Sdfr TT_NIL); 475546283Sdfr if (errno) 475646283Sdfr perror_with_name ("ttrace attach"); 475746283Sdfr 475846283Sdfr /* If successful, the process is now stopped. 475946283Sdfr */ 476046283Sdfr process_state = STOPPED; 476146283Sdfr 476246283Sdfr /* Our caller ("attach_command" in "infcmd.c") 476346283Sdfr * expects to do a "wait_for_inferior" after 476446283Sdfr * the attach, so make sure the inferior is 476546283Sdfr * running when we're done. 476646283Sdfr */ 476746283Sdfr update_thread_state_after_attach( pid, DO_ATTACH_CONTINUE ); 476846283Sdfr 476946283Sdfr return pid; 477046283Sdfr} 477146283Sdfr 477246283Sdfr 477346283Sdfr#if defined(CHILD_POST_ATTACH) 477446283Sdfrvoid 477546283Sdfrchild_post_attach (pid) 477646283Sdfr int pid; 477746283Sdfr{ 477846283Sdfr#ifdef THREAD_DEBUG 477946283Sdfr if( debug_on ) 478046283Sdfr printf( "child-post-attach call\n" ); 478146283Sdfr#endif 478246283Sdfr 478346283Sdfr require_notification_of_events (pid); 478446283Sdfr} 478546283Sdfr#endif 478646283Sdfr 478746283Sdfr 478846283Sdfr/* Stop debugging the process whose number is PID 478946283Sdfr and continue it with signal number SIGNAL. 479046283Sdfr SIGNAL = 0 means just continue it. 479146283Sdfr */ 479246283Sdfrvoid 479346283Sdfrdetach( signal ) 479446283Sdfr int signal; 479546283Sdfr{ 479646283Sdfr errno = 0; 479746283Sdfr call_ttrace (TT_PROC_DETACH, 479846283Sdfr inferior_pid, 479946283Sdfr TT_NIL, 480046283Sdfr (TTRACE_ARG_TYPE) signal, 480146283Sdfr TT_NIL); 480246283Sdfr attach_flag = 0; 480346283Sdfr 480446283Sdfr clear_thread_info(); 480546283Sdfr 480646283Sdfr /* Process-state? */ 480746283Sdfr} 480846283Sdfr#endif /* ATTACH_DETACH */ 480946283Sdfr 481046283Sdfr 481146283Sdfr/* Default the type of the ttrace transfer to int. */ 481246283Sdfr#ifndef TTRACE_XFER_TYPE 481346283Sdfr#define TTRACE_XFER_TYPE int 481446283Sdfr#endif 481546283Sdfr 481646283Sdfrvoid 481746283Sdfr_initialize_kernel_u_addr () 481846283Sdfr{ 481946283Sdfr} 482046283Sdfr 482146283Sdfr#if !defined (CHILD_XFER_MEMORY) 482246283Sdfr/* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory 482346283Sdfr in the NEW_SUN_TTRACE case. 482446283Sdfr It ought to be straightforward. But it appears that writing did 482546283Sdfr not write the data that I specified. I cannot understand where 482646283Sdfr it got the data that it actually did write. */ 482746283Sdfr 482846283Sdfr/* Copy LEN bytes to or from inferior's memory starting at MEMADDR 482946283Sdfr to debugger memory starting at MYADDR. Copy to inferior if 483046283Sdfr WRITE is nonzero. 483146283Sdfr 483246283Sdfr Returns the length copied, which is either the LEN argument or zero. 483346283Sdfr This xfer function does not do partial moves, since child_ops 483446283Sdfr doesn't allow memory operations to cross below us in the target stack 483546283Sdfr anyway. */ 483646283Sdfr 483746283Sdfrint 483846283Sdfrchild_xfer_memory (memaddr, myaddr, len, write, target) 483946283Sdfr CORE_ADDR memaddr; 484046283Sdfr char *myaddr; 484146283Sdfr int len; 484246283Sdfr int write; 484346283Sdfr struct target_ops *target; /* ignored */ 484446283Sdfr{ 484546283Sdfr register int i; 484646283Sdfr /* Round starting address down to longword boundary. */ 484746283Sdfr register CORE_ADDR addr = memaddr & - sizeof (TTRACE_XFER_TYPE); 484846283Sdfr /* Round ending address up; get number of longwords that makes. */ 484946283Sdfr register int count 485046283Sdfr = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1) 485146283Sdfr / sizeof (TTRACE_XFER_TYPE); 485246283Sdfr /* Allocate buffer of that many longwords. */ 485346283Sdfr register TTRACE_XFER_TYPE *buffer 485446283Sdfr = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE)); 485546283Sdfr 485646283Sdfr if (write) 485746283Sdfr { 485846283Sdfr /* Fill start and end extra bytes of buffer with existing memory data. */ 485946283Sdfr 486046283Sdfr if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE)) { 486146283Sdfr /* Need part of initial word -- fetch it. */ 486246283Sdfr buffer[0] = call_ttrace (TT_LWP_RDTEXT, 486346283Sdfr inferior_pid, 486446283Sdfr (TTRACE_ARG_TYPE) addr, 486546283Sdfr TT_NIL, 486646283Sdfr TT_NIL); 486746283Sdfr } 486846283Sdfr 486946283Sdfr if (count > 1) /* FIXME, avoid if even boundary */ 487046283Sdfr { 487146283Sdfr buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT, 487246283Sdfr inferior_pid, 487346283Sdfr ((TTRACE_ARG_TYPE) 487446283Sdfr (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))), 487546283Sdfr TT_NIL, 487646283Sdfr TT_NIL); 487746283Sdfr } 487846283Sdfr 487946283Sdfr /* Copy data to be written over corresponding part of buffer */ 488046283Sdfr 488146283Sdfr memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)), 488246283Sdfr myaddr, 488346283Sdfr len); 488446283Sdfr 488546283Sdfr /* Write the entire buffer. */ 488646283Sdfr 488746283Sdfr for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE)) 488846283Sdfr { 488946283Sdfr errno = 0; 489046283Sdfr call_ttrace (TT_LWP_WRDATA, 489146283Sdfr inferior_pid, 489246283Sdfr (TTRACE_ARG_TYPE) addr, 489346283Sdfr (TTRACE_ARG_TYPE) buffer[i], 489446283Sdfr TT_NIL); 489546283Sdfr if (errno) 489646283Sdfr { 489746283Sdfr /* Using the appropriate one (I or D) is necessary for 489846283Sdfr Gould NP1, at least. */ 489946283Sdfr errno = 0; 490046283Sdfr call_ttrace (TT_LWP_WRTEXT, 490146283Sdfr inferior_pid, 490246283Sdfr (TTRACE_ARG_TYPE) addr, 490346283Sdfr (TTRACE_ARG_TYPE) buffer[i], 490446283Sdfr TT_NIL); 490546283Sdfr } 490646283Sdfr if (errno) 490746283Sdfr return 0; 490846283Sdfr } 490946283Sdfr } 491046283Sdfr else 491146283Sdfr { 491246283Sdfr /* Read all the longwords */ 491346283Sdfr for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE)) 491446283Sdfr { 491546283Sdfr errno = 0; 491646283Sdfr buffer[i] = call_ttrace (TT_LWP_RDTEXT, 491746283Sdfr inferior_pid, 491846283Sdfr (TTRACE_ARG_TYPE) addr, 491946283Sdfr TT_NIL, 492046283Sdfr TT_NIL); 492146283Sdfr if (errno) 492246283Sdfr return 0; 492346283Sdfr QUIT; 492446283Sdfr } 492546283Sdfr 492646283Sdfr /* Copy appropriate bytes out of the buffer. */ 492746283Sdfr memcpy (myaddr, 492846283Sdfr (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)), 492946283Sdfr len); 493046283Sdfr } 493146283Sdfr return len; 493246283Sdfr} 493346283Sdfr 493446283Sdfr 493546283Sdfrstatic void 493646283Sdfrudot_info () 493746283Sdfr{ 493846283Sdfr int udot_off; /* Offset into user struct */ 493946283Sdfr int udot_val; /* Value from user struct at udot_off */ 494046283Sdfr char mess[128]; /* For messages */ 494146283Sdfr 494246283Sdfr if (!target_has_execution) 494346283Sdfr { 494446283Sdfr error ("The program is not being run."); 494546283Sdfr } 494646283Sdfr 494746283Sdfr#if !defined (KERNEL_U_SIZE) 494846283Sdfr 494946283Sdfr /* Adding support for this command is easy. Typically you just add a 495046283Sdfr routine, called "kernel_u_size" that returns the size of the user 495146283Sdfr struct, to the appropriate *-nat.c file and then add to the native 495246283Sdfr config file "#define KERNEL_U_SIZE kernel_u_size()" */ 495346283Sdfr error ("Don't know how large ``struct user'' is in this version of gdb."); 495446283Sdfr 495546283Sdfr#else 495646283Sdfr 495746283Sdfr for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val)) 495846283Sdfr { 495946283Sdfr if ((udot_off % 24) == 0) 496046283Sdfr { 496146283Sdfr if (udot_off > 0) 496246283Sdfr { 496346283Sdfr printf_filtered ("\n"); 496446283Sdfr } 496546283Sdfr printf_filtered ("%04x:", udot_off); 496646283Sdfr } 496746283Sdfr udot_val = call_ttrace (TT_LWP_RUREGS, 496846283Sdfr inferior_pid, 496946283Sdfr (TTRACE_ARG_TYPE) udot_off, 497046283Sdfr TT_NIL, 497146283Sdfr TT_NIL); 497246283Sdfr if (errno != 0) 497346283Sdfr { 497446283Sdfr sprintf (mess, "\nreading user struct at offset 0x%x", udot_off); 497546283Sdfr perror_with_name (mess); 497646283Sdfr } 497746283Sdfr /* Avoid using nonportable (?) "*" in print specs */ 497846283Sdfr printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val); 497946283Sdfr } 498046283Sdfr printf_filtered ("\n"); 498146283Sdfr 498246283Sdfr#endif 498346283Sdfr} 498446283Sdfr#endif /* !defined (CHILD_XFER_MEMORY). */ 498546283Sdfr 498646283Sdfr/* TTrace version of "target_pid_to_exec_file" 498746283Sdfr */ 498846283Sdfrchar * 498946283Sdfrchild_pid_to_exec_file (tid) 499046283Sdfr int tid; 499146283Sdfr{ 499246283Sdfr static char exec_file_buffer[1024]; 499346283Sdfr int tt_status; 499446283Sdfr CORE_ADDR top_of_stack; 499546283Sdfr char four_chars[4]; 499646283Sdfr int name_index; 499746283Sdfr int i; 499846283Sdfr int done; 499946283Sdfr int saved_inferior_pid; 500046283Sdfr 500146283Sdfr /* As of 10.x HP-UX, there's an explicit request to get the 500246283Sdfr *pathname. 500346283Sdfr */ 500446283Sdfr tt_status = call_ttrace (TT_PROC_GET_PATHNAME, 500546283Sdfr tid, 500646283Sdfr (TTRACE_ARG_TYPE) exec_file_buffer, 500746283Sdfr (TTRACE_ARG_TYPE) sizeof (exec_file_buffer) - 1, 500846283Sdfr TT_NIL); 500946283Sdfr if (tt_status >= 0) 501046283Sdfr return exec_file_buffer; 501146283Sdfr 501246283Sdfr /* ??rehrauer: The above request may or may not be broken. It 501346283Sdfr doesn't seem to work when I use it. But, it may be designed 501446283Sdfr to only work immediately after an exec event occurs. (I'm 501546283Sdfr waiting for COSL to explain.) 501646283Sdfr 501746283Sdfr In any case, if it fails, try a really, truly amazingly gross 501846283Sdfr hack that DDE uses, of pawing through the process' data 501946283Sdfr segment to find the pathname. 502046283Sdfr */ 502146283Sdfr top_of_stack = 0x7b03a000; 502246283Sdfr name_index = 0; 502346283Sdfr done = 0; 502446283Sdfr 502546283Sdfr /* On the chance that pid != inferior_pid, set inferior_pid 502646283Sdfr to pid, so that (grrrr!) implicit uses of inferior_pid get 502746283Sdfr the right id. 502846283Sdfr */ 502946283Sdfr saved_inferior_pid = inferior_pid; 503046283Sdfr inferior_pid = tid; 503146283Sdfr 503246283Sdfr /* Try to grab a null-terminated string. */ 503346283Sdfr while (! done) { 503446283Sdfr if (target_read_memory (top_of_stack, four_chars, 4) != 0) 503546283Sdfr { 503646283Sdfr inferior_pid = saved_inferior_pid; 503746283Sdfr return NULL; 503846283Sdfr } 503946283Sdfr for (i = 0; i < 4; i++) { 504046283Sdfr exec_file_buffer[name_index++] = four_chars[i]; 504146283Sdfr done = (four_chars[i] == '\0'); 504246283Sdfr if (done) 504346283Sdfr break; 504446283Sdfr } 504546283Sdfr top_of_stack += 4; 504646283Sdfr } 504746283Sdfr 504846283Sdfr if (exec_file_buffer[0] == '\0') 504946283Sdfr { 505046283Sdfr inferior_pid = saved_inferior_pid; 505146283Sdfr return NULL; 505246283Sdfr } 505346283Sdfr 505446283Sdfr inferior_pid = saved_inferior_pid; 505546283Sdfr return exec_file_buffer; 505646283Sdfr} 505746283Sdfr 505846283Sdfr 505946283Sdfrvoid 506046283Sdfrpre_fork_inferior () 506146283Sdfr{ 506246283Sdfr int status; 506346283Sdfr 506446283Sdfr status = pipe (startup_semaphore.parent_channel); 506546283Sdfr if (status < 0) { 506646283Sdfr warning ("error getting parent pipe for startup semaphore"); 506746283Sdfr return; 506846283Sdfr } 506946283Sdfr 507046283Sdfr status = pipe (startup_semaphore.child_channel); 507146283Sdfr if (status < 0) { 507246283Sdfr warning ("error getting child pipe for startup semaphore"); 507346283Sdfr return; 507446283Sdfr } 507546283Sdfr} 507646283Sdfr 507746283Sdfr/* Called via #define REQUIRE_ATTACH from inftarg.c, 507846283Sdfr * ultimately from "follow_inferior_fork" in infrun.c, 507946283Sdfr * itself called from "resume". 508046283Sdfr * 508146283Sdfr * This seems to be intended to attach after a fork or 508246283Sdfr * vfork, while "attach" is used to attach to a pid 508346283Sdfr * given by the user. The check for an existing attach 508446283Sdfr * seems odd--it always fails in our test system. 508546283Sdfr */ 508646283Sdfrint 508746283Sdfrhppa_require_attach (pid) 508846283Sdfr int pid; 508946283Sdfr{ 509046283Sdfr int tt_status; 509146283Sdfr CORE_ADDR pc; 509246283Sdfr CORE_ADDR pc_addr; 509346283Sdfr unsigned int regs_offset; 509446283Sdfr process_state_t old_process_state = process_state; 509546283Sdfr 509646283Sdfr /* Are we already attached? There appears to be no explicit 509746283Sdfr * way to answer this via ttrace, so we try something which 509846283Sdfr * should be innocuous if we are attached. If that fails, 509946283Sdfr * then we assume we're not attached, and so attempt to make 510046283Sdfr * it so. 510146283Sdfr */ 510246283Sdfr errno = 0; 510346283Sdfr tt_status = call_real_ttrace (TT_PROC_STOP, 510446283Sdfr pid, 510546283Sdfr (lwpid_t) TT_NIL, 510646283Sdfr (TTRACE_ARG_TYPE) TT_NIL, 510746283Sdfr (TTRACE_ARG_TYPE) TT_NIL, 510846283Sdfr TT_NIL); 510946283Sdfr 511046283Sdfr if (errno) 511146283Sdfr { 511246283Sdfr /* No change to process-state! 511346283Sdfr */ 511446283Sdfr errno = 0; 511546283Sdfr pid = attach (pid); 511646283Sdfr } 511746283Sdfr else 511846283Sdfr { 511946283Sdfr /* If successful, the process is now stopped. But if 512046283Sdfr * we're VFORKING, the parent is still running, so don't 512146283Sdfr * change the process state. 512246283Sdfr */ 512346283Sdfr if( process_state != VFORKING ) 512446283Sdfr process_state = STOPPED; 512546283Sdfr 512646283Sdfr /* If we were already attached, you'd think that we 512746283Sdfr * would need to start going again--but you'd be wrong, 512846283Sdfr * as the fork-following code is actually in the middle 512946283Sdfr * of the "resume" routine in in "infrun.c" and so 513046283Sdfr * will (almost) immediately do a resume. 513146283Sdfr * 513246283Sdfr * On the other hand, if we are VFORKING, which means 513346283Sdfr * that the child and the parent share a process for a 513446283Sdfr * while, we know that "resume" won't be resuming 513546283Sdfr * until the child EXEC event is seen. But we still 513646283Sdfr * don't want to continue, as the event is already 513746283Sdfr * there waiting. 513846283Sdfr */ 513946283Sdfr update_thread_state_after_attach( pid, DONT_ATTACH_CONTINUE ); 514046283Sdfr } /* STOP succeeded */ 514146283Sdfr 514246283Sdfr return pid; 514346283Sdfr} 514446283Sdfr 514546283Sdfrint 514646283Sdfrhppa_require_detach (pid, signal) 514746283Sdfr int pid; 514846283Sdfr int signal; 514946283Sdfr{ 515046283Sdfr int tt_status; 515146283Sdfr 515246283Sdfr /* If signal is non-zero, we must pass the signal on to the active 515346283Sdfr thread prior to detaching. We do this by continuing the threads 515446283Sdfr with the signal. 515546283Sdfr */ 515646283Sdfr if (signal != 0) 515746283Sdfr { 515846283Sdfr errno = 0; 515946283Sdfr threads_continue_all_with_signals( pid, signal ); 516046283Sdfr } 516146283Sdfr 516246283Sdfr errno = 0; 516346283Sdfr tt_status = call_ttrace (TT_PROC_DETACH, 516446283Sdfr pid, 516546283Sdfr TT_NIL, 516646283Sdfr TT_NIL, 516746283Sdfr TT_NIL); 516846283Sdfr 516946283Sdfr errno = 0; /* Ignore any errors. */ 517046283Sdfr 517146283Sdfr /* process_state? */ 517246283Sdfr 517346283Sdfr return pid; 517446283Sdfr} 517546283Sdfr 517646283Sdfr/* Given the starting address of a memory page, hash it to a bucket in 517746283Sdfr the memory page dictionary. 517846283Sdfr */ 517946283Sdfrstatic int 518046283Sdfrget_dictionary_bucket_of_page (page_start) 518146283Sdfr CORE_ADDR page_start; 518246283Sdfr{ 518346283Sdfr int hash; 518446283Sdfr 518546283Sdfr hash = (page_start / memory_page_dictionary.page_size); 518646283Sdfr hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; 518746283Sdfr 518846283Sdfr return hash; 518946283Sdfr} 519046283Sdfr 519146283Sdfr 519246283Sdfr/* Given a memory page's starting address, get (i.e., find an existing 519346283Sdfr or create a new) dictionary entry for the page. The page will be 519446283Sdfr write-protected when this function returns, but may have a reference 519546283Sdfr count of 0 (if the page was newly-added to the dictionary). 519646283Sdfr */ 519746283Sdfrstatic memory_page_t * 519846283Sdfrget_dictionary_entry_of_page (pid, page_start) 519946283Sdfr int pid; 520046283Sdfr CORE_ADDR page_start; 520146283Sdfr{ 520246283Sdfr int bucket; 520346283Sdfr memory_page_t * page = NULL; 520446283Sdfr memory_page_t * previous_page = NULL; 520546283Sdfr 520646283Sdfr /* We're going to be using the dictionary now, than-kew. */ 520746283Sdfr require_memory_page_dictionary (pid); 520846283Sdfr 520946283Sdfr /* Try to find an existing dictionary entry for this page. Hash 521046283Sdfr on the page's starting address. 521146283Sdfr */ 521246283Sdfr bucket = get_dictionary_bucket_of_page (page_start); 521346283Sdfr page = &memory_page_dictionary.buckets[bucket]; 521446283Sdfr while (page != NULL) 521546283Sdfr { 521646283Sdfr if (page->page_start == page_start) 521746283Sdfr break; 521846283Sdfr previous_page = page; 521946283Sdfr page = page->next; 522046283Sdfr } 522146283Sdfr 522246283Sdfr /* Did we find a dictionary entry for this page? If not, then 522346283Sdfr add it to the dictionary now. 522446283Sdfr */ 522546283Sdfr if (page == NULL) 522646283Sdfr { 522746283Sdfr /* Create a new entry. */ 522846283Sdfr page = (memory_page_t *) xmalloc (sizeof (memory_page_t)); 522946283Sdfr page->page_start = page_start; 523046283Sdfr page->reference_count = 0; 523146283Sdfr page->next = NULL; 523246283Sdfr page->previous = NULL; 523346283Sdfr 523446283Sdfr /* We'll write-protect the page now, if that's allowed. */ 523546283Sdfr page->original_permissions = write_protect_page (pid, page_start); 523646283Sdfr 523746283Sdfr /* Add the new entry to the dictionary. */ 523846283Sdfr page->previous = previous_page; 523946283Sdfr previous_page->next = page; 524046283Sdfr 524146283Sdfr memory_page_dictionary.page_count++; 524246283Sdfr } 524346283Sdfr 524446283Sdfr return page; 524546283Sdfr} 524646283Sdfr 524746283Sdfr 524846283Sdfrstatic void 524946283Sdfrremove_dictionary_entry_of_page (pid, page) 525046283Sdfr int pid; 525146283Sdfr memory_page_t * page; 525246283Sdfr{ 525346283Sdfr /* Restore the page's original permissions. */ 525446283Sdfr unwrite_protect_page (pid, page->page_start, page->original_permissions); 525546283Sdfr 525646283Sdfr /* Kick the page out of the dictionary. */ 525746283Sdfr if (page->previous != NULL) 525846283Sdfr page->previous->next = page->next; 525946283Sdfr if (page->next != NULL) 526046283Sdfr page->next->previous = page->previous; 526146283Sdfr 526246283Sdfr /* Just in case someone retains a handle to this after it's freed. */ 526346283Sdfr page->page_start = (CORE_ADDR) 0; 526446283Sdfr 526546283Sdfr memory_page_dictionary.page_count--; 526646283Sdfr 526746283Sdfr free (page); 526846283Sdfr} 526946283Sdfr 527046283Sdfr 527146283Sdfrstatic void 527246283Sdfrhppa_enable_syscall_events (pid) 527346283Sdfr int pid; 527446283Sdfr{ 527546283Sdfr int tt_status; 527646283Sdfr ttevent_t ttrace_events; 527746283Sdfr 527846283Sdfr /* Get the set of events that are currently enabled. */ 527946283Sdfr tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK, 528046283Sdfr pid, 528146283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 528246283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 528346283Sdfr TT_NIL); 528446283Sdfr if (errno) 528546283Sdfr perror_with_name ("ttrace"); 528646283Sdfr 528746283Sdfr /* Add syscall events to that set. */ 528846283Sdfr ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY; 528946283Sdfr ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN; 529046283Sdfr 529146283Sdfr tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK, 529246283Sdfr pid, 529346283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 529446283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 529546283Sdfr TT_NIL); 529646283Sdfr if (errno) 529746283Sdfr perror_with_name ("ttrace"); 529846283Sdfr} 529946283Sdfr 530046283Sdfr 530146283Sdfrstatic void 530246283Sdfrhppa_disable_syscall_events (pid) 530346283Sdfr int pid; 530446283Sdfr{ 530546283Sdfr int tt_status; 530646283Sdfr ttevent_t ttrace_events; 530746283Sdfr 530846283Sdfr /* Get the set of events that are currently enabled. */ 530946283Sdfr tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK, 531046283Sdfr pid, 531146283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 531246283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 531346283Sdfr TT_NIL); 531446283Sdfr if (errno) 531546283Sdfr perror_with_name ("ttrace"); 531646283Sdfr 531746283Sdfr /* Remove syscall events from that set. */ 531846283Sdfr ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY; 531946283Sdfr ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN; 532046283Sdfr 532146283Sdfr tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK, 532246283Sdfr pid, 532346283Sdfr (TTRACE_ARG_TYPE) &ttrace_events, 532446283Sdfr (TTRACE_ARG_TYPE) sizeof (ttrace_events), 532546283Sdfr TT_NIL); 532646283Sdfr if (errno) 532746283Sdfr perror_with_name ("ttrace"); 532846283Sdfr} 532946283Sdfr 533046283Sdfr 533146283Sdfr/* The address range beginning with START and ending with START+LEN-1 533246283Sdfr (inclusive) is to be watched via page-protection by a new watchpoint. 533346283Sdfr Set protection for all pages that overlap that range. 533446283Sdfr 533546283Sdfr Note that our caller sets TYPE to: 533646283Sdfr 0 for a bp_hardware_watchpoint, 533746283Sdfr 1 for a bp_read_watchpoint, 533846283Sdfr 2 for a bp_access_watchpoint 533946283Sdfr 534046283Sdfr (Yes, this is intentionally (though lord only knows why) different 534146283Sdfr from the TYPE that is passed to hppa_remove_hw_watchpoint.) 534246283Sdfr */ 534346283Sdfrint 534446283Sdfrhppa_insert_hw_watchpoint (pid, start, len, type) 534546283Sdfr int pid; 534646283Sdfr CORE_ADDR start; 534746283Sdfr LONGEST len; 534846283Sdfr int type; 534946283Sdfr{ 535046283Sdfr CORE_ADDR page_start; 535146283Sdfr int dictionary_was_empty; 535246283Sdfr int page_size; 535346283Sdfr int page_id; 535446283Sdfr LONGEST range_size_in_pages; 535546283Sdfr 535646283Sdfr if (type != 0) 535746283Sdfr error ("read or access hardware watchpoints not supported on HP-UX"); 535846283Sdfr 535946283Sdfr /* Examine all pages in the address range. */ 536046283Sdfr require_memory_page_dictionary (); 536146283Sdfr 536246283Sdfr dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0); 536346283Sdfr 536446283Sdfr page_size = memory_page_dictionary.page_size; 536546283Sdfr page_start = (start / page_size) * page_size; 536646283Sdfr range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size; 536746283Sdfr 536846283Sdfr for (page_id=0; page_id < range_size_in_pages; page_id++, page_start+=page_size) 536946283Sdfr { 537046283Sdfr memory_page_t * page; 537146283Sdfr 537246283Sdfr /* This gets the page entered into the dictionary if it was 537346283Sdfr not already entered. 537446283Sdfr */ 537546283Sdfr page = get_dictionary_entry_of_page (pid, page_start); 537646283Sdfr page->reference_count++; 537746283Sdfr } 537846283Sdfr 537946283Sdfr /* Our implementation depends on seeing calls to kernel code, for the 538046283Sdfr following reason. Here we ask to be notified of syscalls. 538146283Sdfr 538246283Sdfr When a protected page is accessed by user code, HP-UX raises a SIGBUS. 538346283Sdfr Fine. 538446283Sdfr 538546283Sdfr But when kernel code accesses the page, it doesn't give a SIGBUS. 538646283Sdfr Rather, the system call that touched the page fails, with errno=EFAULT. 538746283Sdfr Not good for us. 538846283Sdfr 538946283Sdfr We could accomodate this "feature" by asking to be notified of syscall 539046283Sdfr entries & exits; upon getting an entry event, disabling page-protections; 539146283Sdfr upon getting an exit event, reenabling page-protections and then checking 539246283Sdfr if any watchpoints triggered. 539346283Sdfr 539446283Sdfr However, this turns out to be a real performance loser. syscalls are 539546283Sdfr usually a frequent occurrence. Having to unprotect-reprotect all watched 539646283Sdfr pages, and also to then read all watched memory locations and compare for 539746283Sdfr triggers, can be quite expensive. 539846283Sdfr 539946283Sdfr Instead, we'll only ask to be notified of syscall exits. When we get 540046283Sdfr one, we'll check whether errno is set. If not, or if it's not EFAULT, 540146283Sdfr we can just continue the inferior. 540246283Sdfr 540346283Sdfr If errno is set upon syscall exit to EFAULT, we must perform some fairly 540446283Sdfr hackish stuff to determine whether the failure really was due to a 540546283Sdfr page-protect trap on a watched location. 540646283Sdfr */ 540746283Sdfr if (dictionary_was_empty) 540846283Sdfr hppa_enable_syscall_events (pid); 540946283Sdfr 541046283Sdfr return 1; 541146283Sdfr} 541246283Sdfr 541346283Sdfr 541446283Sdfr/* The address range beginning with START and ending with START+LEN-1 541546283Sdfr (inclusive) was being watched via page-protection by a watchpoint 541646283Sdfr which has been removed. Remove protection for all pages that 541746283Sdfr overlap that range, which are not also being watched by other 541846283Sdfr watchpoints. 541946283Sdfr */ 542046283Sdfrint 542146283Sdfrhppa_remove_hw_watchpoint (pid, start, len, type) 542246283Sdfr int pid; 542346283Sdfr CORE_ADDR start; 542446283Sdfr LONGEST len; 542546283Sdfr enum bptype type; 542646283Sdfr{ 542746283Sdfr CORE_ADDR page_start; 542846283Sdfr int dictionary_is_empty; 542946283Sdfr int page_size; 543046283Sdfr int page_id; 543146283Sdfr LONGEST range_size_in_pages; 543246283Sdfr 543346283Sdfr if (type != 0) 543446283Sdfr error ("read or access hardware watchpoints not supported on HP-UX"); 543546283Sdfr 543646283Sdfr /* Examine all pages in the address range. */ 543746283Sdfr require_memory_page_dictionary (); 543846283Sdfr 543946283Sdfr page_size = memory_page_dictionary.page_size; 544046283Sdfr page_start = (start / page_size) * page_size; 544146283Sdfr range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size; 544246283Sdfr 544346283Sdfr for (page_id=0; page_id < range_size_in_pages; page_id++, page_start+=page_size) 544446283Sdfr { 544546283Sdfr memory_page_t * page; 544646283Sdfr 544746283Sdfr page = get_dictionary_entry_of_page (pid, page_start); 544846283Sdfr page->reference_count--; 544946283Sdfr 545046283Sdfr /* Was this the last reference of this page? If so, then we 545146283Sdfr must scrub the entry from the dictionary, and also restore 545246283Sdfr the page's original permissions. 545346283Sdfr */ 545446283Sdfr if (page->reference_count == 0) 545546283Sdfr remove_dictionary_entry_of_page (pid, page); 545646283Sdfr } 545746283Sdfr 545846283Sdfr dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0); 545946283Sdfr 546046283Sdfr /* If write protections are currently disallowed, then that implies that 546146283Sdfr wait_for_inferior believes that the inferior is within a system call. 546246283Sdfr Since we want to see both syscall entry and return, it's clearly not 546346283Sdfr good to disable syscall events in this state! 546446283Sdfr 546546283Sdfr ??rehrauer: Yeah, it'd be better if we had a specific flag that said, 546646283Sdfr "inferior is between syscall events now". Oh well. 546746283Sdfr */ 546846283Sdfr if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed) 546946283Sdfr hppa_disable_syscall_events (pid); 547046283Sdfr 547146283Sdfr return 1; 547246283Sdfr} 547346283Sdfr 547446283Sdfr 547546283Sdfr/* Could we implement a watchpoint of this type via our available 547646283Sdfr hardware support? 547746283Sdfr 547846283Sdfr This query does not consider whether a particular address range 547946283Sdfr could be so watched, but just whether support is generally available 548046283Sdfr for such things. See hppa_range_profitable_for_hw_watchpoint for a 548146283Sdfr query that answers whether a particular range should be watched via 548246283Sdfr hardware support. 548346283Sdfr */ 548446283Sdfrint 548546283Sdfrhppa_can_use_hw_watchpoint (type, cnt, ot) 548646283Sdfr enum bptype type; 548746283Sdfr int cnt; 548846283Sdfr enum bptype ot; 548946283Sdfr{ 549046283Sdfr return (type == bp_hardware_watchpoint); 549146283Sdfr} 549246283Sdfr 549346283Sdfr 549446283Sdfr/* Assuming we could set a hardware watchpoint on this address, do 549546283Sdfr we think it would be profitable ("a good idea") to do so? If not, 549646283Sdfr we can always set a regular (aka single-step & test) watchpoint 549746283Sdfr on the address... 549846283Sdfr */ 549946283Sdfrint 550046283Sdfrhppa_range_profitable_for_hw_watchpoint (pid, start, len) 550146283Sdfr int pid; 550246283Sdfr CORE_ADDR start; 550346283Sdfr LONGEST len; 550446283Sdfr{ 550546283Sdfr int range_is_stack_based; 550646283Sdfr int range_is_accessible; 550746283Sdfr CORE_ADDR page_start; 550846283Sdfr int page_size; 550946283Sdfr int page; 551046283Sdfr LONGEST range_size_in_pages; 551146283Sdfr 551246283Sdfr /* ??rehrauer: For now, say that all addresses are potentially 551346283Sdfr profitable. Possibly later we'll want to test the address 551446283Sdfr for "stackness"? 551546283Sdfr */ 551646283Sdfr range_is_stack_based = 0; 551746283Sdfr 551846283Sdfr /* If any page in the range is inaccessible, then we cannot 551946283Sdfr really use hardware watchpointing, even though our client 552046283Sdfr thinks we can. In that case, it's actually an error to 552146283Sdfr attempt to use hw watchpoints, so we'll tell our client 552246283Sdfr that the range is "unprofitable", and hope that they listen... 552346283Sdfr */ 552446283Sdfr range_is_accessible = 1; /* Until proven otherwise. */ 552546283Sdfr 552646283Sdfr /* Examine all pages in the address range. */ 552746283Sdfr errno = 0; 552846283Sdfr page_size = sysconf (_SC_PAGE_SIZE); 552946283Sdfr 553046283Sdfr /* If we can't determine page size, we're hosed. Tell our 553146283Sdfr client it's unprofitable to use hw watchpoints for this 553246283Sdfr range. 553346283Sdfr */ 553446283Sdfr if (errno || (page_size <= 0)) 553546283Sdfr { 553646283Sdfr errno = 0; 553746283Sdfr return 0; 553846283Sdfr } 553946283Sdfr 554046283Sdfr page_start = (start / page_size) * page_size; 554146283Sdfr range_size_in_pages = len / (LONGEST)page_size; 554246283Sdfr 554346283Sdfr for (page=0; page < range_size_in_pages; page++, page_start+=page_size) 554446283Sdfr { 554546283Sdfr int tt_status; 554646283Sdfr int page_permissions; 554746283Sdfr 554846283Sdfr /* Is this page accessible? */ 554946283Sdfr errno = 0; 555046283Sdfr tt_status = call_ttrace (TT_PROC_GET_MPROTECT, 555146283Sdfr pid, 555246283Sdfr (TTRACE_ARG_TYPE) page_start, 555346283Sdfr TT_NIL, 555446283Sdfr (TTRACE_ARG_TYPE) &page_permissions); 555546283Sdfr if (errno || (tt_status < 0)) 555646283Sdfr { 555746283Sdfr errno = 0; 555846283Sdfr range_is_accessible = 0; 555946283Sdfr break; 556046283Sdfr } 556146283Sdfr 556246283Sdfr /* Yes, go for another... */ 556346283Sdfr } 556446283Sdfr 556546283Sdfr return (! range_is_stack_based && range_is_accessible); 556646283Sdfr} 556746283Sdfr 556846283Sdfr 556946283Sdfrchar * 557046283Sdfrhppa_pid_or_tid_to_str (id) 557146283Sdfr pid_t id; 557246283Sdfr{ 557346283Sdfr static char buf[100]; /* Static because address returned. */ 557446283Sdfr 557546283Sdfr /* Does this appear to be a process? If so, print it that way. */ 557646283Sdfr if (is_process_id (id)) 557746283Sdfr return hppa_pid_to_str (id); 557846283Sdfr 557946283Sdfr /* Else, print both the GDB thread number and the system thread id. */ 558046283Sdfr sprintf (buf, "thread %d (", pid_to_thread_id (id)); 558146283Sdfr strcat (buf, hppa_tid_to_str (id)); 558246283Sdfr strcat (buf, ")\0"); 558346283Sdfr 558446283Sdfr return buf; 558546283Sdfr} 558646283Sdfr 558746283Sdfr 558846283Sdfr/* If the current pid is not the pid this module reported 558946283Sdfr * from "ptrace_wait" with the most recent event, then the 559046283Sdfr * user has switched threads. 559146283Sdfr * 559246283Sdfr * If the last reported event was a breakpoint, then return 559346283Sdfr * the old thread id, else return 0. 559446283Sdfr */ 559546283Sdfrpid_t 559646283Sdfrhppa_switched_threads( gdb_pid ) 559746283Sdfr pid_t gdb_pid; 559846283Sdfr{ 559946283Sdfr if( gdb_pid == old_gdb_pid ) { 560046283Sdfr /* 560146283Sdfr * Core gdb is working with the same pid that it 560246283Sdfr * was before we reported the last event. This 560346283Sdfr * is ok: e.g. we reported hitting a thread-specific 560446283Sdfr * breakpoint, but we were reporting the wrong 560546283Sdfr * thread, so the core just ignored the event. 560646283Sdfr * 560746283Sdfr * No thread switch has happened. 560846283Sdfr */ 560946283Sdfr return (pid_t) 0; 561046283Sdfr } 561146283Sdfr else if( gdb_pid == reported_pid ) { 561246283Sdfr /* 561346283Sdfr * Core gdb is working with the pid we reported, so 561446283Sdfr * any continue or step will be able to figure out 561546283Sdfr * that it needs to step over any hit breakpoints 561646283Sdfr * without our (i.e. PREPARE_TO_PROCEED's) help. 561746283Sdfr */ 561846283Sdfr return (pid_t) 0; 561946283Sdfr } 562046283Sdfr else if( !reported_bpt ) { 562146283Sdfr /* 562246283Sdfr * The core switched, but we didn't just report a 562346283Sdfr * breakpoint, so there's no just-hit breakpoint 562446283Sdfr * instruction at "reported_pid"'s PC, and thus there 562546283Sdfr * is no need to step over it. 562646283Sdfr */ 562746283Sdfr return (pid_t) 0; 562846283Sdfr } 562946283Sdfr else { 563046283Sdfr /* There's been a real switch, and we reported 563146283Sdfr * a hit breakpoint. Let "hppa_prepare_to_proceed" 563246283Sdfr * know, so it can see whether the breakpoint is 563346283Sdfr * still active. 563446283Sdfr */ 563546283Sdfr return reported_pid; 563646283Sdfr } 563746283Sdfr 563846283Sdfr /* Keep compiler happy with an obvious return at the end. 563946283Sdfr */ 564046283Sdfr return (pid_t) 0; 564146283Sdfr} 564246283Sdfr 564346283Sdfrvoid 564446283Sdfrhppa_ensure_vforking_parent_remains_stopped (pid) 564546283Sdfr int pid; 564646283Sdfr{ 564746283Sdfr /* Nothing to do when using ttrace. Only the ptrace-based implementation 564846283Sdfr must do real work. 564946283Sdfr */ 565046283Sdfr} 565146283Sdfr 565246283Sdfr 565346283Sdfrint 565446283Sdfrhppa_resume_execd_vforking_child_to_get_parent_vfork () 565546283Sdfr{ 565646283Sdfr return 0; /* No, the parent vfork is available now. */ 565746283Sdfr} 565846283Sdfr 565946283Sdfr 566046283Sdfr 566146283Sdfrvoid 566246283Sdfr_initialize_infttrace () 566346283Sdfr{ 566446283Sdfr /* Initialize the ttrace-based hardware watchpoint implementation. */ 566546283Sdfr memory_page_dictionary.page_count = (LONGEST) -1; 566646283Sdfr memory_page_dictionary.page_protections_allowed = 1; 566746283Sdfr 566846283Sdfr errno = 0; 566946283Sdfr memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE); 567046283Sdfr 567146283Sdfr if (errno || (memory_page_dictionary.page_size <= 0)) 567246283Sdfr perror_with_name ("sysconf"); 567346283Sdfr} 567446283Sdfr 5675