From 938f0e2f6766e90a5ddc5df00e97a68873fd1252 Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Wed, 2 Apr 2014 17:02:51 +0100 Subject: Remove previous frame if an error occurs when computing frame id during unwind. https://sourceware.org/ml/gdb-patches/2014-05/msg00712.html If an error is thrown during computing a frame id then the frame is left in existence but without a valid frame id, this will trigger internal errors if/when the frame is later visited (for example in a backtrace). This patch catches errors raised while computing the frame id, and arranges for the new frame, the one without a frame id, to be removed from the linked list of frames. gdb/ChangeLog: * frame.c (remove_prev_frame): New function. (get_prev_frame_if_no_cycle): Create / discard cleanup using remove_prev_frame. gdb/testsuite/ChangeLog: * gdb.arch/amd64-invalid-stack-middle.S: New file. * gdb.arch/amd64-invalid-stack-middle.c: New file. * gdb.arch/amd64-invalid-stack-middle.exp: New file. * gdb.arch/amd64-invalid-stack-top.c: New file. * gdb.arch/amd64-invalid-stack-top.exp: New file. --- .../gdb.arch/amd64-invalid-stack-middle.c | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c (limited to 'gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c') diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c new file mode 100644 index 0000000..05bbd1d --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c @@ -0,0 +1,89 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 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 . +*/ + +#include +#include +#include + +void +breakpt (void) +{ + /* Nothing. */ +} + +void +func5 (void) +{ + breakpt (); +} + +void +func4 (void) +{ + func5 (); +} + +void +func3 (void) +{ + func4 (); +} + +void +func2 (void *ptr) +{ + func3 (); +} + +void +func1 (void *ptr) +{ + func2 (ptr); +} + +/* Finds and returns an invalid pointer, mmaps in a page, grabs a pointer + to it then unmaps the page again. This is almost certainly "undefined" + behaviour, but should be good enough for this small test program. */ + +static void * +make_invalid_ptr (void) +{ + int page_size, ans; + void *ptr; + + page_size = getpagesize (); + ptr = mmap (0, page_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + assert (ptr != MAP_FAILED); + ans = munmap (ptr, page_size); + assert (ans == 0); + + return ptr; +} + +int +main (void) +{ + void *invalid_ptr; + + invalid_ptr = make_invalid_ptr (); + func1 (invalid_ptr); + + return 0; +} -- cgit v1.1