From patchwork Thu Apr 17 12:05:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 605 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx23.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 85CF036007E for ; Thu, 17 Apr 2014 05:06:06 -0700 (PDT) Received: by homiemail-mx23.g.dreamhost.com (Postfix, from userid 14314964) id 274B062920875; Thu, 17 Apr 2014 05:06:05 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx23.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx23.g.dreamhost.com (Postfix) with ESMTPS id 9A0DB629AA5A3 for ; Thu, 17 Apr 2014 05:06:05 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-type; q=dns; s=default; b=eFsSpzqBLOfsf6PO 0e0tiiOzMQCeAMhMnlskk+W6i4YIEZssonS0yRe+OolJmr1JrcTluf3M0zLnsqvU ZKdiBRYjLAFPiD84C4V23NhJASxJN3jE9/lrSkHgGzYwcDMkT8yKjFMlgBVxoQij MhyruXBkPYI6AQQ7cH0LzfXayK4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-type; s=default; bh=/PLeTR9jtEeZufwUgcKiU7 fT/zE=; b=W5O7WYkylOXUGnlaMYFdDvfvTX1avNybJz0o7UgbqVvVqdLkL9xHQh mt79DOF9rA7uyVjwzSh/K7ya0y6ksib7/eB6ZFKyRnCCCKBHUlq4RlkXhjFWuo58 B98Mna1oqJ9LqDv6X8bF5gNoxW6biMrtblaNjzK30bq5ZaLmwrL0I= Received: (qmail 29912 invoked by alias); 17 Apr 2014 12:05:59 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 29765 invoked by uid 89); 17 Apr 2014 12:05:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-gw1-out.broadcom.com Received: from mail-gw1-out.broadcom.com (HELO mail-gw1-out.broadcom.com) (216.31.210.62) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 17 Apr 2014 12:05:56 +0000 Received: from irvexchcas07.broadcom.com (HELO IRVEXCHCAS07.corp.ad.broadcom.com) ([10.9.208.55]) by mail-gw1-out.broadcom.com with ESMTP; 17 Apr 2014 06:09:58 -0700 Received: from IRVEXCHSMTP3.corp.ad.broadcom.com (10.9.207.53) by IRVEXCHCAS07.corp.ad.broadcom.com (10.9.208.55) with Microsoft SMTP Server (TLS) id 14.3.174.1; Thu, 17 Apr 2014 05:05:55 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP3.corp.ad.broadcom.com (10.9.207.53) with Microsoft SMTP Server id 14.3.174.1; Thu, 17 Apr 2014 05:05:55 -0700 Received: from xl-cam-21.broadcom.com (xl-cam-21.cam.broadcom.com [10.177.132.81]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 1E99DEAD4D; Thu, 17 Apr 2014 05:05:55 -0700 (PDT) Received: by xl-cam-21.broadcom.com (Postfix, from userid 15136) id 712DC2CE899D; Thu, 17 Apr 2014 13:05:54 +0100 (BST) From: Andrew Burgess To: CC: Andrew Burgess Subject: [PATCH] Improve MI -var-info-path-expression for nested struct/union case. Date: Thu, 17 Apr 2014 13:05:51 +0100 Message-ID: <1397736351-20306-1-git-send-email-aburgess@broadcom.com> MIME-Version: 1.0 X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in The MI command -var-info-path-expression currently does not handle some cases of nested structures / unions correctly, consider the following source file: int main ( void ) { struct a_t { int var; }; struct s_t { struct a_t a; }; struct s_t s; return 0; /* Break Here (line 16) */ } And this gdb session: (gdb) break 16 Breakpoint 1 at 0x400550: file nested.c, line 16. (gdb) run Starting program: /projects/firepath_work/aburgess/tmp/nested.x Can't read symbols from system-supplied DSO at 0x2aaaaaaab000: File truncated Breakpoint 1, main () at nested.c:16 16 return 0; /* Break Here (line 16) */ (gdb) interpreter-exec mi "-var-create var1 @ s" ^done,name="var1",numchild="1",value="{...}",type="struct s_t",thread-id="1",has_more="0" (gdb) interpreter-exec mi "-var-list-children var1" ^done,numchild="1",children=[child={name="var1.a",exp="a",numchild="1",type="struct a_t",thread-id="1"}],has_more="0" (gdb) interpreter-exec mi "-var-list-children var1.a" ^done,numchild="1",children=[child={name="var1.a.var",exp="var",numchild="0",type="int",thread-id="1"}],has_more="0" (gdb) interpreter-exec mi "-var-info-path-expression var1.a.var" ^done,path_expr="(s).var" (gdb) interpreter-exec mi "-data-evaluate-expression (s).var" ^error,msg="There is no member named var." Notice that the result of the -var-info-path-expression is wrong, and, not surprisingly causes and error when passed into -data-evaluate-expression. With this patch the result is instead this: (gdb) interpreter-exec mi "-var-info-path-expression var1.a.var" ^done,path_expr="((s).a).var" (gdb) interpreter-exec mi "-data-evaluate-expression ((s).a).var" ^done,value="-8320" The changes to varobj.c feel like it might be possible to simplify them, but I can't figure out how, any change I make seems to regress something, so for now I'm proposing this patch. The change is very contained anyway, so if someone can improve it later it's not going to cause any disruption. OK to apply? Thanks, Andrew gdb/ChangeLog: * varobj.c (is_path_expr_parent): Improve test for anonymous structures and unions. gdb/testsuite/ChangeLog: * gdb.mi/var-cmd.c (do_nested_struct_union_tests): New function setting up test structures. (main): Call new test function. * gdb.mi/mi2-var-child.exp: Create additional breakpoint in new test function, continue into test function and walk test structures. --- gdb/testsuite/gdb.mi/mi2-var-child.exp | 61 +++++++++++++++++++++++++++++++ gdb/testsuite/gdb.mi/var-cmd.c | 65 ++++++++++++++++++++++++++++++++++ gdb/varobj.c | 30 +++++++++++++--- 3 files changed, 152 insertions(+), 4 deletions(-) diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp index d2f65c5..d9f5991 100644 --- a/gdb/testsuite/gdb.mi/mi2-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp @@ -1162,6 +1162,10 @@ set lineno [gdb_get_line_number "anonymous type tests breakpoint"] mi_create_breakpoint \ "$srcfile:$lineno" {[0-9]+} keep {do_anonymous_type_tests} \ ".*var-cmd.c" $lineno $hex "break in do_anonymous_type_tests" +set lineno [gdb_get_line_number "nested struct union tests breakpoint"] +mi_create_breakpoint \ + "$srcfile:$lineno" {[0-9]+} keep {do_nested_struct_union_tests} \ + ".*var-cmd.c" $lineno $hex "break in do_nested_struct_union_tests" mi_execute_to "exec-continue" "breakpoint-hit" "do_anonymous_type_tests" ""\ ".*" ".*" {"" "disp=\"keep\""} \ "continue to do_anonymous_type_tests breakpoint" @@ -1235,5 +1239,62 @@ set tree { mi_walk_varobj_tree c $tree verify_everything +mi_send_resuming_command "exec-continue" \ + "continuing execution to enter do_nested_struct_union_tests" +mi_expect_stop "breakpoint-hit" "do_nested_struct_union_tests" ".*" ".*" ".*" \ + {.* disp="keep"} "Run till MI stops in do_nested_struct_union_tests" + +set tree { + {struct ss} var { + {struct s_a} a1 { + int a {} + } + {struct s_b} b1 { + int b {} + } + {union u_ab} u1 { + {struct s_a} a { + int a {} + } + {struct s_b} b { + int b {} + } + } + anonymous union { + {struct s_a} a2 { + int a {} + } + {struct s_b} b2 { + int b {} + } + } + {union {...}} u2 { + {struct s_a} a3 { + int a {} + } + {struct s_b} b3 { + int b {} + } + } + } +} + +mi_walk_varobj_tree c $tree verify_everything + +set tree { + {struct {...}} var2 { + {td_u_ab} ab { + {td_s_a} a { + int a {} + } + {td_s_b} b { + int b {} + } + } + } +} + +mi_walk_varobj_tree c $tree verify_everything + mi_gdb_exit return 0 diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c index 698b294..c519aa1 100644 --- a/gdb/testsuite/gdb.mi/var-cmd.c +++ b/gdb/testsuite/gdb.mi/var-cmd.c @@ -552,6 +552,70 @@ do_anonymous_type_tests (void) return; /* anonymous type tests breakpoint */ } +void +do_nested_struct_union_tests (void) +{ + struct s_a + { + int a; + }; + struct s_b + { + int b; + }; + union u_ab + { + struct s_a a; + struct s_b b; + }; + struct ss + { + struct s_a a1; + struct s_b b1; + union u_ab u1; + + /* Anonymous union. */ + union + { + struct s_a a2; + struct s_b b2; + }; + + union + { + struct s_a a3; + struct s_b b3; + } u2; + }; + + typedef struct + { + int a; + } td_s_a; + + typedef struct + { + int b; + } td_s_b; + + typedef union + { + td_s_a a; + td_s_b b; + } td_u_ab; + + struct ss var; + struct + { + td_u_ab ab; + } var2; + + memset (&var, 0, sizeof (var)); + memset (&var2, 0, sizeof (var2)); + + return; /* nested struct union tests breakpoint */ +} + int main (int argc, char *argv []) { @@ -563,6 +627,7 @@ main (int argc, char *argv []) do_at_tests (); do_bitfield_tests (); do_anonymous_type_tests (); + do_nested_struct_union_tests (); exit (0); } diff --git a/gdb/varobj.c b/gdb/varobj.c index 10ef5b7..33083b2 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1075,12 +1075,34 @@ is_path_expr_parent (struct varobj *var) if (CPLUS_FAKE_CHILD (var)) return 0; - type = varobj_get_value_type (var); + type = varobj_get_gdb_type (var); /* Anonymous unions and structs are also not path_expr parents. */ - return !((TYPE_CODE (type) == TYPE_CODE_STRUCT - || TYPE_CODE (type) == TYPE_CODE_UNION) - && TYPE_NAME (type) == NULL); + if ((TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION) + && TYPE_NAME (type) == NULL + && TYPE_TAG_NAME (type) == NULL) + { + if (var->parent != NULL) + { + const struct type *parent_type; + + parent_type = varobj_get_gdb_type (var->parent); + if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT + || TYPE_CODE (parent_type) == TYPE_CODE_UNION) + { + const char *field_name; + + gdb_assert (var->index < TYPE_NFIELDS (parent_type)); + field_name = TYPE_FIELD_NAME (parent_type, var->index); + return !(field_name == NULL || *field_name == '\0'); + } + } + + return 0; + } + + return 1; } /* Return the path expression parent for VAR. */