From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11977 invoked by alias); 12 Apr 2002 23:18:25 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 11970 invoked from network); 12 Apr 2002 23:18:24 -0000 Received: from unknown (HELO mx04.nexgo.de) (151.189.8.80) by sources.redhat.com with SMTP; 12 Apr 2002 23:18:24 -0000 Received: from einstein.home-of-linux.org (dialin-212-144-185-197.arcor-ip.net [212.144.185.197]) by mx04.nexgo.de (Postfix) with ESMTP id C4FB037C0E for ; Sat, 13 Apr 2002 01:18:10 +0200 (CEST) Received: by einstein.home-of-linux.org (Postfix, from userid 1001) id 1DF6C20022; Fri, 12 Apr 2002 22:19:50 +0200 (CEST) To: gdb@sources.redhat.com Subject: Lifetime of local variables From: Martin Baulig Date: Fri, 12 Apr 2002 16:18:00 -0000 Message-ID: <86u1qghdp5.fsf@einstein.home-of-linux.org> User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-SW-Source: 2002-04/txt/msg00222.txt.bz2 --=-=-= Content-length: 1247 Hi, I was recently working a bit on debugging support for C# (using Mono) and I need a way to tell GDB about the lifetime of local variables. In C#, the JIT engine may decide to store two different variables at the same stack offset if they aren't used throughout the whole function. Now I was wondering how to do this - DWARF 2 already has a `DW_AT_begin_scope' but unfortunately no `DW_AT_end_scope' - can we add this or something similar as a GNU extension ? After looking at the code, I found out that `struct symbol' contains a `ranges' field which seems to do exactly what I want - but this field isn't used anywhere. The following patch * adds a new DWARF 2 attribute DW_AT_end_scope to specify the end of a local variable's scope. * initializes SYMBOL_RANGES() in dwarf2read.c if DW_AT_begin_scope and DW_AT_end_scope are specified. [FIXME: According to the DWARF 2 specification, this attribute takes an offset (DW_FROM_data), not an address - but I found now way to get the current frame's address in new_symbol(), this needs to be fixed.] * checks whether the current PC is within the symbol's SYMBOL_RANGES() when listing the local variables of a function and when printing a variable. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=gdb-variable-scopes.patch Content-length: 5169 Index: include/elf/ChangeLog =================================================================== RCS file: /cvs/src/src/include/elf/ChangeLog,v retrieving revision 1.121 diff -u -u -p -r1.121 ChangeLog --- include/elf/ChangeLog 13 Feb 2002 18:14:48 -0000 1.121 +++ include/elf/ChangeLog 12 Apr 2002 19:50:31 -0000 @@ -1,3 +1,7 @@ +2002-04-12 Martin Baulig + + * dwarf2.h (DW_AT_end_scope): Added as GNU extension. + 2002-02-13 Matt Fredette * m68k.h (EF_M68000): Define. Index: include/elf/dwarf2.h =================================================================== RCS file: /cvs/src/src/include/elf/dwarf2.h,v retrieving revision 1.8 diff -u -u -p -r1.8 dwarf2.h --- include/elf/dwarf2.h 28 Jan 2002 23:26:53 -0000 1.8 +++ include/elf/dwarf2.h 12 Apr 2002 19:50:32 -0000 @@ -328,6 +328,8 @@ enum dwarf_attribute DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, + DW_AT_end_scope = 0x2121, + /* VMS Extensions. */ DW_AT_VMS_rtnbeg_pd_address = 0x2201 }; Index: gdb/ChangeLog =================================================================== RCS file: /cvs/src/src/gdb/ChangeLog,v retrieving revision 1.2421 diff -u -u -p -r1.2421 ChangeLog --- gdb/ChangeLog 12 Apr 2002 07:37:17 -0000 1.2421 +++ gdb/ChangeLog 12 Apr 2002 19:50:38 -0000 @@ -1,3 +1,14 @@ +2002-04-12 Martin Baulig + + * dwarf2read.c (new_symbol): If DW_AT_start_scope and DW_AT_end_scope + are specified, set SYMBOL_RANGES(). + + * findvar.c (read_var_value): Check whether the current PC is within + the SYMBOL_RANGES(), return NULL if not. + + * stack.c (print_block_frame_locals): Only print vars if the current PC + is in their SYMBOL_RANGES(). + 2002-04-12 Kevin Buettner From Jimi X : Index: gdb/dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.52 diff -u -u -p -r1.52 dwarf2read.c --- gdb/dwarf2read.c 4 Apr 2002 22:26:43 -0000 1.52 +++ gdb/dwarf2read.c 12 Apr 2002 19:50:44 -0000 @@ -4394,6 +4394,19 @@ new_symbol (struct die_info *die, struct add_symbol_to_list (sym, list_in_scope); break; } + attr = dwarf_attr (die, DW_AT_start_scope); + attr2 = dwarf_attr (die, DW_AT_end_scope); + if (attr && attr2) + { + struct range_list *r = (struct range_list *) + obstack_alloc (&objfile->type_obstack, + sizeof (struct range_list)); + + r->start = DW_ADDR (attr); + r->end = DW_ADDR (attr2); + + SYMBOL_RANGES (sym) = r; + } attr = dwarf_attr (die, DW_AT_location); if (attr) { Index: gdb/findvar.c =================================================================== RCS file: /cvs/src/src/gdb/findvar.c,v retrieving revision 1.31 diff -u -u -p -r1.31 findvar.c --- gdb/findvar.c 9 Apr 2002 03:06:13 -0000 1.31 +++ gdb/findvar.c 12 Apr 2002 19:50:45 -0000 @@ -417,9 +417,11 @@ struct value * read_var_value (register struct symbol *var, struct frame_info *frame) { register struct value *v; + register struct range_list *r; struct type *type = SYMBOL_TYPE (var); CORE_ADDR addr; register int len; + int range_ok = 0; v = allocate_value (type); VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ @@ -429,6 +431,23 @@ read_var_value (register struct symbol * if (frame == NULL) frame = selected_frame; + + if (!SYMBOL_RANGES (var)) + range_ok = 1; + else + { + for (r = SYMBOL_RANGES (var); r; r = r->next) + { + if (r->start <= frame->pc && r->end > frame->pc) + { + range_ok = 1; + break; + } + } + } + + if (!range_ok) + return NULL; switch (SYMBOL_CLASS (var)) { Index: gdb/stack.c =================================================================== RCS file: /cvs/src/src/gdb/stack.c,v retrieving revision 1.33 diff -u -u -p -r1.33 stack.c --- gdb/stack.c 10 Apr 2002 23:32:33 -0000 1.33 +++ gdb/stack.c 12 Apr 2002 19:50:47 -0000 @@ -1173,14 +1173,36 @@ print_block_frame_locals (struct block * case LOC_REGISTER: case LOC_STATIC: case LOC_BASEREG: - values_printed = 1; - for (j = 0; j < num_tabs; j++) - fputs_filtered ("\t", stream); - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); - fputs_filtered (" = ", stream); - print_variable_value (sym, fi, stream); - fprintf_filtered (stream, "\n"); - break; + { + struct range_list *r; + int range_ok = 0; + + if (!SYMBOL_RANGES (sym)) + range_ok = 1; + else + { + for (r = SYMBOL_RANGES (sym); r; r = r->next) + { + if (r->start <= fi->pc && r->end > fi->pc) + { + range_ok = 1; + break; + } + } + } + + if (range_ok) + { + values_printed = 1; + for (j = 0; j < num_tabs; j++) + fputs_filtered ("\t", stream); + fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); + fputs_filtered (" = ", stream); + print_variable_value (sym, fi, stream); + fprintf_filtered (stream, "\n"); + } + break; + } default: /* Ignore symbols which are not locals. */ --=-=-= Content-length: 37 -- Martin Baulig martin@gnome.org --=-=-=--