/* General utility routines for GDB, the GNU debugger.
- Copyright 1986, 1989, 1990-1992, 1995, 1996, 1998, 2000
+ Copyright 1986, 1989, 1990-1992, 1995, 1996, 1998, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
#undef reg
#endif
-#include "signals.h"
+#include <signal.h>
#include "gdbcmd.h"
#include "serial.h"
#include "bfd.h"
static void
do_close_cleanup (void *arg)
{
- close ((int) arg);
+ int *fd = arg;
+ close (*fd);
+ xfree (fd);
}
struct cleanup *
make_cleanup_close (int fd)
{
- /* int into void*. Outch!! */
- return make_cleanup (do_close_cleanup, (void *) fd);
+ int *saved_fd = xmalloc (sizeof (fd));
+ *saved_fd = fd;
+ return make_cleanup (do_close_cleanup, saved_fd);
}
static void
{
*pmy_chain = ptr->next; /* Do this first incase recursion */
(*ptr->function) (ptr->arg);
- free (ptr);
+ xfree (ptr);
}
}
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next;
- free (ptr);
+ xfree (ptr);
}
}
{
void **location = ptr;
if (location == NULL)
- internal_error ("free_current_contents: NULL pointer");
+ internal_error (__FILE__, __LINE__,
+ "free_current_contents: NULL pointer");
if (*location != NULL)
{
- free (*location);
+ xfree (*location);
*location = NULL;
}
}
{
}
-/* Add a continuation to the continuation list, the gloabl list
+/* Add a continuation to the continuation list, the global list
cmd_continuation. The new continuation will be added at the front.*/
void
-add_continuation (continuation_hook, arg_list)
- void (*continuation_hook) (struct continuation_arg *);
- struct continuation_arg *arg_list;
+add_continuation (void (*continuation_hook) (struct continuation_arg *),
+ struct continuation_arg *arg_list)
{
struct continuation *continuation_ptr;
(continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
saved_continuation = continuation_ptr;
continuation_ptr = continuation_ptr->next;
- free (saved_continuation);
+ xfree (saved_continuation);
}
}
{
continuation_ptr = cmd_continuation;
cmd_continuation = continuation_ptr->next;
- free (continuation_ptr);
+ xfree (continuation_ptr);
}
}
/* Add a continuation to the continuation list, the global list
intermediate_continuation. The new continuation will be added at the front.*/
void
-add_intermediate_continuation (continuation_hook, arg_list)
- void (*continuation_hook) (struct continuation_arg *);
- struct continuation_arg *arg_list;
+add_intermediate_continuation (void (*continuation_hook)
+ (struct continuation_arg *),
+ struct continuation_arg *arg_list)
{
struct continuation *continuation_ptr;
(continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
saved_continuation = continuation_ptr;
continuation_ptr = continuation_ptr->next;
- free (saved_continuation);
+ xfree (saved_continuation);
}
}
{
continuation_ptr = intermediate_continuation;
intermediate_continuation = continuation_ptr->next;
- free (continuation_ptr);
+ xfree (continuation_ptr);
}
}
char *err_string;
struct cleanup *err_string_cleanup;
/* FIXME: cagney/1999-11-10: All error calls should come here.
- Unfortunatly some code uses the sequence: error_begin(); print
+ Unfortunately some code uses the sequence: error_begin(); print
error message; return_to_top_level. That code should be
flushed. */
error_begin ();
vfprintf_filtered (gdb_lasterr, string, args);
/* Retrieve the last error and print it to gdb_stderr */
err_string = error_last_message ();
- err_string_cleanup = make_cleanup (free, err_string);
+ err_string_cleanup = make_cleanup (xfree, err_string);
fputs_filtered (err_string, gdb_stderr);
fprintf_filtered (gdb_stderr, "\n");
do_cleanups (err_string_cleanup);
{
long size;
char *msg = ui_file_xstrdup (stream, &size);
- make_cleanup (free, msg);
+ make_cleanup (xfree, msg);
error ("%s", msg);
}
want to continue, dump core, or just exit. */
NORETURN void
-internal_verror (const char *fmt, va_list ap)
+internal_verror (const char *file, int line,
+ const char *fmt, va_list ap)
{
static char msg[] = "Internal GDB error: recursive internal error.\n";
static int dejavu = 0;
/* Try to get the message out */
target_terminal_ours ();
- fputs_unfiltered ("gdb-internal-error: ", gdb_stderr);
+ fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line);
vfprintf_unfiltered (gdb_stderr, fmt, ap);
fputs_unfiltered ("\n", gdb_stderr);
/* Default (no case) is to quit GDB. When in batch mode this
lessens the likelhood of GDB going into an infinate loop. */
continue_p = query ("\
-An internal GDB error was detected. This may make make further\n\
+An internal GDB error was detected. This may make further\n\
debugging unreliable. Continue this debugging session? ");
/* Default (no case) is to not dump core. Lessen the chance of GDB
}
NORETURN void
-internal_error (char *string, ...)
+internal_error (const char *file, int line, const char *string, ...)
{
va_list ap;
va_start (ap, string);
- internal_verror (string, ap);
+ internal_verror (file, line, string, ap);
va_end (ap);
}
void
mfree (PTR md, PTR ptr)
{
- free (ptr);
+ xfree (ptr);
}
#endif /* USE_MMALLOC */
{
if (size > 0)
{
- internal_error ("virtual memory exhausted: can't allocate %ld bytes.", size);
+ internal_error (__FILE__, __LINE__,
+ "virtual memory exhausted: can't allocate %ld bytes.", size);
}
else
{
- internal_error ("virtual memory exhausted.");
+ internal_error (__FILE__, __LINE__,
+ "virtual memory exhausted.");
}
}
{
return (xmrealloc ((PTR) NULL, ptr, size));
}
+
+/* Free up space allocated by one of xmalloc(), xcalloc(), or
+ xrealloc(). */
+
+void
+xfree (void *ptr)
+{
+ if (ptr != NULL)
+ free (ptr);
+}
\f
+/* Like asprintf/vasprintf but get an internal_error if the call
+ fails. */
+
+void
+xasprintf (char **ret, const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ xvasprintf (ret, format, args);
+ va_end (args);
+}
+
+void
+xvasprintf (char **ret, const char *format, va_list ap)
+{
+ int status = vasprintf (ret, format, ap);
+ /* NULL could be returned due to a memory allocation problem; a
+ badly format string; or something else. */
+ if ((*ret) == NULL)
+ internal_error (__FILE__, __LINE__,
+ "vasprintf returned NULL buffer (errno %d)",
+ errno);
+ /* A negative status with a non-NULL buffer shouldn't never
+ happen. But to be sure. */
+ if (status < 0)
+ internal_error (__FILE__, __LINE__,
+ "vasprintf call failed (errno %d)",
+ errno);
+}
+
+
/* My replacement for the read system call.
Used like `read' but keeps going if `read' returns too soon. */
return p;
}
-/* The "const" is so it compiles under DGUX (which prototypes strsave
- in <string.h>. FIXME: This should be named "xstrsave", shouldn't it?
- Doesn't real strsave return NULL if out of memory? */
-char *
-strsave (const char *ptr)
-{
- return savestring (ptr, strlen (ptr));
-}
-
char *
mstrsave (void *md, const char *ptr)
{
be call for printing things which are independent of the language
of the program being debugged. */
-static void printchar (int c, void (*do_fputs) (const char *, struct ui_file*), void (*do_fprintf) (struct ui_file*, const char *, ...), struct ui_file *stream, int quoter);
-
static void
-printchar (c, do_fputs, do_fprintf, stream, quoter)
- int c;
- void (*do_fputs) (const char *, struct ui_file *);
- void (*do_fprintf) (struct ui_file *, const char *, ...);
- struct ui_file *stream;
- int quoter;
+printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
+ void (*do_fprintf) (struct ui_file *, const char *, ...),
+ struct ui_file *stream, int quoter)
{
c &= 0xFF; /* Avoid sign bit follies */
else
async_request_quit (0);
}
- free (ignore);
+ xfree (ignore);
}
immediate_quit--;
return c;
}
+/* Write character C to gdb_stdout using GDB's paging mechanism and return C.
+ May return nonlocally. */
+
+int
+putchar_filtered (int c)
+{
+ return fputc_filtered (c, gdb_stdout);
+}
+
int
fputc_unfiltered (int c, struct ui_file *stream)
{
char *linebuffer;
struct cleanup *old_cleanups;
- vasprintf (&linebuffer, format, args);
- if (linebuffer == NULL)
- {
- fputs_unfiltered ("\ngdb: virtual memory exhausted.\n", gdb_stderr);
- exit (1);
- }
- old_cleanups = make_cleanup (free, linebuffer);
+ xvasprintf (&linebuffer, format, args);
+ old_cleanups = make_cleanup (xfree, linebuffer);
fputs_maybe_filtered (linebuffer, stream, filter);
do_cleanups (old_cleanups);
}
char *linebuffer;
struct cleanup *old_cleanups;
- vasprintf (&linebuffer, format, args);
- if (linebuffer == NULL)
- {
- fputs_unfiltered ("\ngdb: virtual memory exhausted.\n", gdb_stderr);
- exit (1);
- }
- old_cleanups = make_cleanup (free, linebuffer);
+ xvasprintf (&linebuffer, format, args);
+ old_cleanups = make_cleanup (xfree, linebuffer);
fputs_unfiltered (linebuffer, stream);
do_cleanups (old_cleanups);
}
if (n > max_spaces)
{
if (spaces)
- free (spaces);
+ xfree (spaces);
spaces = (char *) xmalloc (n + 1);
for (t = spaces + n; t != spaces;)
*--t = ' ';
fputs_filtered (demangled ? demangled : name, stream);
if (demangled != NULL)
{
- free (demangled);
+ xfree (demangled);
}
}
}
int
strlen_paddr (void)
{
- return (TARGET_PTR_BIT / 8 * 2);
+ return (TARGET_ADDR_BIT / 8 * 2);
}
char *
paddr (CORE_ADDR addr)
{
- return phex (addr, TARGET_PTR_BIT / 8);
+ return phex (addr, TARGET_ADDR_BIT / 8);
}
char *
paddr_nz (CORE_ADDR addr)
{
- return phex_nz (addr, TARGET_PTR_BIT / 8);
+ return phex_nz (addr, TARGET_ADDR_BIT / 8);
}
static void
host_pointer_to_address (void *ptr)
{
if (sizeof (ptr) != TYPE_LENGTH (builtin_type_ptr))
- internal_error ("core_addr_to_void_ptr: bad cast");
+ internal_error (__FILE__, __LINE__,
+ "core_addr_to_void_ptr: bad cast");
return POINTER_TO_ADDRESS (builtin_type_ptr, &ptr);
}
{
void *ptr;
if (sizeof (ptr) != TYPE_LENGTH (builtin_type_ptr))
- internal_error ("core_addr_to_void_ptr: bad cast");
+ internal_error (__FILE__, __LINE__,
+ "core_addr_to_void_ptr: bad cast");
ADDRESS_TO_POINTER (builtin_type_ptr, &ptr, addr);
return ptr;
}