OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [fork-child.c] - Blame information for rev 227

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Fork a Unix child process, and set up to debug it, for GDB.
2
 
3
   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
4
   2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010
5
   Free Software Foundation, Inc.
6
 
7
   Contributed by Cygnus Support.
8
 
9
   This file is part of GDB.
10
 
11
   This program is free software; you can redistribute it and/or modify
12
   it under the terms of the GNU General Public License as published by
13
   the Free Software Foundation; either version 3 of the License, or
14
   (at your option) any later version.
15
 
16
   This program is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
   GNU General Public License for more details.
20
 
21
   You should have received a copy of the GNU General Public License
22
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23
 
24
#include "defs.h"
25
#include "gdb_string.h"
26
#include "inferior.h"
27
#include "terminal.h"
28
#include "target.h"
29
#include "gdb_wait.h"
30
#include "gdb_vfork.h"
31
#include "gdbcore.h"
32
#include "terminal.h"
33
#include "gdbthread.h"
34
#include "command.h" /* for dont_repeat () */
35
#include "gdbcmd.h"
36
#include "solib.h"
37
 
38
#include <signal.h>
39
 
40
/* This just gets used as a default if we can't find SHELL.  */
41
#define SHELL_FILE "/bin/sh"
42
 
43
extern char **environ;
44
 
45
static char *exec_wrapper;
46
 
47
/* Break up SCRATCH into an argument vector suitable for passing to
48
   execvp and store it in ARGV.  E.g., on "run a b c d" this routine
49
   would get as input the string "a b c d", and as output it would
50
   fill in ARGV with the four arguments "a", "b", "c", "d".  */
51
 
52
static void
53
breakup_args (char *scratch, char **argv)
54
{
55
  char *cp = scratch;
56
 
57
  for (;;)
58
    {
59
      /* Scan past leading separators */
60
      while (*cp == ' ' || *cp == '\t' || *cp == '\n')
61
        cp++;
62
 
63
      /* Break if at end of string.  */
64
      if (*cp == '\0')
65
        break;
66
 
67
      /* Take an arg.  */
68
      *argv++ = cp;
69
 
70
      /* Scan for next arg separator.  */
71
      cp = strchr (cp, ' ');
72
      if (cp == NULL)
73
        cp = strchr (cp, '\t');
74
      if (cp == NULL)
75
        cp = strchr (cp, '\n');
76
 
77
      /* No separators => end of string => break.  */
78
      if (cp == NULL)
79
        break;
80
 
81
      /* Replace the separator with a terminator.  */
82
      *cp++ = '\0';
83
    }
84
 
85
  /* Null-terminate the vector.  */
86
  *argv = NULL;
87
}
88
 
89
/* When executing a command under the given shell, return non-zero if
90
   the '!' character should be escaped when embedded in a quoted
91
   command-line argument.  */
92
 
93
static int
94
escape_bang_in_quoted_argument (const char *shell_file)
95
{
96
  const int shell_file_len = strlen (shell_file);
97
 
98
  /* Bang should be escaped only in C Shells.  For now, simply check
99
     that the shell name ends with 'csh', which covers at least csh
100
     and tcsh.  This should be good enough for now.  */
101
 
102
  if (shell_file_len < 3)
103
    return 0;
104
 
105
  if (shell_file[shell_file_len - 3] == 'c'
106
      && shell_file[shell_file_len - 2] == 's'
107
      && shell_file[shell_file_len - 1] == 'h')
108
    return 1;
109
 
110
  return 0;
111
}
112
 
113
/* Start an inferior Unix child process and sets inferior_ptid to its
114
   pid.  EXEC_FILE is the file to run.  ALLARGS is a string containing
115
   the arguments to the program.  ENV is the environment vector to
116
   pass.  SHELL_FILE is the shell file, or NULL if we should pick
117
   one.  */
118
 
119
/* This function is NOT reentrant.  Some of the variables have been
120
   made static to ensure that they survive the vfork call.  */
121
 
