mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
gbacktrace: Ensure return values of write, dup and fgets are used
Make sure that we did not error when doing write or read operations, and in such case, just exit reporting the error.
This commit is contained in:
parent
8385f52db7
commit
0e4d8c2478
@ -45,6 +45,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
@ -175,9 +176,14 @@ g_on_error_query (const gchar *prg_name)
|
||||
fflush (stdout);
|
||||
|
||||
if (isatty(0) && isatty(1))
|
||||
fgets (buf, 8, stdin);
|
||||
{
|
||||
if (fgets (buf, 8, stdin) == NULL)
|
||||
_exit (0);
|
||||
}
|
||||
else
|
||||
strcpy (buf, "E\n");
|
||||
{
|
||||
strcpy (buf, "E\n");
|
||||
}
|
||||
|
||||
if ((buf[0] == 'E' || buf[0] == 'e')
|
||||
&& buf[1] == '\n')
|
||||
@ -314,6 +320,59 @@ stack_trace_sigchld (int signum)
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
static inline const char *
|
||||
get_strerror (char *buffer, gsize n)
|
||||
{
|
||||
#ifdef HAVE_STRERROR_R
|
||||
return strerror_r (errno, buffer, n);
|
||||
#else
|
||||
const char *error_str = strerror (errno);
|
||||
if (!error_str)
|
||||
return NULL;
|
||||
|
||||
strncpy (buffer, error_str, n);
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gssize
|
||||
checked_write (int fd, gconstpointer buf, gsize n)
|
||||
{
|
||||
gssize written = write (fd, buf, n);
|
||||
|
||||
if (written == -1)
|
||||
{
|
||||
char msg[BUFSIZE] = {0};
|
||||
char error_str[BUFSIZE / 2] = {0};
|
||||
|
||||
get_strerror (error_str, sizeof (error_str) - 1);
|
||||
snprintf (msg, sizeof (msg) - 1, "Unable to write to fd %d: %s", fd, error_str);
|
||||
perror (msg);
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static int
|
||||
checked_dup (int fd)
|
||||
{
|
||||
int new_fd = dup (fd);
|
||||
|
||||
if (new_fd == -1)
|
||||
{
|
||||
char msg[BUFSIZE] = {0};
|
||||
char error_str[BUFSIZE / 2] = {0};
|
||||
|
||||
get_strerror (error_str, sizeof (error_str) - 1);
|
||||
snprintf (msg, sizeof (msg) - 1, "Unable to duplicate fd %d: %s", fd, error_str);
|
||||
perror (msg);
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
return new_fd;
|
||||
}
|
||||
|
||||
static void
|
||||
stack_trace (const char * const *args)
|
||||
{
|
||||
@ -351,9 +410,12 @@ stack_trace (const char * const *args)
|
||||
(void) fcntl (old_err, F_SETFD, getfd | FD_CLOEXEC);
|
||||
}
|
||||
|
||||
close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
|
||||
close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
|
||||
close (2); dup (out_fd[1]); /* set the stderr to the out pipe */
|
||||
close (0);
|
||||
checked_dup (in_fd[0]); /* set the stdin to the in pipe */
|
||||
close (1);
|
||||
checked_dup (out_fd[1]); /* set the stdout to the out pipe */
|
||||
close (2);
|
||||
checked_dup (out_fd[1]); /* set the stderr to the out pipe */
|
||||
|
||||
execvp (args[0], (char **) args); /* exec gdb */
|
||||
|
||||
@ -361,7 +423,8 @@ stack_trace (const char * const *args)
|
||||
if (old_err != -1)
|
||||
{
|
||||
close (2);
|
||||
dup (old_err);
|
||||
/* We can ignore the return value here as we're failing anyways */
|
||||
(void) !dup (old_err);
|
||||
}
|
||||
perror ("exec " DEBUGGER " failed");
|
||||
_exit (0);
|
||||
@ -376,14 +439,14 @@ stack_trace (const char * const *args)
|
||||
FD_SET (out_fd[0], &fdset);
|
||||
|
||||
#ifdef USE_LLDB
|
||||
write (in_fd[1], "bt\n", 3);
|
||||
write (in_fd[1], "p x = 0\n", 8);
|
||||
write (in_fd[1], "process detach\n", 15);
|
||||
write (in_fd[1], "quit\n", 5);
|
||||
checked_write (in_fd[1], "bt\n", 3);
|
||||
checked_write (in_fd[1], "p x = 0\n", 8);
|
||||
checked_write (in_fd[1], "process detach\n", 15);
|
||||
checked_write (in_fd[1], "quit\n", 5);
|
||||
#else
|
||||
write (in_fd[1], "backtrace\n", 10);
|
||||
write (in_fd[1], "p x = 0\n", 8);
|
||||
write (in_fd[1], "quit\n", 5);
|
||||
checked_write (in_fd[1], "backtrace\n", 10);
|
||||
checked_write (in_fd[1], "p x = 0\n", 8);
|
||||
checked_write (in_fd[1], "quit\n", 5);
|
||||
#endif
|
||||
|
||||
idx = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user