diff options
Diffstat (limited to 'gdb/main.c')
-rw-r--r-- | gdb/main.c | 142 |
1 files changed, 96 insertions, 46 deletions
diff --git a/gdb/main.c b/gdb/main.c index 96df49c9815..42485c0e6d3 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -82,11 +82,44 @@ extern char *external_editor_command; #include <sys/cygwin.h> /* for cygwin32_conv_to_posix_path */ #endif -int -main (argc, argv) - int argc; - char **argv; +/* Call command_loop. If it happens to return, pass that through as a + non-zero return status. */ + +static int +captured_command_loop (void *data) { + if (command_loop_hook == NULL) + command_loop (); + else + command_loop_hook (); + /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton + would clean things up (restoring the cleanup chain) to the state + they were just prior to the call. Technically, this means that + the do_cleanups() below is redundant. Unfortunatly, many FUNC's + are not that well behaved. do_cleanups should either be replaced + with a do_cleanups call (to cover the problem) or an assertion + check to detect bad FUNCs code. */ + do_cleanups (ALL_CLEANUPS); + /* If the command_loop returned, normally (rather than threw an + error) we try to quit. If the quit is aborted, catch_errors() + which called this catch the signal and restart the command + loop. */ + quit_command (NULL, instream == stdin); + return 1; +} + +struct captured_main_args + { + int argc; + char **argv; + }; + +static int +captured_main (void *data) +{ + struct captured_main_args *context = data; + int argc = context->argc; + char **argv = context->argv; int count; static int quiet = 0; static int batch = 0; @@ -139,12 +172,6 @@ main (argc, argv) alloca (4 - i); #endif - /* If error() is called from initialization code, just exit */ - if (SET_TOP_LEVEL ()) - { - exit (1); - } - cmdsize = 1; cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg)); ncmd = 0; @@ -470,10 +497,8 @@ main (argc, argv) if (!inhibit_gdbinit) { - if (!SET_TOP_LEVEL ()) - source_command (homeinit, 0); + catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); /* Do stats; no need to do them elsewhere since we'll only need them if homedir is set. Make sure that they are @@ -491,41 +516,30 @@ main (argc, argv) /* Now perform all the actions indicated by the arguments. */ if (cdarg != NULL) { - if (!SET_TOP_LEVEL ()) - { - cd_command (cdarg, 0); - } + catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); for (i = 0; i < ndir; i++) - if (!SET_TOP_LEVEL ()) - directory_command (dirarg[i], 0); + catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL); free ((PTR) dirarg); - do_cleanups (ALL_CLEANUPS); if (execarg != NULL && symarg != NULL && STREQ (execarg, symarg)) { - /* The exec file and the symbol-file are the same. If we can't open - it, better only print one error message. */ - if (!SET_TOP_LEVEL ()) - { - exec_file_command (execarg, !batch); - symbol_file_command (symarg, 0); - } + /* The exec file and the symbol-file are the same. If we can't + open it, better only print one error message. + catch_command_errors returns non-zero on success! */ + if (catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL)) + catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL); } else { if (execarg != NULL) - if (!SET_TOP_LEVEL ()) - exec_file_command (execarg, !batch); + catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL); if (symarg != NULL) - if (!SET_TOP_LEVEL ()) - symbol_file_command (symarg, 0); + catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL); } - 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 @@ -538,17 +552,16 @@ main (argc, argv) if (corearg != NULL) { - if (!SET_TOP_LEVEL ()) - core_file_command (corearg, !batch); - else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ()) - attach_command (corearg, !batch); + if (catch_command_errors (core_file_command, corearg, !batch, RETURN_MASK_ALL) == 0) + { + /* See if the core file is really a PID. */ + if (isdigit (corearg[0])) + catch_command_errors (attach_command, corearg, !batch, RETURN_MASK_ALL); + } } - do_cleanups (ALL_CLEANUPS); if (ttyarg != NULL) - if (!SET_TOP_LEVEL ()) - tty_command (ttyarg, !batch); - do_cleanups (ALL_CLEANUPS); + catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); #ifdef ADDITIONAL_OPTION_HANDLER ADDITIONAL_OPTION_HANDLER; @@ -566,14 +579,15 @@ main (argc, argv) || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) if (!inhibit_gdbinit) { - if (!SET_TOP_LEVEL ()) - source_command (gdbinit, 0); + catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); for (i = 0; i < ncmd; i++) { - if (!SET_TOP_LEVEL ()) +#if 0 + /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that + expanded into a call to setjmp(). */ + if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */ { /* NOTE: I am commenting this out, because it is not clear where this feature is used. It is very old and @@ -586,6 +600,8 @@ main (argc, argv) source_command (cmdarg[i], !batch); do_cleanups (ALL_CLEANUPS); } +#endif + catch_command_errors (source_command, cmdarg[i], !batch, RETURN_MASK_ALL); } free ((PTR) cmdarg); @@ -632,6 +648,11 @@ main (argc, argv) The WIN32 Gui calls this main to set up gdb's state, and has its own command loop. */ #if !defined _WIN32 || defined __GNUC__ + /* GUIs generally have their own command loop, mainloop, or + whatever. This is a good place to gain control because many + error conditions will end up here via longjmp(). */ +#if 0 + /* FIXME: cagney/1999-11-06: The original main loop was like: */ while (1) { if (!SET_TOP_LEVEL ()) @@ -647,11 +668,40 @@ main (argc, argv) quit_command ((char *) 0, instream == stdin); } } - /* No exit -- exit is through quit_command. */ + /* NOTE: If the command_loop() returned normally, the loop would + attempt to exit by calling the function quit_command(). That + function would either call exit() or throw an error returning + control to SET_TOP_LEVEL. */ + /* NOTE: The function do_cleanups() was called once each time round + the loop. The usefulness of the call isn't clear. If an error + was thrown, everything would have already been cleaned up. If + command_loop() returned normally and quit_command() was called, + either exit() or error() (again cleaning up) would be called. */ +#endif + /* NOTE: cagney/1999-11-07: There is probably no reason for not + moving this loop and the code found in captured_command_loop() + into the command_loop() proper. The main thing holding back that + change - SET_TOP_LEVEL() - has been eliminated. */ + while (1) + { + catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); + } #endif + /* No exit -- exit is through quit_command. */ +} +int +main (int argc, char **argv) +{ + int top_level_val; + struct captured_main_args args; + args.argc = argc; + args.argv = argv; + catch_errors (captured_main, &args, "", RETURN_MASK_ALL); + return 0; } + /* Don't use *_filtered for printing help. We don't want to prompt for continue no matter how small the screen or how much we're going to print. */ |