From bf1d7d9ce0e35cfa01400e2da11f0d84ea89e481 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 6 Jan 2009 18:31:59 +0000 Subject: [PATCH] Check return values of functions declared with warn_unused_result attribute in GLIBC 2.8. * cli/cli-cmds.c (pwd_command): Check return value from getcwd. * inflow.c (check_syscall): New function. (new_tty): Use check_syscall to check return values from open and dup. * linux-nat.c (linux_nat_info_proc_cmd): Check return value from fgets. * main.c (captured_main): Call cwd after setting up gdb_stderr; check for errors from getcwd. * mi/mi-cmd-env.c (mi_cmd_env_pwd): Check return value from getcwd. * ui-file.c (stdio_file_write): Ignore return value from fwrite. (stdio_file_fputs): Same. * utils.c (internal_vproblem): abort if last-ditch error message write fails. --- gdb/ChangeLog | 14 ++++++++++++++ gdb/cli/cli-cmds.c | 4 +++- gdb/inflow.c | 26 ++++++++++++++++++-------- gdb/linux-nat.c | 6 ++++-- gdb/main.c | 12 +++++++++--- gdb/mi/mi-cmd-env.c | 5 ++++- gdb/ui-file.c | 8 ++++++-- gdb/utils.c | 14 ++++++++++---- 8 files changed, 68 insertions(+), 21 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 59caeab817..8c93b4aff6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,19 @@ 2009-01-06 Jim Blandy + Check return values of functions declared with warn_unused_result + attribute in GLIBC 2.8. + * cli/cli-cmds.c (pwd_command): Check return value from getcwd. + * inflow.c (check_syscall): New function. + (new_tty): Use check_syscall to check return values from open and dup. + * linux-nat.c (linux_nat_info_proc_cmd): Check return value from fgets. + * main.c (captured_main): Call cwd after setting up gdb_stderr; + check for errors from getcwd. + * mi/mi-cmd-env.c (mi_cmd_env_pwd): Check return value from getcwd. + * ui-file.c (stdio_file_write): Ignore return value from fwrite. + (stdio_file_fputs): Same. + * utils.c (internal_vproblem): abort if last-ditch error message + write fails. + * top.c (gdb_init): Don't set the current directory here; that's already been done in captured_main. diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index de35e1a3b0..b391e303ca 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -320,7 +320,9 @@ pwd_command (char *args, int from_tty) { if (args) error (_("The \"pwd\" command does not take an argument: %s"), args); - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); + if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf))) + error (_("Error finding name of working directory: %s"), + safe_strerror (errno)); if (strcmp (gdb_dirbuf, current_directory) != 0) printf_unfiltered (_("Working directory %s\n (canonically %s).\n"), diff --git a/gdb/inflow.c b/gdb/inflow.c index a7cb25f3c8..972b52ef73 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -523,6 +523,20 @@ new_tty_prefork (const char *ttyname) inferior_thisrun_terminal = ttyname; } + +/* If RESULT, assumed to be the return value from a system call, is + negative, print the error message indicated by errno and exit. + MSG should identify the operation that failed. */ +static void +check_syscall (const char *msg, int result) +{ + if (result < 0) + { + print_sys_errmsg (msg, errno); + _exit (1); + } +} + void new_tty (void) { @@ -549,27 +563,23 @@ new_tty (void) /* Now open the specified new terminal. */ tty = open (inferior_thisrun_terminal, O_RDWR | O_NOCTTY); - if (tty == -1) - { - print_sys_errmsg (inferior_thisrun_terminal, errno); - _exit (1); - } + check_syscall (inferior_thisrun_terminal, tty); /* Avoid use of dup2; doesn't exist on all systems. */ if (tty != 0) { close (0); - dup (tty); + check_syscall ("dup'ing tty into fd 0", dup (tty)); } if (tty != 1) { close (1); - dup (tty); + check_syscall ("dup'ing tty into fd 1", dup (tty)); } if (tty != 2) { close (2); - dup (tty); + check_syscall ("dup'ing tty into fd 2", dup (tty)); } #ifdef TIOCSCTTY diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index dfa7ef275b..9a7e39c3dc 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -3684,8 +3684,10 @@ linux_nat_info_proc_cmd (char *args, int from_tty) if ((procfile = fopen (fname1, "r")) != NULL) { struct cleanup *cleanup = make_cleanup_fclose (procfile); - fgets (buffer, sizeof (buffer), procfile); - printf_filtered ("cmdline = '%s'\n", buffer); + if (fgets (buffer, sizeof (buffer), procfile)) + printf_filtered ("cmdline = '%s'\n", buffer); + else + warning (_("unable to read '%s'"), fname1); do_cleanups (cleanup); } else diff --git a/gdb/main.c b/gdb/main.c index ccd5e46860..0eb95964e9 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -188,9 +188,6 @@ captured_main (void *data) line[0] = '\0'; /* Terminate saved (now empty) cmd line */ instream = stdin; - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - current_directory = gdb_dirbuf; - gdb_stdout = stdio_fileopen (stdout); gdb_stderr = stdio_fileopen (stderr); gdb_stdlog = gdb_stderr; /* for moment */ @@ -199,6 +196,15 @@ captured_main (void *data) gdb_stdtargerr = gdb_stderr; /* for moment */ gdb_stdtargin = gdb_stdin; /* for moment */ + if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf))) + /* Don't use *_filtered or warning() (which relies on + current_target) until after initialize_all_files(). */ + fprintf_unfiltered (gdb_stderr, + _("%s: warning: error finding working directory: %s\n"), + argv[0], safe_strerror (errno)); + + current_directory = gdb_dirbuf; + /* Set the sysroot path. */ #ifdef TARGET_SYSTEM_ROOT_RELOCATABLE gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT); diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c index b40fac4750..cbc9bdb7ce 100644 --- a/gdb/mi/mi-cmd-env.c +++ b/gdb/mi/mi-cmd-env.c @@ -79,7 +79,10 @@ mi_cmd_env_pwd (char *command, char **argv, int argc) /* Otherwise the mi level is 2 or higher. */ - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); + if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf))) + error (_("mi_cmd_env_pwd: error finding name of working directory: %s"), + safe_strerror (errno)); + ui_out_field_string (uiout, "cwd", gdb_dirbuf); } diff --git a/gdb/ui-file.c b/gdb/ui-file.c index a7ecde4dfc..02a031410c 100644 --- a/gdb/ui-file.c +++ b/gdb/ui-file.c @@ -481,7 +481,9 @@ stdio_file_write (struct ui_file *file, const char *buf, long length_buf) if (stdio->magic != &stdio_file_magic) internal_error (__FILE__, __LINE__, _("stdio_file_write: bad magic number")); - fwrite (buf, length_buf, 1, stdio->file); + /* Calling error crashes when we are called from the exception framework. */ + if (fwrite (buf, length_buf, 1, stdio->file)) + ; } static void @@ -491,7 +493,9 @@ stdio_file_fputs (const char *linebuffer, struct ui_file *file) if (stdio->magic != &stdio_file_magic) internal_error (__FILE__, __LINE__, _("stdio_file_fputs: bad magic number")); - fputs (linebuffer, stdio->file); + /* Calling error crashes when we are called from the exception framework. */ + if (fputs (linebuffer, stdio->file)) + ; } static int diff --git a/gdb/utils.c b/gdb/utils.c index 4740a48765..5ceb7aef64 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -862,10 +862,16 @@ internal_vproblem (struct internal_problem *problem, case 1: dejavu = 2; fputs_unfiltered (msg, gdb_stderr); - abort (); /* NOTE: GDB has only three calls to abort(). */ + abort (); /* NOTE: GDB has only four calls to abort(). */ default: dejavu = 3; - write (STDERR_FILENO, msg, sizeof (msg)); + /* Newer GLIBC versions put the warn_unused_result attribute + on write, but this is one of those rare cases where + ignoring the return value is correct. Casting to (void) + does not fix this problem. This is the solution suggested + at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509. */ + if (write (STDERR_FILENO, msg, sizeof (msg)) != sizeof (msg)) + abort (); /* NOTE: GDB has only four calls to abort(). */ exit (1); } } @@ -930,7 +936,7 @@ further debugging may prove unreliable.", file, line, problem->name, msg); if (quit_p) { if (dump_core_p) - abort (); /* NOTE: GDB has only three calls to abort(). */ + abort (); /* NOTE: GDB has only four calls to abort(). */ else exit (1); } @@ -940,7 +946,7 @@ further debugging may prove unreliable.", file, line, problem->name, msg); { #ifdef HAVE_WORKING_FORK if (fork () == 0) - abort (); /* NOTE: GDB has only three calls to abort(). */ + abort (); /* NOTE: GDB has only four calls to abort(). */ #endif } } -- 2.34.1