📄 main.c
字号:
voidsource_cleanup (stream) FILE *stream;{ /* Restore the previous input stream. */ instream = stream;}/* Read commands from STREAM. */static voidread_command_file (stream) FILE *stream;{ struct cleanup *cleanups; cleanups = make_cleanup (source_cleanup, instream); instream = stream; command_loop (); do_cleanups (cleanups);}/* * Process the core file argument. * We infer (lexically) from the name and (semantically) from the * corresponding file type what the target is. It's one of a live * user process (pid), a user process core dump (core), a kernel * crash dump (vmcore), a live kernel (/dev/mem), a remote kernel (/dev/ttya) * or a remote internet host (@127.0.0.1). */voiddo_core_arg(corefile, batch) char *corefile; int batch;{ struct stat stb; if (setjmp(to_top_level)) return; if (corefile[0] == '@') /* Internet host -- we're remote debugging. */ remote_open(corefile, 0); else if (stat(corefile, &stb) == 0) {#ifdef KERNELDEBUG if (S_ISCHR(stb.st_mode)) { /* * character device -- either we're debugging a live * kernel (/dev/mem, /dev/kmem) or a remote kernel * over a serial link. Use the heuristic that * /dev/mem has a "small" major device number. */ if (major(stb.st_rdev) <= 4) /* kernel memory */ kernel_core_open(corefile, !batch); else remote_open(corefile, !batch); } else if (kernel_debugging) /* a kernel crash dump */ kernel_core_open(corefile, !batch); else#endif core_file_command(corefile, !batch); } else if (isdigit(corefile[0])) attach_command(corefile, !batch); else /* * stat() failed and arg isn't a pid */ perror(corefile);}intmain (argc, argv) int argc; char **argv;{ int count; static int inhibit_gdbinit = 0; static int quiet = 1; static int batch = 0; /* Pointers to various arguments from command line. */ char *symarg = NULL; char *execarg = NULL; char *corearg = NULL; char *cdarg = NULL; char *ttyarg = NULL; char *cp; /* Pointers to all arguments of +command option. */ char **cmdarg; /* Allocated size of cmdarg. */ int cmdsize; /* Number of elements of cmdarg used. */ int ncmd; /* Indices of all arguments of +directory option. */ char **dirarg; /* Allocated size. */ int dirsize; /* Number of elements used. */ int ndir; register int i; /* XXX Windows only for xgdb. */ char *strrchr(); if (cp = strrchr(argv[0], '/')) ++cp; else cp = argv[0]; if (*cp != 'x') inhibit_windows = 1; /* This needs to happen before the first use of malloc. */ init_malloc ((PTR) NULL);#if defined (ALIGN_STACK_ON_STARTUP) i = (int) &count & 0x3; if (i != 0) alloca (4 - i);#endif /* If error() is called from initialization code, just exit */ if (setjmp (to_top_level)) { exit(1); } cmdsize = 1; cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg)); ncmd = 0; dirsize = 1; dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg)); ndir = 0; quit_flag = 0; instream = stdin; getcwd (dirbuf, sizeof (dirbuf)); current_directory = dirbuf;#ifdef SET_STACK_LIMIT_HUGE { struct rlimit rlim; /* Set the stack limit huge so that alloca (particularly stringtab * in dbxread.c) does not fail. */ getrlimit (RLIMIT_STACK, &rlim); original_stack_limit = rlim.rlim_cur; rlim.rlim_cur = rlim.rlim_max; setrlimit (RLIMIT_STACK, &rlim); }#endif /* SET_STACK_LIMIT_HUGE */ /* Parse arguments and options. */ { int c; static int print_help; /* When var field is 0, use flag field to record the equivalent short option (or arbitrary numbers starting at 10 for those with no equivalent). */ static struct option long_options[] = { {"readnow", no_argument, &readnow_symbol_files, 1}, {"r", no_argument, &readnow_symbol_files, 1}, {"mapped", no_argument, &mapped_symbol_files, 1}, {"m", no_argument, &mapped_symbol_files, 1}, {"quiet", no_argument, &quiet, 1}, {"q", no_argument, &quiet, 1}, {"version", no_argument, &quiet, 0}, {"nc", no_argument, &inhibit_confirm, 1}, {"nx", no_argument, &inhibit_gdbinit, 1}, {"nw", no_argument, &inhibit_windows, 1}, {"n", no_argument, &inhibit_gdbinit, 1}, {"batch", no_argument, &batch, 1}, {"epoch", no_argument, &epoch_interface, 1}, {"fullname", no_argument, &frame_file_full_name, 1}, {"f", no_argument, &frame_file_full_name, 1}, {"help", no_argument, &print_help, 1}, {"se", required_argument, 0, 10}, {"symbols", required_argument, 0, 's'}, {"s", required_argument, 0, 's'}, {"exec", required_argument, 0, 'e'}, {"e", required_argument, 0, 'e'}, {"core", required_argument, 0, 'c'}, {"c", required_argument, 0, 'c'}, {"command", required_argument, 0, 'x'}, {"x", required_argument, 0, 'x'}, {"directory", required_argument, 0, 'd'}, {"cd", required_argument, 0, 11}, {"tty", required_argument, 0, 't'}, {"baud", required_argument, 0, 'b'}, {"b", required_argument, 0, 'b'}, {"w", no_argument, &write_files, 1},#ifdef KERNELDEBUG {"k", no_argument, &kernel_debugging, 1},#endif/* Allow machine descriptions to add more options... */#ifdef ADDITIONAL_OPTIONS ADDITIONAL_OPTIONS#endif {0, no_argument, 0, 0}, }; while (1) { int option_index; c = getopt_long_only (argc, argv, "", long_options, &option_index); if (c == EOF) break; /* Long option that takes an argument. */ if (c == 0 && long_options[option_index].flag == 0) c = long_options[option_index].val; switch (c) { case 0: /* Long option that just sets a flag. */ break; case 10: symarg = optarg; execarg = optarg; break; case 11: cdarg = optarg; break; case 's': symarg = optarg; break; case 'e': execarg = optarg; break; case 'c': corearg = optarg; break; case 'x': cmdarg[ncmd++] = optarg; if (ncmd >= cmdsize) { cmdsize *= 2; cmdarg = (char **) xrealloc ((char *)cmdarg, cmdsize * sizeof (*cmdarg)); } break; case 'd': dirarg[ndir++] = optarg; if (ndir >= dirsize) { dirsize *= 2; dirarg = (char **) xrealloc ((char *)dirarg, dirsize * sizeof (*dirarg)); } break; case 't': ttyarg = optarg; break; case 'q': quiet = 1; break; case 'b': baud_rate = optarg; break;#ifdef ADDITIONAL_OPTION_CASES ADDITIONAL_OPTION_CASES#endif case '?': fprintf (stderr, "Use `%s +help' for a complete list of options.\n", argv[0]); exit (1); } } if (print_help) { fputs ("\This is GDB, the GNU debugger. Use the command\n\ gdb [options] [executable [core-file]]\n\to enter the debugger.\n\\n\Options available are:\n\ -help Print this message.\n\ -quiet Do not print version number on startup.\n\ -fullname Output information used by emacs-GDB interface.\n\ -epoch Output information used by epoch emacs-GDB interface.\n\ -batch Exit after processing options.\n\ -nx Do not read .gdbinit file.\n\ -tty=TTY Use TTY for input/output by the program being debugged.\n\ -cd=DIR Change current directory to DIR.\n\ -directory=DIR Search for source files in DIR.\n\ -command=FILE Execute GDB commands from FILE.\n\ -symbols=SYMFILE Read symbols from SYMFILE.\n\ -exec=EXECFILE Use EXECFILE as the executable.\n\ -se=FILE Use FILE as symbol file and executable file.\n\ -core=COREFILE Analyze the core dump COREFILE.\n\ -b BAUDRATE Set serial port baud rate used for remote debugging.\n\ -mapped Use mapped symbol files if supported on this system.\n\ -readnow Fully read symbol files on first access.\n\ -k Kernel debugging.\n\ -w Writeable text.\n\ -version Print GNU message and version number on startup.\n\ -nc Don't confirm quit or run commands.\n\", stderr);#ifdef ADDITIONAL_OPTION_HELP fputs (ADDITIONAL_OPTION_HELP, stderr);#endif fputs ("\n\For more information, type \"help\" from within GDB, or consult the\n\GDB manual (available as on-line info or a printed manual).\n", stderr); /* Exiting after printing this message seems like the most useful thing to do. */ exit (0); } /* OK, that's all the options. The other arguments are filenames. */ count = 0; for (; optind < argc; optind++) switch (++count) { case 1: symarg = argv[optind]; execarg = argv[optind]; break; case 2: corearg = argv[optind]; break; case 3: fprintf (stderr, "Excess command line arguments ignored. (%s%s)\n", argv[optind], (optind == argc - 1) ? "" : " ..."); break; } if (batch) quiet = 1; } /* Run the init function of each source file */ initialize_cmd_lists (); /* This needs to be done first */ initialize_all_files (); initialize_main (); /* But that omits this file! Do it now */ init_signals (); if (!quiet) { /* Print all the junk at the top, with trailing "..." if we are about to read a symbol file (possibly slowly). */ print_gnu_advertisement (); print_gdb_version (); if (symarg) printf_filtered (".."); wrap_here(""); fflush (stdout); /* Force to screen during slow operations */ } error_pre_print = "\n\n"; /* We may get more than one warning, don't double space all of them... */ warning_pre_print = "\nwarning: "; /* We need a default language for parsing expressions, so simple things like "set width 0" won't fail if no language is explicitly set in a config file or implicitly set by reading an executable during startup. */ set_language (language_c); expected_language = current_language; /* don't warn about the change. */ /* Now perform all the actions indicated by the arguments. */ if (cdarg != NULL) { if (!setjmp (to_top_level)) { cd_command (cdarg, 0); init_source_path (); } } do_cleanups (ALL_CLEANUPS); for (i = 0; i < ndir; i++) if (!setjmp (to_top_level)) directory_command (dirarg[i], 0); free ((PTR)dirarg); do_cleanups (ALL_CLEANUPS); if (execarg != NULL && symarg != NULL && strcmp (execarg, symarg) == 0) { /* The exec file and the symbol-file are the same. If we can't open it, better only print one error message. */ if (!setjmp (to_top_level)) { exec_file_command (execarg, !batch); symbol_file_command (symarg, 0); } } else { if (execarg != NULL) if (!setjmp (to_top_level)) exec_file_command (execarg, !batch); if (symarg != NULL) if (!setjmp (to_top_level)) symbol_file_command (symarg, 0); } do_cleanups (ALL_CLEANUPS); /* After the symbol file has been read, print a newline to get us beyond the copyright line... But errors should still set off the error message with a (single) blank line. */ if (!quiet) printf_filtered ("\n"); error_pre_print = "\n"; warning_pre_print = "\nwarning: "; if (corearg != NULL) do_core_arg(corearg, batch); do_cleanups (ALL_CLEANUPS); if (ttyarg != NULL) if (!setjmp (to_top_level)) tty_command (ttyarg, !batch); do_cleanups (ALL_CLEANUPS);#ifdef ADDITIONAL_OPTION_HANDLER ADDITIONAL_OPTION_HANDLER;#endif /* Error messages should no longer be distinguished with extra output. */ error_pre_print = 0; warning_pre_print = "warning: "; if (!inhibit_gdbinit) source_init_files(); for (i = 0; i < ncmd; i++) { if (!setjmp (to_top_level)) { if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0') read_command_file (stdin); else source_command (cmdarg[i], !batch); do_cleanups (ALL_CLEANUPS); } } free ((PTR)cmdarg); /* Read in the old history after all the command files have been read. */ initialize_history(); if (batch) { /* We have hit the end of the batch file. */ exit (0); } /* Do any host- or target-specific hacks. This is used for i960 targets to force the user to set a nindy target and spec its parameters. */#ifdef BEFORE_MAIN_LOOP_HOOK BEFORE_MAIN_LOOP_HOOK;#endif /* The command loop. */ while (1) { if (!setjmp (to_top_level)) { do_cleanups (ALL_CLEANUPS); /* Do complete cleanup */ command_loop (); quit_command ((char *)0, instream == stdin); } } /* No exit -- exit is through quit_command. */}voidexecute_user_command (c, args) struct cmd_list_element *c; char *args;{ register struct command_line *cmdlines; struct cleanup *old_chain; if (args) error ("User-defined commands cannot take arguments."); cmdlines = c->user_commands; if (cmdlines == 0) /* Null command */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -