From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18751 invoked by alias); 3 May 2008 20:19:49 -0000 Received: (qmail 18743 invoked by uid 22791); 3 May 2008 20:19:48 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 03 May 2008 20:19:31 +0000 Received: (qmail 1771 invoked from network); 3 May 2008 20:19:29 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 3 May 2008 20:19:29 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: expressions with C preprocessor macro info Date: Sat, 03 May 2008 20:38:00 -0000 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_PjMHIIuBkFpeBL6" Message-Id: <200805032119.27919.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-05/txt/msg00138.txt.bz2 --Boundary-00=_PjMHIIuBkFpeBL6 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Content-length: 2037 Hi, I noticed while doing something else in parse.c, something suspicous. It happens that after preprocessor macros support went in, parse.c:parse_exp_in_context got changed in a form that introduced a bug here: static struct expression * parse_exp_in_context (char **stringptr, struct block *block, int comma,=20 int void_context_p) { ... if (!block) block =3D get_selected_block (&expression_context_pc); ^^^ if this returns a block, expression_context_pc contains an accurate pc. /* Fall back to using the current source static context, if any. */ if (!block) { struct symtab_and_line cursal =3D get_current_source_symtab_and_line = (); if (cursal.symtab) block =3D BLOCKVECTOR_BLOCK (BLOCKVECTOR (cursal.symtab), STATIC_BLOCK); } /* Save the context, if specified by caller, or found above. */ if (block) { expression_context_block =3D block; expression_context_pc =3D BLOCK_START (block); ^^^ but here we're always overriding it with BLOCK_START. } Talking about this with Jim Blandy, he explained it like so: "We want the exact PC because macros are scoped from one line to the next, not by block. =C2=A0For example, we could have: =C2=A0 =C2=A0 { =C2=A0 =C2=A0 =C2=A0 int foo; =C2=A0 =C2=A0 =C2=A0 f (); #define M slurgh; =C2=A0 =C2=A0 =C2=A0 g (); #undef M =C2=A0 =C2=A0 =C2=A0 h (); =C2=A0 =C2=A0 } In this case, there will be only one lexical block covering the declaration of foo and all three statements, but we'd like to see the definition of M when we're stopped at the call to g, and not when we're stopped at the calls to f or h. =C2=A0So we need to take a PC, find the source line and file, and then use that to decide whether any given macro is in scope." Currently, "print M" when stopped at the g (); call above prints: (gdb) print M No symbol "M" in current context. The attached patch fixes the issue, and adds a test to ensure we don't regress again. Tested on x86_64-unknown-linux-pc. OK? --=20 Pedro Alves --Boundary-00=_PjMHIIuBkFpeBL6 Content-Type: text/x-diff; charset="utf-8"; name="expression_context_pc.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="expression_context_pc.diff" Content-length: 3918 2008-05-03 Pedro Alves gdb/ * parse.c (parse_exp_in_context): Don't override expression_context_pc if get_selected_block returned a valid block. gdb/testsuite/ * gdb.base/macscp.exp, gdb.base/macscp1.c: Add test for printing expressions with macros. --- gdb/parse.c | 26 ++++++++++++-------------- gdb/testsuite/gdb.base/macscp.exp | 23 +++++++++++++++++++++++ gdb/testsuite/gdb.base/macscp1.c | 13 +++++++++++++ 3 files changed, 48 insertions(+), 14 deletions(-) Index: src/gdb/parse.c =================================================================== --- src.orig/gdb/parse.c 2008-05-03 20:32:38.000000000 +0100 +++ src/gdb/parse.c 2008-05-03 20:43:01.000000000 +0100 @@ -961,26 +961,24 @@ parse_exp_in_context (char **stringptr, old_chain = make_cleanup (free_funcalls, 0 /*ignore*/); funcall_chain = 0; - /* If no context specified, try using the current frame, if any. */ + expression_context_block = block; - if (!block) - block = get_selected_block (&expression_context_pc); + /* If no context specified, try using the current frame, if any. */ + if (!expression_context_block) + expression_context_block = get_selected_block (&expression_context_pc); + else + expression_context_pc = BLOCK_START (expression_context_block); - /* Fall back to using the current source static context, if any. */ + /* Fall back to using the current source static context, if any. */ - if (!block) + if (!expression_context_block) { struct symtab_and_line cursal = get_current_source_symtab_and_line (); if (cursal.symtab) - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (cursal.symtab), STATIC_BLOCK); - } - - /* Save the context, if specified by caller, or found above. */ - - if (block) - { - expression_context_block = block; - expression_context_pc = BLOCK_START (block); + expression_context_block + = BLOCKVECTOR_BLOCK (BLOCKVECTOR (cursal.symtab), STATIC_BLOCK); + if (expression_context_block) + expression_context_pc = BLOCK_START (expression_context_block); } expout_size = 10; Index: src/gdb/testsuite/gdb.base/macscp.exp =================================================================== --- src.orig/gdb/testsuite/gdb.base/macscp.exp 2008-05-03 20:32:39.000000000 +0100 +++ src/gdb/testsuite/gdb.base/macscp.exp 2008-05-03 20:37:56.000000000 +0100 @@ -24,6 +24,7 @@ if $tracelevel then { set prms_id 0 set bug_id 0 +set srcfile macscp1.c set testfile "macscp" set binfile ${objdir}/${subdir}/${testfile} @@ -405,3 +406,25 @@ for {set i 0} {$i < [llength $funcs]} {i } } } + +gdb_test "break [gdb_get_line_number "set breakpoint here"]" \ + "Breakpoint.*at.* file .*, line.*" \ + "breakpoint macscp_expr" + +gdb_test "continue" "foo = 0;.*" "continue to macsp_expr" + +gdb_test "print M" \ + "No symbol \"M\" in current context\." \ + "print expression with macro before define." + +gdb_test "next" "foo = 1;" "next to definition" + +gdb_test "print M" \ + " = 0" \ + "print expression with macro in scope." + +gdb_test "next" "foo = 2;" "next to definition" + +gdb_test "print M" \ + "No symbol \"M\" in current context\." \ + "print expression with macro after undef." Index: src/gdb/testsuite/gdb.base/macscp1.c =================================================================== --- src.orig/gdb/testsuite/gdb.base/macscp1.c 2008-05-03 20:32:39.000000000 +0100 +++ src/gdb/testsuite/gdb.base/macscp1.c 2008-05-03 20:37:56.000000000 +0100 @@ -63,6 +63,18 @@ macscp1_3 () puts ("macscp1_3"); } +void +macscp_expr (void) +{ + int foo = -1; + + foo = 0; /* set breakpoint here */ +#define M foo + foo = 1; +#undef M + foo = 2; +} + int main (int argc, char **argv) { @@ -77,4 +89,5 @@ main (int argc, char **argv) macscp4_2_from_macscp3 (); macscp3_2 (); macscp1_3 (); + macscp_expr (); } --Boundary-00=_PjMHIIuBkFpeBL6--