From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30458 invoked by alias); 30 Sep 2008 20:53:14 -0000 Received: (qmail 30448 invoked by uid 22791); 30 Sep 2008 20:53:13 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 30 Sep 2008 20:52:38 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 58BF42A967C for ; Tue, 30 Sep 2008 16:52:36 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id ADqWy2Jh01lY for ; Tue, 30 Sep 2008 16:52:36 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id E7C842A966F for ; Tue, 30 Sep 2008 16:52:35 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 07BE7E7ACD; Tue, 30 Sep 2008 13:52:33 -0700 (PDT) Date: Tue, 30 Sep 2008 20:53:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [commit/Ada] Special handling for predefined exceptions... Message-ID: <20080930205233.GA3560@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="MGYHOYXEY6WxJCY8" Content-Disposition: inline User-Agent: Mutt/1.4.2.2i 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-09/txt/msg00591.txt.bz2 --MGYHOYXEY6WxJCY8 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2335 Hello, For Ada, we provide a command "catch exception [EXCEPTION_NAME]" that stops the execution when an exception is raised. If an exception name is specified in the command, then the debugger only stops when a specific exception is raised. The matching of the exception is performed through an internal condition that looks like this: long_integer (e) = long_integer (&EXCEPTION_NAME)" (where "e" is a parameter of the function where we inserted the catchpoint that contains a pointer to the exception data). The way it works is: For every EXCEPTION_NAME, the compiler defines an entity whose name is EXCEPTION_NAME (fully qualified). So when we want to verify whether we have raised a given exception, we just verify that its address is the address of the symbol whose name is EXCEPTION_NAME. Ada defines some standard exception names such as Constraint_Error (used when using a value that's out of bounds, for instance), Program_Error, Tasking_Error, etc. With GNAT, these exceptions are defined inside runtime units which are not compiled with debugging info. The situation that we ran into was a situation where the user defined several enumerates whose name was Constraint_Error (there were several enumeration types involved). As a result, the evaluation of the condition above ends up finding the enumerates which had no relevance whatsoever for our condition. We dealt with the situation by taking a compromise: We believe that this type of situation is not very common. In all my years at AdaCore, we have only had one report of such issue. So what we did was make the pre-defined exception names a little special, and assume that "constraint_error" in the catch exception command means the pre-defined exception. If the user ever happened to define his own exception with a name identical to one of the pre-defined exception (which should be very rare), and wants to break on his exception, then he'll have to use the fully-qualified name of his exception. 2008-09-30 Joel Brobecker * ada-lang.c (standard_exc): New static constant. (ada_exception_catchpoint_cond_string): Add special handling for the predefined exceptions. Tested on x86-linux. Checked in. I will see if I can add a note in our documentation about this (as a separate patch). -- Joel --MGYHOYXEY6WxJCY8 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="std-exc.diff" Content-length: 2248 Index: ada-lang.c =================================================================== RCS file: /cvs/src/src/gdb/ada-lang.c,v retrieving revision 1.173 retrieving revision 1.174 diff -u -p -r1.173 -r1.174 --- ada-lang.c 30 Sep 2008 20:14:13 -0000 1.173 +++ ada-lang.c 30 Sep 2008 20:42:21 -0000 1.174 @@ -9650,6 +9650,15 @@ enum exception_catchpoint_kind ex_catch_assert }; +/* Ada's standard exceptions. */ + +static char *standard_exc[] = { + "constraint_error", + "program_error", + "storage_error", + "tasking_error" +}; + typedef CORE_ADDR (ada_unhandled_exception_name_addr_ftype) (void); /* A structure that describes how to support exception catchpoints @@ -10334,6 +10343,35 @@ ada_exception_breakpoint_ops (enum excep static char * ada_exception_catchpoint_cond_string (const char *exp_string) { + int i; + + /* The standard exceptions are a special case. They are defined in + runtime units that have been compiled without debugging info; if + EXP_STRING is the not-fully-qualified name of a standard + exception (e.g. "constraint_error") then, during the evaluation + of the condition expression, the symbol lookup on this name would + *not* return this standard exception. The catchpoint condition + may then be set only on user-defined exceptions which have the + same not-fully-qualified name (e.g. my_package.constraint_error). + + To avoid this unexcepted behavior, these standard exceptions are + systematically prefixed by "standard". This means that "catch + exception constraint_error" is rewritten into "catch exception + standard.constraint_error". + + If an exception named contraint_error is defined in another package of + the inferior program, then the only way to specify this exception as a + breakpoint condition is to use its fully-qualified named: + e.g. my_package.constraint_error. */ + + for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++) + { + if (strcmp (standard_exc [i], exp_string) == 0) + { + return xstrprintf ("long_integer (e) = long_integer (&standard.%s)", + exp_string); + } + } return xstrprintf ("long_integer (e) = long_integer (&%s)", exp_string); } --MGYHOYXEY6WxJCY8--