diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 2001-10-02 10:18:40 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2001-10-02 10:18:40 -0400 |
commit | 38cbfe40a046b12a3d9bc56e6cf76d86c458ef39 (patch) | |
tree | 6570bc15069492ca4f53a85c5d09a36d099fd63f /gcc/ada/gmem.c | |
parent | 70482933d8f6a73b660f4cfa97b5c7c9deaf152e (diff) | |
download | gcc-38cbfe40a046b12a3d9bc56e6cf76d86c458ef39.zip gcc-38cbfe40a046b12a3d9bc56e6cf76d86c458ef39.tar.gz gcc-38cbfe40a046b12a3d9bc56e6cf76d86c458ef39.tar.bz2 |
New Language: Ada
From-SVN: r45955
Diffstat (limited to 'gcc/ada/gmem.c')
-rw-r--r-- | gcc/ada/gmem.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/gcc/ada/gmem.c b/gcc/ada/gmem.c new file mode 100644 index 0000000..31e4b84 --- /dev/null +++ b/gcc/ada/gmem.c @@ -0,0 +1,216 @@ +/**************************************************************************** + * * + * GNATMEM COMPONENTS * + * * + * G M E M * + * * + * $Revision: 1.1 $ + * * + * C Implementation File * + * * + * Copyright (C) 2000-2001 Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 2, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * + * for more details. You should have received a copy of the GNU General * + * Public License distributed with GNAT; see file COPYING. If not, write * + * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + * * + * As a special exception, if you link this file with other files to * + * produce an executable, this file does not by itself cause the resulting * + * executable to be covered by the GNU General Public License. This except- * + * ion does not however invalidate any other reasons why the executable * + * file might be covered by the GNU Public License. * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). * + * * + ****************************************************************************/ + +/* This unit reads the allocation tracking log produced by augmented + __gnat_malloc and __gnat_free procedures (see file a-raise.c) and + provides GNATMEM tool with gdb-compliant output. The output is + processed by GNATMEM to detect dynamic memory allocation errors. + + See GNATMEM section in GNAT User's Guide for more information. + + NOTE: This capability is currently supported on the following targets: + + DEC Unix + SGI Irix + Linux x86 + Solaris (sparc and x86) (*) + Windows 98/95/NT (x86) + + (*) on these targets, the compilation must be done with -funwind-tables to + be able to build the stack backtrace. */ + +#ifdef __alpha_vxworks +#include "vxWorks.h" +#endif + +#ifdef IN_RTS +#include "tconfig.h" +#include "tsystem.h" +#else +#include "config.h" +#include "system.h" +#endif + +#include "adaint.h" + +static FILE *gmemfile; + +/* tb_len is the number of call level supported by this module */ +#define TB_LEN 200 + +static char *tracebk [TB_LEN]; +static int cur_tb_len, cur_tb_pos; + +extern void convert_addresses PARAMS ((char *[], int, void *, + int *)); +static void gmem_read_backtrace PARAMS ((void)); +static char *spc2nul PARAMS ((char *)); + +extern int __gnat_gmem_initialize PARAMS ((char *)); +extern void __gnat_gmem_a2l_initialize PARAMS ((char *)); +extern void __gnat_gmem_read_next PARAMS ((char *)); +extern void __gnat_gmem_read_bt_frame PARAMS ((char *)); + +/* Reads backtrace information from gmemfile placing them in tracebk + array. cur_tb_len is the size of this array. */ + +static void +gmem_read_backtrace () +{ + fread (&cur_tb_len, sizeof (int), 1, gmemfile); + fread (tracebk, sizeof (char *), cur_tb_len, gmemfile); + cur_tb_pos = 0; +} + +/* Initialize gmem feature from the dumpname file. Return 1 if the + dumpname has been generated by GMEM (instrumented malloc/free) and 0 if not + (i.e. probably a GDB generated file). */ + +int +__gnat_gmem_initialize (dumpname) + char *dumpname; +{ + char header[10]; + + gmemfile = fopen (dumpname, "rb"); + fread (header, 10, 1, gmemfile); + + /* Check for GMEM magic-tag. */ + if (memcmp (header, "GMEM DUMP\n", 10)) + { + fclose (gmemfile); + return 0; + } + + return 1; +} + +/* Initialize addr2line library */ + +void +__gnat_gmem_a2l_initialize (exename) + char *exename; +{ + extern char **gnat_argv; + char s [100]; + int l; + + gnat_argv [0] = exename; + convert_addresses (tracebk, 1, s, &l); +} + +/* Read next allocation of deallocation information from the GMEM file and + write an alloc/free information in buf to be processed by GDB (see gnatmem + implementation). */ + +void +__gnat_gmem_read_next (buf) + char *buf; +{ + void *addr; + int size; + char c; + + if ((c = fgetc (gmemfile)) == EOF) + { + fclose (gmemfile); + sprintf (buf, "Program exited."); + } + else + { + switch (c) + { + case 'A' : + fread (&addr, sizeof (char *), 1, gmemfile); + fread (&size, sizeof (int), 1, gmemfile); + sprintf (buf, "ALLOC^%d^0x%lx^", size, (long) addr); + break; + case 'D' : + fread (&addr, sizeof (char *), 1, gmemfile); + sprintf (buf, "DEALL^0x%lx^", (long) addr); + break; + default: + puts ("GMEM dump file corrupt"); + __gnat_os_exit (1); + } + + gmem_read_backtrace (); + } +} + +/* Scans the line until the space or new-line character is encountered; + this character is replaced by nul and its position is returned. */ + +static char * +spc2nul (s) + char *s; +{ + while (*++s) + if (*s == ' ' || *s == '\n') + { + *s = 0; + return s; + } + + abort (); +} + +/* Convert backtrace address in tracebk at position cur_tb_pos to a symbolic + traceback information returned in buf and to be processed by GDB (see + gnatmem implementation). */ + +void +__gnat_gmem_read_bt_frame (buf) + char *buf; +{ + int l = 0; + char s[1000]; + char *name, *file; + + if (cur_tb_pos >= cur_tb_len) + { + buf [0] = ' '; + buf [1] = '\0'; + return; + } + + convert_addresses (tracebk + cur_tb_pos, 1, s, &l); + s[l] = '\0'; + name = spc2nul (s) + 4; + file = spc2nul (name) + 4; + spc2nul (file); + ++cur_tb_pos; + + sprintf (buf, "# %s () at %s", name, file); +} |