122
int
123
fork_inferior (char *exec_file_arg, char *allargs, char **env,
124
               void (*traceme_fun) (void), void (*init_trace_fun) (int),
125
               void (*pre_trace_fun) (void), char *shell_file_arg)
126
{
127
  int pid;
128
  char *shell_command;
129
  static char default_shell_file[] = SHELL_FILE;
130
  int len;
131
  /* Set debug_fork then attach to the child while it sleeps, to debug. */
132
  static int debug_fork = 0;
133
  /* This is set to the result of setpgrp, which if vforked, will be visible
134
     to you in the parent process.  It's only used by humans for debugging.  */
135
  static int debug_setpgrp = 657473;
136
  static char *shell_file;
137
  static char *exec_file;
138
  char **save_our_env;
139
  int shell = 0;
140
  static char **argv;
141
  const char *inferior_io_terminal = get_inferior_io_terminal ();
142
  struct inferior *inf;
143
 
144
  /* If no exec file handed to us, get it from the exec-file command
145
     -- with a good, common error message if none is specified.  */
146
  exec_file = exec_file_arg;
147
  if (exec_file == 0)
148
    exec_file = get_exec_file (1);
149
 
150
  /* STARTUP_WITH_SHELL is defined in inferior.h.  If 0,e we'll just
151
    do a fork/exec, no shell, so don't bother figuring out what
152
    shell.  */
153
  shell_file = shell_file_arg;
154
  if (STARTUP_WITH_SHELL)
155
    {
156
      /* Figure out what shell to start up the user program under.  */
157
      if (shell_file == NULL)
158
        shell_file = getenv ("SHELL");
159
      if (shell_file == NULL)
160
        shell_file = default_shell_file;
161
      shell = 1;
162
    }
163
 
164
  /* Multiplying the length of exec_file by 4 is to account for the
165
     fact that it may expand when quoted; it is a worst-case number
166
     based on every character being '.  */
167
  len = 5 + 4 * strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop */ 12;
168
  if (exec_wrapper)
169
    len += strlen (exec_wrapper) + 1;
170
 
171
  shell_command = (char *) alloca (len);
172
  shell_command[0] = '\0';
173
 
174
  if (!shell)
175
    {
176
      /* We're going to call execvp.  Create argument vector.
177
         Calculate an upper bound on the length of the vector by
178
         assuming that every other character is a separate
179
         argument.  */
180
      int argc = (strlen (allargs) + 1) / 2 + 2;
181
      argv = (char **) xmalloc (argc * sizeof (*argv));
182
      argv[0] = exec_file;
183
      breakup_args (allargs, &argv[1]);
184
    }
185
  else
186
    {
187
      /* We're going to call a shell.  */
188
 
189
      char *p;
190
      int need_to_quote;
191
      const int escape_bang = escape_bang_in_quoted_argument (shell_file);
192
 
193
      strcat (shell_command, "exec ");
194
 
195
      /* Add any exec wrapper.  That may be a program name with arguments, so
196
         the user must handle quoting.  */
197
      if (exec_wrapper)
198
        {
199
          strcat (shell_command, exec_wrapper);
200
          strcat (shell_command, " ");
201
        }
202
 
203
      /* Now add exec_file, quoting as necessary.  */
204
 
205
      /* Quoting in this style is said to work with all shells.  But
206
         csh on IRIX 4.0.1 can't deal with it.  So we only quote it if
207
         we need to.  */
208
      p = exec_file;
209
      while (1)
210
        {
211
          switch (*p)
212
            {
213
            case '\'':
214
            case '!':
215
            case '"':
216
            case '(':
217
            case ')':
218
            case '$':
219
            case '&':
220
            case ';':
221
            case '<':
222
            case '>':
223
            case ' ':
224
            case '\n':
225
            case '\t':
226
              need_to_quote = 1;
227
              goto end_scan;
228
 
229
            case '\0':
230
              need_to_quote = 0;
231
              goto end_scan;
232
 
233
            default:
234
              break;
235
            }
236
          ++p;
237
        }
238
    end_scan:
239
      if (need_to_quote)
240
        {
241
          strcat (shell_command, "'");
242
          for (p = exec_file; *p != '\0'; ++p)
243
            {
244
              if (*p == '\'')
245
                strcat (shell_command, "'\\''");
246
              else if (*p == '!' && escape_bang)
247
                strcat (shell_command, "\\!");
248
              else
249
                strncat (shell_command, p, 1);
250
            }
251
          strcat (shell_command, "'");
252
        }
253
      else
254
        strcat (shell_command, exec_file);
255
 
256
      strcat (shell_command, " ");
257
      strcat (shell_command, allargs);
258
    }
259
 
260
  /* On some systems an exec will fail if the executable is open.  */
261
  close_exec_file ();
262
 
263
  /* Retain a copy of our environment variables, since the child will
264
     replace the value of environ and if we're vforked, we have to
265
     restore it.  */
266
  save_our_env = environ;
267
 
268
  /* Tell the terminal handling subsystem what tty we plan to run on;
269
     it will just record the information for later.  */
270
  new_tty_prefork (inferior_io_terminal);
271
 
272
  /* It is generally good practice to flush any possible pending stdio
273
     output prior to doing a fork, to avoid the possibility of both
274
     the parent and child flushing the same data after the fork. */
275
  gdb_flush (gdb_stdout);
276
  gdb_flush (gdb_stderr);
277
 
278
  /* If there's any initialization of the target layers that must
279
     happen to prepare to handle the child we're about fork, do it
280
     now...  */
281
  if (pre_trace_fun != NULL)
282
    (*pre_trace_fun) ();
283
 
284
  /* Create the child process.  Since the child process is going to
285
     exec(3) shortly afterwards, try to reduce the overhead by
286
     calling vfork(2).  However, if PRE_TRACE_FUN is non-null, it's
287
     likely that this optimization won't work since there's too much
288
     work to do between the vfork(2) and the exec(3).  This is known
289
     to be the case on ttrace(2)-based HP-UX, where some handshaking
290
     between parent and child needs to happen between fork(2) and
291
     exec(2).  However, since the parent is suspended in the vforked
292
     state, this doesn't work.  Also note that the vfork(2) call might
293
     actually be a call to fork(2) due to the fact that autoconf will
294
     ``#define vfork fork'' on certain platforms.  */
295
  if (pre_trace_fun || debug_fork)
296
    pid = fork ();
297
  else
298
    pid = vfork ();
299
 
300
  if (pid < 0)
301
    perror_with_name (("vfork"));
302
 
303
  if (pid == 0)
304
    {
305
      if (debug_fork)
306
        sleep (debug_fork);
307
 
308
      /* Create a new session for the inferior process, if necessary.
309
         It will also place the inferior in a separate process group.  */
310
      if (create_tty_session () <= 0)
311
        {
312
          /* No session was created, but we still want to run the inferior
313
             in a separate process group.  */
314
          debug_setpgrp = gdb_setpgid ();
315
          if (debug_setpgrp == -1)
316
            perror ("setpgrp failed in child");
317
        }
318
 
319
      /* Ask the tty subsystem to switch to the one we specified
320
         earlier (or to share the current terminal, if none was
321
         specified).  */
322
      new_tty ();
323
 
324
      /* Changing the signal handlers for the inferior after
325
         a vfork can also change them for the superior, so we don't mess
326
         with signals here.  See comments in
327
         initialize_signals for how we get the right signal handlers
328
         for the inferior.  */
329
 
330
      /* "Trace me, Dr. Memory!" */
331
      (*traceme_fun) ();
332
 
333
      /* The call above set this process (the "child") as debuggable
334
        by the original gdb process (the "parent").  Since processes
335
        (unlike people) can have only one parent, if you are debugging
336
        gdb itself (and your debugger is thus _already_ the
337
        controller/parent for this child), code from here on out is
338
        undebuggable.  Indeed, you probably got an error message
339
        saying "not parent".  Sorry; you'll have to use print
340
        statements!  */
341
 
342
      /* There is no execlpe call, so we have to set the environment
343
         for our child in the global variable.  If we've vforked, this
344
         clobbers the parent, but environ is restored a few lines down
345
         in the parent.  By the way, yes we do need to look down the
346
         path to find $SHELL.  Rich Pixley says so, and I agree.  */
347
      environ = env;
348
 
349
      /* If we decided above to start up with a shell, we exec the
350
         shell, "-c" says to interpret the next arg as a shell command
351
         to execute, and this command is "exec <target-program>
352
         <args>".  */
353
      if (shell)
354
        {
355
          execlp (shell_file, shell_file, "-c", shell_command, (char *) 0);
356
 
357
          /* If we get here, it's an error.  */
358
          fprintf_unfiltered (gdb_stderr, "Cannot exec %s: %s.\n", shell_file,
359
                              safe_strerror (errno));
360
          gdb_flush (gdb_stderr);
361
          _exit (0177);
362
        }
363
      else
364
        {
365
          /* Otherwise, we directly exec the target program with
366
             execvp.  */
367
          int i;
368
          char *errstring;
369
 
370
          execvp (exec_file, argv);
371
 
372
          /* If we get here, it's an error.  */
373
          errstring = safe_strerror (errno);
374
          fprintf_unfiltered (gdb_stderr, "Cannot exec %s ", exec_file);
375
 
376
          i = 1;
377
          while (argv[i] != NULL)
378
            {
379
              if (i != 1)
380
                fprintf_unfiltered (gdb_stderr, " ");
381
              fprintf_unfiltered (gdb_stderr, "%s", argv[i]);
382
              i++;
383
            }
384
          fprintf_unfiltered (gdb_stderr, ".\n");
385
#if 0
386
          /* This extra info seems to be useless.  */
387
          fprintf_unfiltered (gdb_stderr, "Got error %s.\n", errstring);
388
#endif
389
          gdb_flush (gdb_stderr);
390
          _exit (0177);
391
        }
392
    }
393
 
394
  /* Restore our environment in case a vforked child clob'd it.  */
395
  environ = save_our_env;
396
 
397
  if (!have_inferiors ())
398
    init_thread_list ();
399
 
400
  inf = current_inferior ();
401
 
402
  inferior_appeared (inf, pid);
403
 
404
  /* Needed for wait_for_inferior stuff below.  */
405
  inferior_ptid = pid_to_ptid (pid);
406
 
407
  new_tty_postfork ();
408
 
409
  /* We have something that executes now.  We'll be running through
410
     the shell at this point, but the pid shouldn't change.  Targets
411
     supporting MT should fill this task's ptid with more data as soon
412
     as they can.  */
413
  add_thread_silent (inferior_ptid);
414
 
415
  /* Now that we have a child process, make it our target, and
416
     initialize anything target-vector-specific that needs
417
     initializing.  */
418
  if (init_trace_fun)
419
    (*init_trace_fun) (pid);
420
 
421
  /* We are now in the child process of interest, having exec'd the
422
     correct program, and are poised at the first instruction of the
423
     new program.  */
424
  return pid;
425
}
426
 
