From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3599 invoked by alias); 5 Feb 2009 03:03:11 -0000 Received: (qmail 3196 invoked by uid 22791); 5 Feb 2009 03:03:08 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_22,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.45.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 05 Feb 2009 03:03:02 +0000 Received: from wpaz17.hot.corp.google.com (wpaz17.hot.corp.google.com [172.24.198.81]) by smtp-out.google.com with ESMTP id n15330hY009373 for ; Wed, 4 Feb 2009 19:03:00 -0800 Received: from localhost (elbrus.corp.google.com [172.18.116.17]) by wpaz17.hot.corp.google.com with ESMTP id n1532vl0004173; Wed, 4 Feb 2009 19:02:58 -0800 Received: by localhost (Postfix, from userid 74925) id 8A6073A6B7A; Wed, 4 Feb 2009 19:02:57 -0800 (PST) To: gdb-patches@sourceware.org Subject: [patch] Fix a crash when displaying variables from shared library. Message-Id: <20090205030257.8A6073A6B7A@localhost> Date: Thu, 05 Feb 2009 03:03:00 -0000 From: ppluzhnikov@google.com (Paul Pluzhnikov) X-IsSubscribed: yes 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: 2009-02/txt/msg00116.txt.bz2 Greetings, Consider this source: /* main.c */ int main() { return foo(); } /* foo.c; compile as a shared library */ int a_global; int foo() { return ++a_global; } If you set "display a_global", and re-run the program, GDB will crash (gdb-6.7, 6.8, Head). This is happening because display_chain expressions refer to symbols, but solib symbols get freed and reloaded across inferior restarts. Attached patch adds a test case and fixes the problem. Tested on x86_64-linux with no regressions. OK to commit? -- Paul Pluzhnikov ChangeLog: 2009-02-04 Paul Pluzhnikov * printcmd.c (do_one_display): Reparse exp_string. (clear_dangling_display_expressions): New function. (_initialize_printcmd): Add observer. * solib.c (clear_solib): Add missing notification. testsuite/ChangeLog: 2009-02-04 Paul Pluzhnikov * solib-display.exp: New file. * solib-display-main.c: New file. * solib-display-lib.c: New file. Index: printcmd.c =================================================================== RCS file: /cvs/src/src/gdb/printcmd.c,v retrieving revision 1.142 diff -u -p -u -r1.142 printcmd.c --- printcmd.c 5 Feb 2009 00:13:43 -0000 1.142 +++ printcmd.c 5 Feb 2009 02:43:31 -0000 @@ -43,6 +43,7 @@ #include "disasm.h" #include "dfp.h" #include "valprint.h" +#include "observer.h" #ifdef TUI #include "tui/tui.h" /* For tui_active et.al. */ @@ -1526,6 +1527,9 @@ do_one_display (struct display *d) if (!within_current_scope) return; + if (d->exp == NULL) + d->exp = parse_expression (d->exp_string); + current_display_number = d->number; annotate_display_begin (); @@ -1731,6 +1735,18 @@ disable_display_command (char *args, int p++; } } + +static void +clear_dangling_display_expressions (struct so_list *solist) +{ + struct display *d; + + for (d = display_chain; d; d = d->next) + { + xfree (d->exp); + d->exp = NULL; + } +} /* Print the value in stack frame FRAME of a variable specified by a @@ -2367,6 +2383,8 @@ _initialize_printcmd (void) current_display_number = -1; + observer_attach_solib_unloaded (clear_dangling_display_expressions); + add_info ("address", address_info, _("Describe where symbol SYM is stored.")); Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.109 diff -u -p -u -r1.109 solib.c --- solib.c 15 Jan 2009 16:35:22 -0000 1.109 +++ solib.c 5 Feb 2009 02:43:31 -0000 @@ -908,6 +908,7 @@ clear_solib (void) { struct so_list *so = so_list_head; so_list_head = so->next; + observer_notify_solib_unloaded (so); if (so->abfd) remove_target_sections (so->abfd); free_so (so); Index: testsuite/gdb.base/solib-display-lib.c =================================================================== RCS file: testsuite/gdb.base/solib-display-lib.c diff -N testsuite/gdb.base/solib-display-lib.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-display-lib.c 5 Feb 2009 02:43:31 -0000 @@ -0,0 +1,19 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +int a_global; +int foo () { return ++a_global; } Index: testsuite/gdb.base/solib-display-main.c =================================================================== RCS file: testsuite/gdb.base/solib-display-main.c diff -N testsuite/gdb.base/solib-display-main.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-display-main.c 5 Feb 2009 02:43:31 -0000 @@ -0,0 +1,23 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +extern int foo (); + +int main () +{ + return foo (); +} Index: testsuite/gdb.base/solib-display.exp =================================================================== RCS file: testsuite/gdb.base/solib-display.exp diff -N testsuite/gdb.base/solib-display.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-display.exp 5 Feb 2009 02:43:31 -0000 @@ -0,0 +1,61 @@ +# Copyright 2009 Free Software Foundation, Inc. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contributed by Paul Pluzhnikov +# + +if {[skip_shlib_tests]} { + return 0 +} + +# Library file. +set libname "solib-display-lib" +set srcfile_lib ${srcdir}/${subdir}/${libname}.c +set binfile_lib ${objdir}/${subdir}/${libname}.so +set lib_flags [list debug ldflags=-Wl,-Bsymbolic] +# Binary file. +set testfile "solib-display-main" +set srcfile ${srcdir}/${subdir}/${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +set bin_flags [list debug shlib=${binfile_lib}] + +if [get_compiler_info ${binfile}] { + return -1 +} + +if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" + || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { + untested "Could not compile $binfile_lib or $binfile." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +gdb_test "display a_global" +gdb_test "continue" +gdb_test "run" "1: a_global = 0" + +gdb_exit + +return 0 + +