From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22606 invoked by alias); 18 Aug 2010 18:59:54 -0000 Received: (qmail 22591 invoked by uid 22791); 18 Aug 2010 18:59:51 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_VP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 18 Aug 2010 18:59:45 +0000 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o7IIxh7P016655 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 18 Aug 2010 14:59:43 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7IIxhs3005143; Wed, 18 Aug 2010 14:59:43 -0400 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o7IIxgVh010979; Wed, 18 Aug 2010 14:59:42 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 17D34378196; Wed, 18 Aug 2010 12:59:41 -0600 (MDT) From: Tom Tromey To: gdb-patches@sourceware.org Subject: FYI: fix PR 11919 Date: Wed, 18 Aug 2010 18:59:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii 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: 2010-08/txt/msg00313.txt.bz2 I am checking this in. This patch fixes PR 11919. That bug concerns an error case in the field name completion code: (gdb) p gdb_stdin.x.Type struct ui_file has no component named x. The fix is to catch exceptions from parse_field_expression and just return NULL from the completer in this case. This patch also fixes a latent memory leak in parse_field_expression, and cleans up the error reporting code in lookup_struct_elt_type. Built and regtested on x86-64 (compile farm). Tom 2010-08-18 Tom Tromey PR symtab/11919: * gdbtypes.c (lookup_struct_elt_type): Clean up error emission. * parse.c (parse_field_expression): Use RETURN_MASK_ERROR. Move name-copying lower. Document exception behavior. * completer.c (expression_completer): Catch exceptions from parse_field_expression. 2010-08-18 Tom Tromey PR symtab/11919: * gdb.base/completion.exp: Add test. Index: completer.c =================================================================== RCS file: /cvs/src/src/gdb/completer.c,v retrieving revision 1.39 diff -u -r1.39 completer.c --- completer.c 13 May 2010 23:53:32 -0000 1.39 +++ completer.c 18 Aug 2010 18:33:05 -0000 @@ -24,6 +24,7 @@ #include "filenames.h" /* For DOSish file names. */ #include "language.h" #include "gdb_assert.h" +#include "exceptions.h" #include "cli/cli-decode.h" @@ -414,13 +415,19 @@ char ** expression_completer (struct cmd_list_element *ignore, char *text, char *word) { - struct type *type; + struct type *type = NULL; char *fieldname, *p; + volatile struct gdb_exception except; /* Perform a tentative parse of the expression, to see whether a field completion is required. */ fieldname = NULL; - type = parse_field_expression (text, &fieldname); + TRY_CATCH (except, RETURN_MASK_ERROR) + { + type = parse_field_expression (text, &fieldname); + } + if (except.reason < 0) + return NULL; if (fieldname && type) { for (;;) Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.196 diff -u -r1.196 gdbtypes.c --- gdbtypes.c 28 Jul 2010 16:23:58 -0000 1.196 +++ gdbtypes.c 18 Aug 2010 18:33:07 -0000 @@ -1212,6 +1212,7 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) { int i; + char *typename; for (;;) { @@ -1225,11 +1226,9 @@ if (TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION) { - target_terminal_ours (); - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "Type "); - type_print (type, "", gdb_stderr, -1); - error (_(" is not a structure or union type.")); + typename = type_to_string (type); + make_cleanup (xfree, typename); + error (_("Type %s is not a structure or union type."), typename); } #if 0 @@ -1281,14 +1280,9 @@ return NULL; } - target_terminal_ours (); - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "Type "); - type_print (type, "", gdb_stderr, -1); - fprintf_unfiltered (gdb_stderr, " has no component named "); - fputs_filtered (name, gdb_stderr); - error ((".")); - return (struct type *) -1; /* For lint */ + typename = type_to_string (type); + make_cleanup (xfree, typename); + error (_("Type %s has no component named %s."), typename, name); } /* Lookup the vptr basetype/fieldno values for TYPE. Index: parse.c =================================================================== RCS file: /cvs/src/src/gdb/parse.c,v retrieving revision 1.102 diff -u -r1.102 parse.c --- parse.c 4 Jun 2010 21:39:47 -0000 1.102 +++ parse.c 18 Aug 2010 18:33:07 -0000 @@ -1202,8 +1202,10 @@ /* Parse STRING as an expression. If parsing ends in the middle of a field reference, return the type of the left-hand-side of the reference; furthermore, if the parsing ends in the field name, - return the field name in *NAME. In all other cases, return NULL. - Returned non-NULL *NAME must be freed by the caller. */ + return the field name in *NAME. If the parsing ends in the middle + of a field reference, but the reference is somehow invalid, throw + an exception. In all other cases, return NULL. Returned non-NULL + *NAME must be freed by the caller. */ struct type * parse_field_expression (char *string, char **name) @@ -1213,7 +1215,7 @@ int subexp; volatile struct gdb_exception except; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY_CATCH (except, RETURN_MASK_ERROR) { in_parse_field = 1; exp = parse_exp_in_context (&string, 0, 0, 0, &subexp); @@ -1233,10 +1235,12 @@ xfree (exp); return NULL; } - /* (*NAME) is a part of the EXP memory block freed below. */ - *name = xstrdup (*name); + /* This might throw an exception. If so, we want to let it + propagate. */ val = evaluate_subexpression_type (exp, subexp); + /* (*NAME) is a part of the EXP memory block freed below. */ + *name = xstrdup (*name); xfree (exp); return value_type (val); Index: testsuite/gdb.base/completion.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/completion.exp,v retrieving revision 1.46 diff -u -r1.46 completion.exp --- testsuite/gdb.base/completion.exp 5 May 2010 18:06:57 -0000 1.46 +++ testsuite/gdb.base/completion.exp 18 Aug 2010 18:33:14 -0000 @@ -827,23 +827,8 @@ timeout { fail "(timeout) complete 'set follow-fork-mode'" } } -send_gdb "p values\[0\].nonex.\t" -gdb_expect { - -re "Type struct some_struct has no component named nonex.\r\n$gdb_prompt $"\ - { pass "Completing non-existing component" } - -re ".*$gdb_prompt $" { fail "Completing non-existing component" } - timeout { fail "(timeout) Completing non-existing component" } - eof { fail "(eof) Completing non-existing component #2" } - } -# Double memory freeing gets found only on the second run: -send_gdb "p values\[0\].nonex.\t" -gdb_expect { - -re "Type struct some_struct has no component named nonex.\r\n$gdb_prompt $"\ - { pass "Completing non-existing component #2" } - -re ".*$gdb_prompt $" { fail "Completing non-existing component #2" } - timeout { fail "(timeout) Completing non-existing component #2" } - eof { fail "(eof) Completing non-existing component #2" } - } +gdb_test_no_output "complete print values\[0\].x." \ + "field completion with invalid field" # If there is a non-deprecated completion, it should be returned. gdb_test "complete sav" "save" "test non-deprecated completion"