xref: /openbsd/gnu/usr.bin/binutils/gdb/inftarg.c (revision 7b36286a)
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 }
661