* server.h (ATTR_MALLOC): New macro.
(xmalloc,xcalloc,xstrdup): Declare.
* hostio.c: Replace malloc,calloc,strdup with xmalloc,xcalloc,xstrdup.
* inferiors.c: Ditto.
* linux-low.c: Ditto.
* mem-break.c: Ditto.
* regcache.c: Ditto.
* remote-utils.c: Ditto.
* server.c: Ditto.
* target.c: Ditto.
* win32-low.c: Ditto.
+2008-12-13 Doug Evans <dje@google.com>
+
+ * utils.c (xmalloc,xcalloc,xstrdup): New fns.
+ * server.h (ATTR_MALLOC): New macro.
+ (xmalloc,xcalloc,xstrdup): Declare.
+ * hostio.c: Replace malloc,calloc,strdup with xmalloc,xcalloc,xstrdup.
+ * inferiors.c: Ditto.
+ * linux-low.c: Ditto.
+ * mem-break.c: Ditto.
+ * regcache.c: Ditto.
+ * remote-utils.c: Ditto.
+ * server.c: Ditto.
+ * target.c: Ditto.
+ * win32-low.c: Ditto.
+
2008-12-12 Doug Evans <dje@google.com>
* linux-low.c (linux_wait_for_process): Don't clobber current_inferior
{
int input_index, output_index, escaped;
- *data = malloc (p_len);
+ *data = xmalloc (p_len);
output_index = 0;
escaped = 0;
}
/* Record the new file descriptor. */
- new_fd = malloc (sizeof (struct fd_list));
+ new_fd = xmalloc (sizeof (struct fd_list));
new_fd->fd = fd;
new_fd->next = open_fds;
open_fds = new_fd;
return;
}
- data = malloc (len);
+ data = xmalloc (len);
#ifdef HAVE_PREAD
ret = pread (fd, data, len, offset);
#else
void
add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id)
{
- struct thread_info *new_thread = malloc (sizeof (*new_thread));
+ struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
memset (new_thread, 0, sizeof (*new_thread));
void
loaded_dll (const char *name, CORE_ADDR base_addr)
{
- struct dll_info *new_dll = malloc (sizeof (*new_dll));
+ struct dll_info *new_dll = xmalloc (sizeof (*new_dll));
memset (new_dll, 0, sizeof (*new_dll));
new_dll->entry.id = -1;
- new_dll->name = strdup (name);
+ new_dll->name = xstrdup (name);
new_dll->base_addr = base_addr;
add_inferior_to_list (&all_dlls, &new_dll->entry);
{
struct inferior_list_entry *new_entry;
- new_entry = malloc (sizeof (struct inferior_list_entry));
+ new_entry = xmalloc (sizeof (struct inferior_list_entry));
new_entry->id = pid;
add_inferior_to_list (list, new_entry);
}
{
struct process_info *process;
- process = (struct process_info *) malloc (sizeof (*process));
+ process = (struct process_info *) xmalloc (sizeof (*process));
memset (process, 0, sizeof (*process));
process->head.id = pid;
|| process->bp_reinsert != 0))
{
struct pending_signals *p_sig;
- p_sig = malloc (sizeof (*p_sig));
+ p_sig = xmalloc (sizeof (*p_sig));
p_sig->prev = process->pending_signals;
p_sig->signal = signal;
if (info == NULL)
if (process->resume->sig != 0)
{
struct pending_signals *p_sig;
- p_sig = malloc (sizeof (*p_sig));
+ p_sig = xmalloc (sizeof (*p_sig));
p_sig->prev = process->pending_signals;
p_sig->signal = process->resume->sig;
memset (&p_sig->info, 0, sizeof (siginfo_t));
continue;
}
- buf = malloc (regset->size);
+ buf = xmalloc (regset->size);
#ifndef __sparc__
res = ptrace (regset->get_request, inferior_pid, 0, buf);
#else
continue;
}
- buf = malloc (regset->size);
+ buf = xmalloc (regset->size);
/* First fill the buffer with the current register set contents,
in case there are any items in the kernel's regset that are
{
int child_pid, ret, status;
long second_pid;
- char *stack = malloc (STACK_SIZE * 4);
+ char *stack = xmalloc (STACK_SIZE * 4);
linux_supports_tracefork_flag = 0;
#ifdef HAVE_LINUX_REGSETS
for (num_regsets = 0; target_regsets[num_regsets].size >= 0; num_regsets++)
;
- disabled_regsets = malloc (num_regsets);
+ disabled_regsets = xmalloc (num_regsets);
#endif
}
if (breakpoint_data == NULL)
error ("Target does not support breakpoints.");
- bp = malloc (sizeof (struct breakpoint));
+ bp = xmalloc (sizeof (struct breakpoint));
memset (bp, 0, sizeof (struct breakpoint));
(*the_target->read_memory) (where, bp->old_data,
if (register_bytes == 0)
return NULL; /* The architecture hasn't been initialized yet. */
- regcache = malloc (sizeof (*regcache));
+ regcache = xmalloc (sizeof (*regcache));
/* Make sure to zero-initialize the register cache when it is created,
in case there are registers the target never fetches. This way they'll
read as zero instead of garbage. */
- regcache->registers = calloc (1, register_bytes);
+ regcache->registers = xcalloc (1, register_bytes);
if (regcache->registers == NULL)
fatal ("Could not allocate register cache.");
char buf3[1];
char *p;
- buf2 = malloc (PBUFSIZ);
+ buf2 = xmalloc (PBUFSIZ);
/* Copy the packet into buffer BUF2, encapsulating it
and giving it a checksum. */
unsigned int mem_len;
decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
- mem_buf = malloc (mem_len);
+ mem_buf = xmalloc (mem_len);
if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
convert_int_to_ascii (mem_buf, own_buf, mem_len);
else
decode_address (addrp, p, q - p);
/* Save the symbol in our cache. */
- sym = malloc (sizeof (*sym));
- sym->name = strdup (name);
+ sym = xmalloc (sizeof (*sym));
+ sym->name = xstrdup (name);
sym->addr = *addrp;
sym->next = symbol_cache;
symbol_cache = sym;
void
monitor_output (const char *msg)
{
- char *buf = malloc (strlen (msg) * 2 + 2);
+ char *buf = xmalloc (strlen (msg) * 2 + 2);
buf[0] = 'O';
hexify (buf + 1, msg, 0);
}
/* Expand the result. */
- result = malloc (i + special + 1);
+ result = xmalloc (i + special + 1);
for (i = 0, special = 0; text[i] != '\0'; i++)
switch (text[i])
{
CORE_ADDR found_addr;
int cmd_name_len = sizeof ("qSearch:memory:") - 1;
- pattern = malloc (packet_len);
+ pattern = xmalloc (packet_len);
if (pattern == NULL)
{
error ("Unable to allocate memory to perform the search");
if (search_space_len < search_buf_size)
search_buf_size = search_space_len;
- search_buf = malloc (search_buf_size);
+ search_buf = xmalloc (search_buf_size);
if (search_buf == NULL)
{
free (pattern);
return;
if (len > PBUFSIZ - 2)
len = PBUFSIZ - 2;
- spu_buf = malloc (len + 1);
+ spu_buf = xmalloc (len + 1);
if (!spu_buf)
return;
require_running (own_buf);
strcpy (own_buf, "E00");
- spu_buf = malloc (packet_len - 15);
+ spu_buf = xmalloc (packet_len - 15);
if (!spu_buf)
return;
if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex,
more. */
if (len > PBUFSIZ - 2)
len = PBUFSIZ - 2;
- data = malloc (len + 1);
+ data = xmalloc (len + 1);
n = (*the_target->read_auxv) (ofs, data, len + 1);
if (n < 0)
write_enn (own_buf);
for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name);
- document = malloc (total_len);
+ document = xmalloc (total_len);
strcpy (document, "<library-list>\n");
p = document + strlen (document);
return;
if (len > PBUFSIZ - 2)
len = PBUFSIZ - 2;
- workbuf = malloc (len + 1);
+ workbuf = xmalloc (len + 1);
if (!workbuf)
return;
/* Handle "monitor" commands. */
if (strncmp ("qRcmd,", own_buf, 6) == 0)
{
- char *mon = malloc (PBUFSIZ);
+ char *mon = xmalloc (PBUFSIZ);
int len = strlen (own_buf + 6);
if ((len % 2) != 0 || unhexify (mon, own_buf + 6, len / 2) != len / 2)
/* Allocate room for one extra action, for the default remain-stopped
behavior; if no default action is in the list, we'll need the extra
slot. */
- resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
+ resume_info = xmalloc ((n + 1) * sizeof (resume_info[0]));
default_action.thread = -1;
default_action.leave_stopped = 1;
new_argc++;
}
- new_argv = calloc (new_argc + 2, sizeof (char *));
+ new_argv = xcalloc (new_argc + 2, sizeof (char *));
i = 0;
for (p = own_buf + strlen ("vRun;"); *p; p = next_p)
{
new_argv[i] = NULL;
else
{
- new_argv[i] = malloc (1 + (next_p - p) / 2);
+ new_argv[i] = xmalloc (1 + (next_p - p) / 2);
unhexify (new_argv[i], p, (next_p - p) / 2);
new_argv[i][(next_p - p) / 2] = '\0';
}
return 0;
}
- new_argv[0] = strdup (program_argv[0]);
+ new_argv[0] = xstrdup (program_argv[0]);
}
/* Free the old argv. */
initialize_async_io ();
initialize_low ();
- own_buf = malloc (PBUFSIZ + 1);
- mem_buf = malloc (PBUFSIZ);
+ own_buf = xmalloc (PBUFSIZ + 1);
+ mem_buf = xmalloc (PBUFSIZ);
if (pid == 0 && *next_arg != NULL)
{
int i, n;
n = argc - (next_arg - argv);
- program_argv = malloc (sizeof (char *) * (n + 1));
+ program_argv = xmalloc (sizeof (char *) * (n + 1));
for (i = 0; i < n; i++)
- program_argv[i] = strdup (next_arg[i]);
+ program_argv[i] = xstrdup (next_arg[i]);
program_argv[i] = NULL;
/* Wait till we are at first instruction in program. */
#endif
#endif
+#ifndef ATTR_MALLOC
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define ATTR_MALLOC __attribute__ ((__malloc__))
+#else
+#define ATTR_MALLOC /* nothing */
+#endif
+#endif
+
/* A type used for binary buffers. */
typedef unsigned char gdb_byte;
/* Functions from utils.c */
+void *xmalloc (size_t) ATTR_MALLOC;
+void *xcalloc (size_t, size_t) ATTR_MALLOC;
+char *xstrdup (const char *) ATTR_MALLOC;
void perror_with_name (char *string);
void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
if (buffer != NULL)
free (buffer);
- buffer = malloc (len);
+ buffer = xmalloc (len);
memcpy (buffer, myaddr, len);
check_mem_write (memaddr, buffer, len);
res = (*the_target->write_memory) (memaddr, buffer, len);
void
set_target_ops (struct target_ops *target)
{
- the_target = (struct target_ops *) malloc (sizeof (*the_target));
+ the_target = (struct target_ops *) xmalloc (sizeof (*the_target));
memcpy (the_target, target, sizeof (*the_target));
}
/* Generally useful subroutines used throughout the program. */
+static void malloc_failure (size_t size) ATTR_NORETURN;
+
+static void
+malloc_failure (size_t size)
+{
+ fprintf (stderr, "gdbserver: ran out of memory while trying to allocate %lu bytes\n",
+ (unsigned long) size);
+ exit (1);
+}
+
+/* Allocate memory without fail.
+ If malloc fails, this will print a message to stderr and exit. */
+
+void *
+xmalloc (size_t size)
+{
+ void *newmem;
+
+ if (size == 0)
+ size = 1;
+ newmem = malloc (size);
+ if (!newmem)
+ malloc_failure (size);
+
+ return newmem;
+}
+
+/* Allocate memory without fail and set it to zero.
+ If malloc fails, this will print a message to stderr and exit. */
+
+void *
+xcalloc (size_t nelem, size_t elsize)
+{
+ void *newmem;
+
+ if (nelem == 0 || elsize == 0)
+ nelem = elsize = 1;
+
+ newmem = calloc (nelem, elsize);
+ if (!newmem)
+ malloc_failure (nelem * elsize);
+
+ return newmem;
+}
+
+/* Copy a string into a memory buffer.
+ If malloc fails, this will print a message to stderr and exit. */
+
+char *
+xstrdup (const char *s)
+{
+ char *ret = strdup (s);
+ if (ret == NULL)
+ malloc_failure (strlen (s) + 1);
+ return ret;
+}
+
/* Print the system error message for errno, and also mention STRING
as the file name for which the error was encountered.
Then return to command level. */
if ((th = thread_rec (tid, FALSE)))
return th;
- th = calloc (1, sizeof (*th));
+ th = xcalloc (1, sizeof (*th));
th->tid = tid;
th->h = h;