OSDN Git Service

2004-10-08 Andrew Cagney <cagney@gnu.org>
[pf3gnuchains/pf3gnuchains3x.git] / gdb / inftarg.c
1 /* Target-vector operations for controlling Unix child processes, for GDB.
2
3    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
4    2000, 2002, 2003, 2004 Free Software Foundation, Inc.
5
6    Contributed by Cygnus Support.
7
8    ## Contains temporary hacks..
9
10    This file is part of GDB.
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place - Suite 330,
25    Boston, MA 02111-1307, USA.  */
26
27 #include "defs.h"
28 #include "frame.h"              /* required by inferior.h */
29 #include "inferior.h"
30 #include "target.h"
31 #include "gdbcore.h"
32 #include "command.h"
33 #include "gdb_stat.h"
34 #include <signal.h>
35 #include <sys/types.h>
36 #include <fcntl.h>
37 #include "observer.h"
38 #include "gdb_wait.h"
39 #include "inflow.h"
40
41 extern struct symtab_and_line *child_enable_exception_callback (enum
42                                                                 exception_event_kind,
43                                                                 int);
44
45 extern struct exception_event_record
46   *child_get_current_exception_event (void);
47
48 extern void _initialize_inftarg (void);
49
50 static void child_prepare_to_store (void);
51
52 #ifndef CHILD_WAIT
53 static ptid_t child_wait (ptid_t, struct target_waitstatus *);
54 #endif /* CHILD_WAIT */
55
56 static void child_open (char *, int);
57
58 static void child_files_info (struct target_ops *);
59
60 static void child_detach (char *, int);
61
62 static void child_attach (char *, int);
63
64 #if !defined(CHILD_POST_ATTACH)
65 extern void child_post_attach (int);
66 #endif
67
68 static void ptrace_me (void);
69
70 static void ptrace_him (int);
71
72 static void child_create_inferior (char *, char *, char **, int);
73
74 static void child_mourn_inferior (void);
75
76 static int child_can_run (void);
77
78 static void child_stop (void);
79
80 #ifndef CHILD_THREAD_ALIVE
81 int child_thread_alive (ptid_t);
82 #endif
83
84 static void init_child_ops (void);
85
86 extern char **environ;
87
88 int child_suppress_run = 0;     /* Non-zero if inftarg should pretend not to
89                                    be a runnable target.  Used by targets
90                                    that can sit atop inftarg, such as HPUX
91                                    thread support.  */
92
93 #ifndef CHILD_WAIT
94
95 /* Wait for child to do something.  Return pid of child, or -1 in case
96    of error; store status through argument pointer OURSTATUS.  */
97
98 static ptid_t
99 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
100 {
101   int save_errno;
102   int status;
103   char *execd_pathname = NULL;
104   int exit_status;
105   int related_pid;
106   int syscall_id;
107   enum target_waitkind kind;
108   int pid;
109
110   do
111     {
112       set_sigint_trap ();       /* Causes SIGINT to be passed on to the
113                                    attached process. */
114       set_sigio_trap ();
115
116       pid = wait (&status);
117
118       save_errno = errno;
119
120       clear_sigio_trap ();
121
122       clear_sigint_trap ();
123
124       if (pid == -1)
125         {
126           if (save_errno == EINTR)
127             continue;
128
129           fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
130                               safe_strerror (save_errno));
131
132           /* Claim it exited with unknown signal.  */
133           ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
134           ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
135           return pid_to_ptid (-1);
136         }
137
138       /* Did it exit?
139        */
140       if (target_has_exited (pid, status, &exit_status))
141         {
142           /* ??rehrauer: For now, ignore this. */
143           continue;
144         }
145
146       if (!target_thread_alive (pid_to_ptid (pid)))
147         {
148           ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
149           return pid_to_ptid (pid);
150         }
151       } while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */
152
153   store_waitstatus (ourstatus, status);
154   return pid_to_ptid (pid);
155 }
156 #endif /* CHILD_WAIT */
157
158 #ifndef CHILD_THREAD_ALIVE
159
160 /* Check to see if the given thread is alive.
161
162    FIXME: Is kill() ever the right way to do this?  I doubt it, but
163    for now we're going to try and be compatable with the old thread
164    code.  */
165 int
166 child_thread_alive (ptid_t ptid)
167 {
168   pid_t pid = PIDGET (ptid);
169
170   return (kill (pid, 0) != -1);
171 }
172
173 #endif
174
175 /* Attach to process PID, then initialize for debugging it.  */
176
177 static void
178 child_attach (char *args, int from_tty)
179 {
180   char *exec_file;
181   int pid;
182   char *dummy;
183
184   if (!args)
185     error_no_arg ("process-id to attach");
186
187   dummy = args;
188   pid = strtol (args, &dummy, 0);
189   /* Some targets don't set errno on errors, grrr! */
190   if ((pid == 0) && (args == dummy))
191       error ("Illegal process-id: %s\n", args);
192   
193   if (pid == getpid ()) /* Trying to masturbate? */
194     error ("I refuse to debug myself!");
195   
196   if (from_tty)
197     {
198       exec_file = (char *) get_exec_file (0);
199       
200       if (exec_file)
201         printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
202                            target_pid_to_str (pid_to_ptid (pid)));
203       else
204         printf_unfiltered ("Attaching to %s\n",
205                            target_pid_to_str (pid_to_ptid (pid)));
206       
207       gdb_flush (gdb_stdout);
208     }
209
210   attach (pid);
211   
212   inferior_ptid = pid_to_ptid (pid);
213   push_target (&deprecated_child_ops);
214 }
215
216 #if !defined(CHILD_POST_ATTACH)
217 void
218 child_post_attach (int pid)
219 {
220   /* This version of Unix doesn't require a meaningful "post attach"
221      operation by a debugger.  */
222 }
223 #endif
224
225 /* Take a program previously attached to and detaches it.
226    The program resumes execution and will no longer stop
227    on signals, etc.  We'd better not have left any breakpoints
228    in the program or it'll die when it hits one.  For this
229    to work, it may be necessary for the process to have been
230    previously attached.  It *might* work if the program was
231    started via the normal ptrace (PTRACE_TRACEME).  */
232
233 static void
234 child_detach (char *args, int from_tty)
235 {
236   int siggnal = 0;
237   int pid = PIDGET (inferior_ptid);
238   
239   if (from_tty)
240     {
241       char *exec_file = get_exec_file (0);
242       if (exec_file == 0)
243         exec_file = "";
244       printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
245                          target_pid_to_str (pid_to_ptid (pid)));
246       gdb_flush (gdb_stdout);
247     }
248   if (args)
249     siggnal = atoi (args);
250   
251   detach (siggnal);
252   
253   inferior_ptid = null_ptid;
254   unpush_target (&deprecated_child_ops);
255 }
256
257 /* Get ready to modify the registers array.  On machines which store
258    individual registers, this doesn't need to do anything.  On machines
259    which store all the registers in one fell swoop, this makes sure
260    that registers contains all the registers from the program being
261    debugged.  */
262
263 static void
264 child_prepare_to_store (void)
265 {
266 #ifdef CHILD_PREPARE_TO_STORE
267   CHILD_PREPARE_TO_STORE ();
268 #endif
269 }
270
271 /* Print status information about what we're accessing.  */
272
273 static void
274 child_files_info (struct target_ops *ignore)
275 {
276   printf_unfiltered ("\tUsing the running image of %s %s.\n",
277       attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
278 }
279
280 static void
281 child_open (char *arg, int from_tty)
282 {
283   error ("Use the \"run\" command to start a Unix child process.");
284 }
285
286 /* Stub function which causes the inferior that runs it, to be ptrace-able
287    by its parent process.  */
288
289 static void
290 ptrace_me (void)
291 {
292   /* "Trace me, Dr. Memory!" */
293   call_ptrace (0, 0, (PTRACE_TYPE_ARG3) 0, 0);
294 }
295
296 /* Stub function which causes the GDB that runs it, to start ptrace-ing
297    the child process.  */
298
299 static void
300 ptrace_him (int pid)
301 {
302   push_target (&deprecated_child_ops);
303
304   /* On some targets, there must be some explicit synchronization
305      between the parent and child processes after the debugger
306      forks, and before the child execs the debuggee program.  This
307      call basically gives permission for the child to exec.
308    */
309
310   target_acknowledge_created_inferior (pid);
311
312   /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
313    * and will be 1 or 2 depending on whether we're starting
314    * without or with a shell.
315    */
316   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
317
318   /* On some targets, there must be some explicit actions taken after
319      the inferior has been started up.
320    */
321   target_post_startup_inferior (pid_to_ptid (pid));
322 }
323
324 /* Start an inferior Unix child process and sets inferior_ptid to its pid.
325    EXEC_FILE is the file to run.
326    ALLARGS is a string containing the arguments to the program.
327    ENV is the environment vector to pass.  Errors reported with error().  */
328
329 static void
330 child_create_inferior (char *exec_file, char *allargs, char **env,
331                        int from_tty)
332 {
333 #ifdef HPUXHPPA
334   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL);
335 #else
336   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL);
337 #endif
338   /* We are at the first instruction we care about.  */
339   observer_notify_inferior_created (&current_target, from_tty);
340   /* Pedal to the metal... */
341   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
342 }
343
344 #if !defined(CHILD_POST_STARTUP_INFERIOR)
345 void
346 child_post_startup_inferior (ptid_t ptid)
347 {
348   /* This version of Unix doesn't require a meaningful "post startup inferior"
349      operation by a debugger.
350    */
351 }
352 #endif
353
354 #if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR)
355 void
356 child_acknowledge_created_inferior (int pid)
357 {
358   /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
359      operation by a debugger.
360    */
361 }
362 #endif
363
364
365 #if !defined(CHILD_INSERT_FORK_CATCHPOINT)
366 int
367 child_insert_fork_catchpoint (int pid)
368 {
369   /* This version of Unix doesn't support notification of fork events.  */
370   return 0;
371 }
372 #endif
373
374 #if !defined(CHILD_REMOVE_FORK_CATCHPOINT)
375 int
376 child_remove_fork_catchpoint (int pid)
377 {
378   /* This version of Unix doesn't support notification of fork events.  */
379   return 0;
380 }
381 #endif
382
383 #if !defined(CHILD_INSERT_VFORK_CATCHPOINT)
384 int
385 child_insert_vfork_catchpoint (int pid)
386 {
387   /* This version of Unix doesn't support notification of vfork events.  */
388   return 0;
389 }
390 #endif
391
392 #if !defined(CHILD_REMOVE_VFORK_CATCHPOINT)
393 int
394 child_remove_vfork_catchpoint (int pid)
395 {
396   /* This version of Unix doesn't support notification of vfork events.  */
397   return 0;
398 }
399 #endif
400
401 #if !defined(CHILD_FOLLOW_FORK)
402 int
403 child_follow_fork (int follow_child)
404 {
405   /* This version of Unix doesn't support following fork or vfork events.  */
406   return 0;
407 }
408 #endif
409
410 #if !defined(CHILD_INSERT_EXEC_CATCHPOINT)
411 int
412 child_insert_exec_catchpoint (int pid)
413 {
414   /* This version of Unix doesn't support notification of exec events.  */
415   return 0;
416 }
417 #endif
418
419 #if !defined(CHILD_REMOVE_EXEC_CATCHPOINT)
420 int
421 child_remove_exec_catchpoint (int pid)
422 {
423   /* This version of Unix doesn't support notification of exec events.  */
424   return 0;
425 }
426 #endif
427
428 #if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
429 int
430 child_reported_exec_events_per_exec_call (void)
431 {
432   /* This version of Unix doesn't support notification of exec events.
433    */
434   return 1;
435 }
436 #endif
437
438 #if !defined(CHILD_HAS_EXITED)
439 int
440 child_has_exited (int pid, int wait_status, int *exit_status)
441 {
442   if (WIFEXITED (wait_status))
443     {
444       *exit_status = WEXITSTATUS (wait_status);
445       return 1;
446     }
447
448   if (WIFSIGNALED (wait_status))
449     {
450       *exit_status = 0;         /* ?? Don't know what else to say here. */
451       return 1;
452     }
453
454   /* ?? Do we really need to consult the event state, too?  Assume the
455      wait_state alone suffices.
456    */
457   return 0;
458 }
459 #endif
460
461
462 static void
463 child_mourn_inferior (void)
464 {
465   unpush_target (&deprecated_child_ops);
466   generic_mourn_inferior ();
467 }
468
469 static int
470 child_can_run (void)
471 {
472   /* This variable is controlled by modules that sit atop inftarg that may layer
473      their own process structure atop that provided here.  hpux-thread.c does
474      this because of the Hpux user-mode level thread model.  */
475
476   return !child_suppress_run;
477 }
478
479 /* Send a SIGINT to the process group.  This acts just like the user typed a
480    ^C on the controlling terminal.
481
482    XXX - This may not be correct for all systems.  Some may want to use
483    killpg() instead of kill (-pgrp). */
484
485 static void
486 child_stop (void)
487 {
488   kill (-inferior_process_group, SIGINT);
489 }
490
491 #if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK)
492 struct symtab_and_line *
493 child_enable_exception_callback (enum exception_event_kind kind, int enable)
494 {
495   return (struct symtab_and_line *) NULL;
496 }
497 #endif
498
499 #if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT)
500 struct exception_event_record *
501 child_get_current_exception_event (void)
502 {
503   return (struct exception_event_record *) NULL;
504 }
505 #endif
506
507
508 #if !defined(CHILD_PID_TO_EXEC_FILE)
509 char *
510 child_pid_to_exec_file (int pid)
511 {
512   /* This version of Unix doesn't support translation of a process ID
513      to the filename of the executable file.
514    */
515   return NULL;
516 }
517 #endif
518
519 char *
520 child_core_file_to_sym_file (char *core)
521 {
522   /* The target stratum for a running executable need not support
523      this operation.
524    */
525   return NULL;
526 }
527
528 /* Perform a partial transfer to/from the specified object.  For
529    memory transfers, fall back to the old memory xfer functions.  */
530
531 static LONGEST
532 child_xfer_partial (struct target_ops *ops, enum target_object object,
533                     const char *annex, void *readbuf,
534                     const void *writebuf, ULONGEST offset, LONGEST len)
535 {
536   switch (object)
537     {
538     case TARGET_OBJECT_MEMORY:
539       if (readbuf)
540         return child_xfer_memory (offset, readbuf, len, 0/*write*/,
541                                   NULL, ops);
542       if (writebuf)
543         return child_xfer_memory (offset, (void *) writebuf, len, 1/*write*/,
544                                   NULL, ops);
545       return -1;
546
547     case TARGET_OBJECT_UNWIND_TABLE:
548 #ifndef NATIVE_XFER_UNWIND_TABLE
549 #define NATIVE_XFER_UNWIND_TABLE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
550 #endif
551       return NATIVE_XFER_UNWIND_TABLE (ops, object, annex, readbuf, writebuf,
552                                        offset, len);
553
554     case TARGET_OBJECT_AUXV:
555 #ifndef NATIVE_XFER_AUXV
556 #define NATIVE_XFER_AUXV(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
557 #endif
558       return NATIVE_XFER_AUXV (ops, object, annex, readbuf, writebuf,
559                                offset, len);
560
561     case TARGET_OBJECT_WCOOKIE:
562 #ifndef NATIVE_XFER_WCOOKIE
563 #define NATIVE_XFER_WCOOKIE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
564 #endif
565       return NATIVE_XFER_WCOOKIE (ops, object, annex, readbuf, writebuf,
566                                   offset, len);
567
568     default:
569       return -1;
570     }
571 }
572
573 #if !defined(CHILD_PID_TO_STR)
574 char *
575 child_pid_to_str (ptid_t ptid)
576 {
577   return normal_pid_to_str (ptid);
578 }
579 #endif
580
581 static void
582 init_child_ops (void)
583 {
584   deprecated_child_ops.to_shortname = "child";
585   deprecated_child_ops.to_longname = "Unix child process";
586   deprecated_child_ops.to_doc = "Unix child process (started by the \"run\" command).";
587   deprecated_child_ops.to_open = child_open;
588   deprecated_child_ops.to_attach = child_attach;
589   deprecated_child_ops.to_post_attach = child_post_attach;
590   deprecated_child_ops.to_detach = child_detach;
591   deprecated_child_ops.to_resume = child_resume;
592   deprecated_child_ops.to_wait = child_wait;
593   deprecated_child_ops.to_fetch_registers = fetch_inferior_registers;
594   deprecated_child_ops.to_store_registers = store_inferior_registers;
595   deprecated_child_ops.to_prepare_to_store = child_prepare_to_store;
596   deprecated_child_ops.deprecated_xfer_memory = child_xfer_memory;
597   deprecated_child_ops.to_xfer_partial = child_xfer_partial;
598   deprecated_child_ops.to_files_info = child_files_info;
599   deprecated_child_ops.to_insert_breakpoint = memory_insert_breakpoint;
600   deprecated_child_ops.to_remove_breakpoint = memory_remove_breakpoint;
601   deprecated_child_ops.to_terminal_init = terminal_init_inferior;
602   deprecated_child_ops.to_terminal_inferior = terminal_inferior;
603   deprecated_child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
604   deprecated_child_ops.to_terminal_save_ours = terminal_save_ours;
605   deprecated_child_ops.to_terminal_ours = terminal_ours;
606   deprecated_child_ops.to_terminal_info = child_terminal_info;
607   deprecated_child_ops.to_kill = kill_inferior;
608   deprecated_child_ops.to_create_inferior = child_create_inferior;
609   deprecated_child_ops.to_post_startup_inferior = child_post_startup_inferior;
610   deprecated_child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
611   deprecated_child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
612   deprecated_child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
613   deprecated_child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
614   deprecated_child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
615   deprecated_child_ops.to_follow_fork = child_follow_fork;
616   deprecated_child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
617   deprecated_child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
618   deprecated_child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
619   deprecated_child_ops.to_has_exited = child_has_exited;
620   deprecated_child_ops.to_mourn_inferior = child_mourn_inferior;
621   deprecated_child_ops.to_can_run = child_can_run;
622   deprecated_child_ops.to_thread_alive = child_thread_alive;
623   deprecated_child_ops.to_pid_to_str = child_pid_to_str;
624   deprecated_child_ops.to_stop = child_stop;
625   deprecated_child_ops.to_enable_exception_callback = child_enable_exception_callback;
626   deprecated_child_ops.to_get_current_exception_event = child_get_current_exception_event;
627   deprecated_child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
628   deprecated_child_ops.to_stratum = process_stratum;
629   deprecated_child_ops.to_has_all_memory = 1;
630   deprecated_child_ops.to_has_memory = 1;
631   deprecated_child_ops.to_has_stack = 1;
632   deprecated_child_ops.to_has_registers = 1;
633   deprecated_child_ops.to_has_execution = 1;
634   deprecated_child_ops.to_magic = OPS_MAGIC;
635 }
636
637 void
638 _initialize_inftarg (void)
639 {
640 #ifdef HAVE_OPTIONAL_PROC_FS
641   char procname[32];
642   int fd;
643
644   /* If we have an optional /proc filesystem (e.g. under OSF/1),
645      don't add ptrace support if we can access the running GDB via /proc.  */
646 #ifndef PROC_NAME_FMT
647 #define PROC_NAME_FMT "/proc/%05d"
648 #endif
649   sprintf (procname, PROC_NAME_FMT, getpid ());
650   fd = open (procname, O_RDONLY);
651   if (fd >= 0)
652     {
653       close (fd);
654       return;
655     }
656 #endif
657
658   init_child_ops ();
659   add_target (&deprecated_child_ops);
660 }