From patchwork Mon May 19 11:48:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary Benson X-Patchwork-Id: 1010 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id EDEA2360076 for ; Mon, 19 May 2014 04:48:16 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14314964) id A1B0241CA6B1D; Mon, 19 May 2014 04:48:16 -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 8189141CA6B02 for ; Mon, 19 May 2014 04:48:16 -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:date:from:to:cc:subject:message-id :mime-version:content-type; q=dns; s=default; b=F339tAdrMs1HoSck 1XHADA33qwNY74g+LFMp+RI0xYCvNC9p0ZQZFPYDpgSzqqRkAe98qyI0ZHaWMxKx 2DL7J3FB6aGZZvf7bXG0rw/pZDdsDoNGnrNweE+b6RGNzoiOB13DSEQJwMovFYbi 3d8yrgahOJA9G8zaFF4V8Zpul5E= 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:date:from:to:cc:subject:message-id :mime-version:content-type; s=default; bh=XhywlvuM9eJ72pGOwViReU qJfsQ=; b=LLaB0i+9uOeR+wmuUTP5cQBw4Qa7CiRWJzpdhBexaK11oQwtTamDIm utNVsEe0UYfy8JVkPiQjchc0haHMN5IdjOj2clhlsSk4+pNW5Ux0HTFJHrAhPgDg eNbp7xv6XJHquP5gfU2AciTeYP5mmALFR3NiM3/wbdkvVRlnCsuTQ= Received: (qmail 26579 invoked by alias); 19 May 2014 11:48:14 -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 26556 invoked by uid 89); 19 May 2014 11:48:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 19 May 2014 11:48:11 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s4JBm46t021741 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 19 May 2014 07:48:04 -0400 Received: from blade.nx (ovpn-116-75.ams2.redhat.com [10.36.116.75]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s4JBm2Jn019432; Mon, 19 May 2014 07:48:03 -0400 Received: by blade.nx (Postfix, from userid 1000) id 245B926240E; Mon, 19 May 2014 12:48:02 +0100 (BST) Date: Mon, 19 May 2014 12:48:02 +0100 From: Gary Benson To: gdb-patches@sourceware.org Cc: Andrew Burgess , Doug Evans , Eli Zaretskii , Florian Weimer , Mark Kettenis , Pedro Alves , Tom Tromey Subject: [PATCH 2/2 v2] Demangler crash handler Message-ID: <20140519114801.GA31140@blade.nx> MIME-Version: 1.0 Content-Disposition: inline X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in Hi all, This patch is an updated version of patch 2 of the demangler crash handler I posted last week. Patch 1 of this series [1] remains the same. The main change I have made is to cause the crash handler to be disabled by default. The user must explicitly enable the handler with "maint set catch-demangler-crashes on". This will simplify triage of bugs such as PR 16957 [2], a new demangler crash that was reported on Friday. The user did not supply enough information to see the offending symbol, and I don't have the necessary compiler or libraries to reproduce the bug locally. With this patch we can instruct the user to enter "maint set catch-demangler-crashes on" and repeat whatever they did to cause the crash in the first place. We can then easily obtain the first offending symbol GDB encountered. The other main change I have made from the original patch is to remove as much code as possible from the signal handler itself such that only a (sig)longjmp remains. While this is still not strictly safe, it should be clear if any future problems have been caused by this because the problem will only occur if the user has enabled the crash handler. One final change from my original patch is that this patch uses internal_warning to offer the same "quit this session/create a core file" choices as offered for other internal problems. Is this ok to commit? Thanks, Gary --- [1] https://sourceware.org/ml/gdb-patches/2014-05/msg00109.html [2] https://sourceware.org/bugzilla/show_bug.cgi?id=16957 -- This patch adds a new maintainence boolean, catch_demangler_crashes. If set, calls to the demangler are wrapped with a segmentation fault handler. The first time a segmentation fault is caught the offending symbol is displayed and internal_warning is called. The NEWS file entry for this patch is as follows: * New options maint set catch-demangler-crashes (on|off) maint show catch-demangler-crashes Control whether the debugger should attempt to catch crashes in the symbol name demangler. The default is not to attempt to catch crashes. The first time a crash is caught the offending symbol is displayed and the user is presented with options to terminate the current session and/or to create a core file. gdb/ 2014-05-19 Gary Benson * cp-support.c (signal.h): New include. (catch_demangler_crashes): New flag. (SIGJMP_BUF): New define. (SIGSETJMP): Likewise. (SIGLONGJMP): Likewise. (gdb_demangle_jmp_buf): New variable. (gdb_demangle_signal_handler): New function. (gdb_demangle): If catch_demangler_crashes is set, install the above signal handler before calling bfd_demangle, and restore the original signal handler afterwards. Display the offending symbol and call internal_warning the first time a segmentation fault is caught. (_initialize_cp_support): New maint set/show command. gdb/doc/ 2014-05-19 Gary Benson * gdb.texinfo (Maintenance Commands): Document new "maint set/show catch-demangler-crashes" option. diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 91533e8..d065d1f 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -36,6 +36,7 @@ #include "value.h" #include "cp-abi.h" #include "language.h" +#include #include "safe-ctype.h" @@ -1505,12 +1506,101 @@ cp_lookup_rtti_type (const char *name, struct block *block) return rtti_type; } +#ifdef SIGSEGV + +/* If nonzero, attempt to catch crashes in the demangler and print + useful debugging information. */ + +static int catch_demangler_crashes = 0; + +/* Wrap set/long jmp so that it's more portable. */ + +#if defined(HAVE_SIGSETJMP) +#define SIGJMP_BUF sigjmp_buf +#define SIGSETJMP(buf) sigsetjmp((buf), 1) +#define SIGLONGJMP(buf,val) siglongjmp((buf), (val)) +#else +#define SIGJMP_BUF jmp_buf +#define SIGSETJMP(buf) setjmp(buf) +#define SIGLONGJMP(buf,val) longjmp((buf), (val)) +#endif + +/* Stack context and environment for demangler crash recovery. */ + +static SIGJMP_BUF gdb_demangle_jmp_buf; + +/* Signal handler for gdb_demangle. */ + +static void +gdb_demangle_signal_handler (int signo) +{ + SIGLONGJMP (gdb_demangle_jmp_buf, signo); +} + +#endif + /* A wrapper for bfd_demangle. */ char * gdb_demangle (const char *name, int options) { - return bfd_demangle (NULL, name, options); + char *result = NULL; + int crash_signal = 0; + +#ifdef SIGSEGV +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + struct sigaction sa, old_sa; + + if (catch_demangler_crashes) + { + sa.sa_handler = gdb_demangle_signal_handler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (SIGSEGV, &sa, &old_sa); + } +#else + void (*ofunc) (); + + if (catch_demangler_crashes) + ofunc = (void (*)()) signal (SIGSEGV, gdb_demangle_signal_handler); +#endif + + if (catch_demangler_crashes) + crash_signal = SIGSETJMP (gdb_demangle_jmp_buf); +#endif + + if (crash_signal == 0) + result = bfd_demangle (NULL, name, options); + +#ifdef SIGSEGV + if (catch_demangler_crashes) + { +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + sigaction (SIGSEGV, &old_sa, NULL); +#else + signal (SIGSEGV, ofunc); +#endif + + if (crash_signal != 0) + { + static int error_reported = 0; + + if (!error_reported) + { + internal_warning (__FILE__, __LINE__, + _("unable to demangle '%s' " + "(demangler failed with signal %d)"), + name, crash_signal); + + error_reported = 1; + } + + result = NULL; + } + } +#endif + + return result; } /* Don't allow just "maintenance cplus". */ @@ -1585,4 +1675,17 @@ _initialize_cp_support (void) Usage: info vtbl EXPRESSION\n\ Evaluate EXPRESSION and display the virtual function table for the\n\ resulting object.")); + +#ifdef SIGSEGV + add_setshow_boolean_cmd ("catch-demangler-crashes", class_maintenance, + &catch_demangler_crashes, _("\ +Set whether to attempt to catch demangler crashes."), _("\ +Show whether GDB will attempt to catch demangler crashes."), _("\ +If enabled GDB will attempt to catch demangler crashes and\n\ +display the offending symbol."), + NULL, + NULL, + &maintenance_set_cmdlist, + &maintenance_show_cmdlist); +#endif }