From patchwork Thu Mar 27 13:20:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 310 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (caibbdcaaahc.dreamhost.com [208.113.200.72]) by wilcox.dreamhost.com (Postfix) with ESMTP id 9046D3604DA for ; Thu, 27 Mar 2014 06:20:33 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14314964) id 422D240B8A855; Thu, 27 Mar 2014 06:20:33 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx20.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-mx20.g.dreamhost.com (Postfix) with ESMTPS id 1863B40B8A846 for ; Thu, 27 Mar 2014 06:20:33 -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:message-id:date:from:mime-version:to:subject :content-type:content-transfer-encoding; q=dns; s=default; b=sro CRdEYqW1PxGnV/to12UXCllCdePmrbD7L7EcagMS02UN0fu25mgZkDHrnYrdgnSH uyrfUQKxJCAYannrJ4m+Im9oMbFx3I8kiq4a/8M4klr8zx+FGpGtQbQyfVMjviZY gzFgC13kyAXTSyBfXFzlfv9c/0SNqIBC+I3vLFM8= 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:message-id:date:from:mime-version:to:subject :content-type:content-transfer-encoding; s=default; bh=JB5QhKRMh LvYAbnwVefmVmZTNN8=; b=FEtMiE/0kw6c5sxb/FK3dNd8ALZrOcTGlhKJlwqrS IFP5okbHYNHmNVMTsvSIkL7+Dg/XofO01MTByVG+vNhtmkAQXYeld0Nmlo4ma/OI PkupfuNRTNAJX16+AhEvFfIrNegRauLHouTCtD+aijPzpFXR5K9qOFeioT1BDnV1 z4= Received: (qmail 7946 invoked by alias); 27 Mar 2014 13:20:31 -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 7935 invoked by uid 89); 27 Mar 2014 13:20:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-gw3-out.broadcom.com Received: from mail-gw3-out.broadcom.com (HELO mail-gw3-out.broadcom.com) (216.31.210.64) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Mar 2014 13:20:28 +0000 Received: from irvexchcas07.broadcom.com (HELO IRVEXCHCAS07.corp.ad.broadcom.com) ([10.9.208.55]) by mail-gw3-out.broadcom.com with ESMTP; 27 Mar 2014 06:35:59 -0700 Received: from IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) by IRVEXCHCAS07.corp.ad.broadcom.com (10.9.208.55) with Microsoft SMTP Server (TLS) id 14.3.174.1; Thu, 27 Mar 2014 06:20:27 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) with Microsoft SMTP Server id 14.3.174.1; Thu, 27 Mar 2014 06:20:27 -0700 Received: from [10.177.73.80] (unknown [10.177.73.80]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 9C3FCEAD4C for ; Thu, 27 Mar 2014 06:20:26 -0700 (PDT) Message-ID: <53342599.9000206@broadcom.com> Date: Thu, 27 Mar 2014 13:20:25 +0000 From: Andrew Burgess User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 MIME-Version: 1.0 To: "gdb-patches@sourceware.org" Subject: [PATCH] -stack-info-depth should always return a count. X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in The MI command -stack-info-depth return the "depth" field in most cases. However, if due to stack corruption, gdb tries to access some invalid memory then the result is an error and no depth. I believe that the current behaviour would be better if gdb always returned a depth number, indicating the number of frames that are available before the stack corruption, the patch below does this. I have also added an new "reason" field to the -stack-info-depth reply, the reason is a string that tries to explain why gdb is giving this depth as an answer. For stacks without any corruption the only two possible reason strings are "All frames" (this is the total stack depth), or "Reached frame limit" (a LIMIT was passed to -stack-info-depth and reached). If there is stack corruption then the reason will be the error string from gdb. OK to apply? Thanks, Andrew gdb/ChangeLog: 2014-03-27 Andrew Burgess * mi/mi-cmd-stack.c (mi_cmd_stack_info_depth): Add TRY_CATCH around the stack unwind. Add a reason field to explain the given depth. * NEWS: Mention changes to -stack-info-depth command. gdb/testsuite/ChangeLog: 2014-03-27 Andrew Burgess * gdb.mi/mi-stack.exp (test_stack_info_depth): Expect new reason field. gdb/doc/ChangeLog: 2014-03-27 Andrew Burgess * gdb.texinfo (gdb/mi Stack Manipulation): Add information and examples explaining new reason field for -stack-info-depth command. diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c index 7bc8114..9a4eec7 100644 --- a/gdb/mi/mi-cmd-stack.c +++ b/gdb/mi/mi-cmd-stack.c @@ -170,8 +170,10 @@ void mi_cmd_stack_info_depth (char *command, char **argv, int argc) { int frame_high; - int i; + int i = 0; struct frame_info *fi; + volatile struct gdb_exception except; + const char *reason; if (argc > 1) error (_("-stack-info-depth: Usage: [MAX_DEPTH]")); @@ -183,12 +185,29 @@ mi_cmd_stack_info_depth (char *command, char **argv, int argc) the stack. */ frame_high = -1; - for (i = 0, fi = get_current_frame (); - fi && (i < frame_high || frame_high == -1); - i++, fi = get_prev_frame (fi)) - QUIT; + TRY_CATCH (except, RETURN_MASK_ERROR) + { + for (i = 0, fi = get_current_frame (); + fi && (i < frame_high || frame_high == -1); + i++, fi = get_prev_frame (fi)) + QUIT; + } + + if (except.message) + { + /* Due to the lazy way state is fetched from the target, if we have + an exception our depth count will be one greater than it should + be. */ + reason = except.message; + --i; + } + else if (frame_high == -1 || i < frame_high) + reason = _("All frames"); + else + reason = _("Reached frame limit"); ui_out_field_int (current_uiout, "depth", i); + ui_out_field_string (current_uiout, "reason", reason); } /* Print a list of the locals for the current frame. With argument of 2014-03-26 Yao Qi * lib/gdb.exp (readline_is_used): New proc. diff --git a/gdb/testsuite/gdb.mi/mi-stack.exp b/gdb/testsuite/gdb.mi/mi-stack.exp index ac7db7a..4977342 100644 --- a/gdb/testsuite/gdb.mi/mi-stack.exp +++ b/gdb/testsuite/gdb.mi/mi-stack.exp @@ -137,15 +137,15 @@ proc test_stack_info_depth {} { # -stack-info-depth 99 mi_gdb_test "231-stack-info-depth" \ - "231\\^done,depth=\"5\"" \ + "231\\^done,depth=\"5\",reason=\"\[^\"\]+\"" \ "stack info-depth" mi_gdb_test "231-stack-info-depth 3" \ - "231\\^done,depth=\"3\"" \ + "231\\^done,depth=\"3\",reason=\"\[^\"\]+\"" \ "stack info-depth 3" mi_gdb_test "231-stack-info-depth 99" \ - "231\\^done,depth=\"5\"" \ + "231\\^done,depth=\"5\",reason=\"\[^\"\]+\"" \ "stack info-depth 99" mi_gdb_test "231-stack-info-depth 99 99" \ diff --git a/gdb/NEWS b/gdb/NEWS index 2a384ba..172101e 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -95,6 +95,12 @@ PowerPC64 GNU/Linux little-endian powerpc64le-*-linux* and "assf"), have been deprecated. Use the "sharedlibrary" command, or its alias "share", instead. +* MI changes + + ** The -stack-info-depth command will now always return a depth even if + stack corruption is encountered. A new reason string is also returned + that explains why gdb is reporting this depth. + *** Changes in GDB 7.7 * Improved support for process record-replay and reverse debugging on diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 1df3ca0..4f4ece8 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -27534,8 +27534,11 @@ fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="17"@} -stack-info-depth [ @var{max-depth} ] @end smallexample -Return the depth of the stack. If the integer argument @var{max-depth} -is specified, do not count beyond @var{max-depth} frames. +Return the depth of the stack. If the integer argument +@var{max-depth} is specified, do not count beyond @var{max-depth} +frames. The reason why gdb returns the answer it does is also given. +Possible reasons are @var{All frames}, @var{Reached frame limit}, or +an error message. @subsubheading @value{GDBN} Command @@ -27548,19 +27551,35 @@ For a stack with frame levels 0 through 11: @smallexample (gdb) -stack-info-depth -^done,depth="12" +^done,depth="12",reason="All frames" (gdb) -stack-info-depth 4 -^done,depth="4" +^done,depth="4",reason="Reached frame limit" (gdb) -stack-info-depth 12 -^done,depth="12" +^done,depth="12",reason="Reached frame limit" (gdb) -stack-info-depth 11 -^done,depth="11" +^done,depth="11",reason="Reached frame limit" (gdb) -stack-info-depth 13 -^done,depth="12" +^done,depth="12",reason="All frames" +(gdb) +@end smallexample + +An example where there are 3 valid stack frames, after which the stack +pointer is corrupted and gdb is unable to unwind the stack further: + +@smallexample +(gdb) +-stack-info-depth +^done,depth="3",reason="Cannot access memory at address 0xffffffff" +(gdb) +-stack-info-depth 4 +^done,depth="3",reason="Cannot access memory at address 0xffffffff" +(gdb) +-stack-info-depth 3 +^done,depth="3",reason="Reached frame limit" (gdb) @end smallexample