427
/* Accept NTRAPS traps from the inferior.  */
428
 
429
void
430
startup_inferior (int ntraps)
431
{
432
  int pending_execs = ntraps;
433
  int terminal_initted = 0;
434
  ptid_t resume_ptid;
435
 
436
  if (target_supports_multi_process ())
437
    resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
438
  else
439
    resume_ptid = minus_one_ptid;
440
 
441
  /* The process was started by the fork that created it, but it will
442
     have stopped one instruction after execing the shell.  Here we
443
     must get it up to actual execution of the real program.  */
444
 
445
  if (exec_wrapper)
446
    pending_execs++;
447
 
448
  while (1)
449
    {
450
      int resume_signal = TARGET_SIGNAL_0;
451
      ptid_t event_ptid;
452
 
453
      struct target_waitstatus ws;
454
      memset (&ws, 0, sizeof (ws));
455
      event_ptid = target_wait (resume_ptid, &ws, 0);
456
 
457
      if (ws.kind == TARGET_WAITKIND_IGNORE)
458
        /* The inferior didn't really stop, keep waiting.  */
459
        continue;
460
 
461
      switch (ws.kind)
462
        {
463
          case TARGET_WAITKIND_SPURIOUS:
464
          case TARGET_WAITKIND_LOADED:
465
          case TARGET_WAITKIND_FORKED:
466
          case TARGET_WAITKIND_VFORKED:
467
          case TARGET_WAITKIND_SYSCALL_ENTRY:
468
          case TARGET_WAITKIND_SYSCALL_RETURN:
469
            /* Ignore gracefully during startup of the inferior.  */
470
            switch_to_thread (event_ptid);
471
            break;
472
 
473
          case TARGET_WAITKIND_SIGNALLED:
474
            target_terminal_ours ();
475
            target_mourn_inferior ();
476
            error (_("During startup program terminated with signal %s, %s."),
477
                   target_signal_to_name (ws.value.sig),
478
                   target_signal_to_string (ws.value.sig));
479
            return;
480
 
481
          case TARGET_WAITKIND_EXITED:
482
            target_terminal_ours ();
483
            target_mourn_inferior ();
484
            if (ws.value.integer)
485
              error (_("During startup program exited with code %d."),
486
                     ws.value.integer);
487
            else
488
              error (_("During startup program exited normally."));
489
            return;
490
 
491
          case TARGET_WAITKIND_EXECD:
492
            /* Handle EXEC signals as if they were SIGTRAP signals.  */
493
            xfree (ws.value.execd_pathname);
494
            resume_signal = TARGET_SIGNAL_TRAP;
495
            switch_to_thread (event_ptid);
496
            break;
497
 
498
          case TARGET_WAITKIND_STOPPED:
499
            resume_signal = ws.value.sig;
500
            switch_to_thread (event_ptid);
501
            break;
502
        }
503
 
504
      if (resume_signal != TARGET_SIGNAL_TRAP)
505
        {
506
          /* Let shell child handle its own signals in its own way.  */
507
          target_resume (resume_ptid, 0, resume_signal);
508
        }
509
      else
510
        {
511
          /* We handle SIGTRAP, however; it means child did an exec.  */
512
          if (!terminal_initted)
513
            {
514
              /* Now that the child has exec'd we know it has already
515
                 set its process group.  On POSIX systems, tcsetpgrp
516
                 will fail with EPERM if we try it before the child's
517
                 setpgid.  */
518
 
519
              /* Set up the "saved terminal modes" of the inferior
520
                 based on what modes we are starting it with.  */
521
              target_terminal_init ();
522
 
523
              /* Install inferior's terminal modes.  */
524
              target_terminal_inferior ();
525
 
526
              terminal_initted = 1;
527
            }
528
 
529
          if (--pending_execs == 0)
530
            break;
531
 
532
          /* Just make it go on.  */
533
          target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
534
        }
535
    }
536
 
537
  /* Mark all threads non-executing.  */
538
  set_executing (resume_ptid, 0);
539
}
540
 
541
/* Implement the "unset exec-wrapper" command.  */
542
 
543
static void
544
unset_exec_wrapper_command (char *args, int from_tty)
545
{
546
  xfree (exec_wrapper);
547
  exec_wrapper = NULL;
548
}
549
 
550
/* Provide a prototype to silence -Wmissing-prototypes.  */
551
extern initialize_file_ftype _initialize_fork_child;
552
 
553
void
554
_initialize_fork_child (void)
555
{
556
  add_setshow_filename_cmd ("exec-wrapper", class_run, &exec_wrapper, _("\
557
Set a wrapper for running programs.\n\
558
The wrapper prepares the system and environment for the new program."),
559
                            _("\
560
Show the wrapper for running programs."), NULL,
561
                            NULL, NULL,
562
                            &setlist, &showlist);
563
 
564
  add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
565
           _("Disable use of an execution wrapper."),
566
           &unsetlist);
567
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.