You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
615 lines
20 KiB
615 lines
20 KiB
commit c75bd3a23915c3122070a95e1974e323543ffbe4 |
|
Author: Jan Kratochvil <jan.kratochvil@redhat.com> |
|
Date: Sun Sep 7 14:09:59 2014 +0200 |
|
|
|
Fix crash on Python frame filters with unreadable arg |
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1126177 |
|
|
|
ERROR: AddressSanitizer: SEGV on unknown address 0x000000000050 (pc 0x000000992bef sp 0x7ffff9039530 bp 0x7ffff9039540 |
|
T0) |
|
#0 0x992bee in value_type .../gdb/value.c:925 |
|
#1 0x87c951 in py_print_single_arg python/py-framefilter.c:445 |
|
#2 0x87cfae in enumerate_args python/py-framefilter.c:596 |
|
#3 0x87e0b0 in py_print_args python/py-framefilter.c:968 |
|
|
|
It crashes because frame_arg::val is documented it may contain NULL |
|
(frame_arg::error is then non-NULL) but the code does not handle it. |
|
|
|
Another bug is that py_print_single_arg() calls goto out of its TRY_CATCH |
|
which messes up GDB cleanup chain crashing GDB later. |
|
|
|
It is probably 7.7 regression (I have not verified it) due to the introduction |
|
of Python frame filters. |
|
|
|
gdb/ChangeLog |
|
|
|
PR python/17355 |
|
* python/py-framefilter.c (py_print_single_arg): Handle NULL FA->VAL. |
|
Fix goto out of TRY_CATCH. |
|
|
|
gdb/testsuite/ChangeLog |
|
|
|
PR python/17355 |
|
* gdb.python/amd64-py-framefilter-invalidarg.S: New file. |
|
* gdb.python/py-framefilter-invalidarg-gdb.py.in: New file. |
|
* gdb.python/py-framefilter-invalidarg.exp: New file. |
|
* gdb.python/py-framefilter-invalidarg.py: New file. |
|
|
|
### a/gdb/ChangeLog |
|
### b/gdb/ChangeLog |
|
## -1,3 +1,9 @@ |
|
+2014-09-07 Jan Kratochvil <jan.kratochvil@redhat.com> |
|
+ |
|
+ PR python/17355 |
|
+ * python/py-framefilter.c (py_print_single_arg): Handle NULL FA->VAL. |
|
+ Fix goto out of TRY_CATCH. |
|
+ |
|
2014-09-06 Doug Evans <xdje42@gmail.com> |
|
Tom Tromey <tromey@redhat.com> |
|
|
|
### a/gdb/testsuite/ChangeLog |
|
### b/gdb/testsuite/ChangeLog |
|
## -1,3 +1,11 @@ |
|
+2014-09-07 Jan Kratochvil <jan.kratochvil@redhat.com> |
|
+ |
|
+ PR python/17355 |
|
+ * gdb.python/amd64-py-framefilter-invalidarg.S: New file. |
|
+ * gdb.python/py-framefilter-invalidarg-gdb.py.in: New file. |
|
+ * gdb.python/py-framefilter-invalidarg.exp: New file. |
|
+ * gdb.python/py-framefilter-invalidarg.py: New file. |
|
+ |
|
2014-09-06 Doug Evans <xdje42@gmail.com> |
|
|
|
PR 15276 |
|
Index: gdb-7.6.1/gdb/python/py-framefilter.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/python/py-framefilter.c 2015-11-27 18:06:21.901228682 +0100 |
|
+++ gdb-7.6.1/gdb/python/py-framefilter.c 2015-11-27 18:06:22.445231731 +0100 |
|
@@ -365,9 +365,12 @@ |
|
{ |
|
struct value *val; |
|
volatile struct gdb_exception except; |
|
+ enum py_bt_status retval = PY_BT_OK; |
|
|
|
if (fa != NULL) |
|
{ |
|
+ if (fa->val == NULL && fa->error == NULL) |
|
+ return PY_BT_OK; |
|
language = language_def (SYMBOL_LANGUAGE (fa->sym)); |
|
val = fa->val; |
|
} |
|
@@ -433,16 +436,18 @@ |
|
/* For MI print the type, but only for simple values. This seems |
|
weird, but this is how MI choose to format the various output |
|
types. */ |
|
- if (args_type == MI_PRINT_SIMPLE_VALUES) |
|
+ if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL) |
|
{ |
|
if (py_print_type (out, val) == PY_BT_ERROR) |
|
{ |
|
+ retval = PY_BT_ERROR; |
|
do_cleanups (cleanups); |
|
- goto error; |
|
+ continue; |
|
} |
|
} |
|
|
|
- annotate_arg_value (value_type (val)); |
|
+ if (val != NULL) |
|
+ annotate_arg_value (value_type (val)); |
|
|
|
/* If the output is to the CLI, and the user option "set print |
|
frame-arguments" is set to none, just output "...". */ |
|
@@ -454,27 +459,25 @@ |
|
for the case of MI_PRINT_NO_VALUES. */ |
|
if (args_type != NO_VALUES) |
|
{ |
|
- if (py_print_value (out, val, opts, 0, args_type, language) |
|
- == PY_BT_ERROR) |
|
+ if (val == NULL) |
|
{ |
|
- do_cleanups (cleanups); |
|
- goto error; |
|
+ gdb_assert (fa != NULL && fa->error != NULL); |
|
+ ui_out_field_fmt (out, "value", |
|
+ _("<error reading variable: %s>"), |
|
+ fa->error); |
|
} |
|
+ else if (py_print_value (out, val, opts, 0, args_type, language) |
|
+ == PY_BT_ERROR) |
|
+ retval = PY_BT_ERROR; |
|
} |
|
} |
|
|
|
do_cleanups (cleanups); |
|
} |
|
if (except.reason < 0) |
|
- { |
|
- gdbpy_convert_exception (except); |
|
- goto error; |
|
- } |
|
- |
|
- return PY_BT_OK; |
|
+ gdbpy_convert_exception (except); |
|
|
|
- error: |
|
- return PY_BT_ERROR; |
|
+ return retval; |
|
} |
|
|
|
/* Helper function to loop over frame arguments provided by the |
|
Index: gdb-7.6.1/gdb/testsuite/gdb.python/amd64-py-framefilter-invalidarg.S |
|
=================================================================== |
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
|
+++ gdb-7.6.1/gdb/testsuite/gdb.python/amd64-py-framefilter-invalidarg.S 2015-11-27 18:06:22.446231736 +0100 |
|
@@ -0,0 +1,261 @@ |
|
+/* 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 <http://www.gnu.org/licenses/>. */ |
|
+ |
|
+/* This file is compiled from a single line |
|
+ int main (int argc, char **argv) { return 0; } |
|
+ using -g -dA -S -O2 and patched as #if-ed below. */ |
|
+ |
|
+ .file "py-framefilter-invalidarg.c" |
|
+ .text |
|
+.Ltext0: |
|
+ .globl main |
|
+ .type main, @function |
|
+main: |
|
+.LFB0: |
|
+ .file 1 "py-framefilter-invalidarg.c" |
|
+ # py-framefilter-invalidarg.c:1 |
|
+ .loc 1 1 0 |
|
+ .cfi_startproc |
|
+# BLOCK 2 seq:0 |
|
+# PRED: ENTRY (FALLTHRU) |
|
+ pushq %rbp |
|
+ .cfi_def_cfa_offset 16 |
|
+ .cfi_offset 6, -16 |
|
+ movq %rsp, %rbp |
|
+ .cfi_def_cfa_register 6 |
|
+ movl %edi, -4(%rbp) |
|
+ movq %rsi, -16(%rbp) |
|
+ # py-framefilter-invalidarg.c:2 |
|
+ .loc 1 2 0 |
|
+ movl $0, %eax |
|
+ # py-framefilter-invalidarg.c:3 |
|
+ .loc 1 3 0 |
|
+ popq %rbp |
|
+ .cfi_def_cfa 7, 8 |
|
+# SUCC: EXIT [100.0%] |
|
+ ret |
|
+ .cfi_endproc |
|
+.LFE0: |
|
+ .size main, .-main |
|
+.Letext0: |
|
+ .section .debug_info,"",@progbits |
|
+.Ldebug_info0: |
|
+ .long .Le - .Ls # Length of Compilation Unit Info |
|
+.Ls: |
|
+ .value 0x4 # DWARF version number |
|
+ .long .Ldebug_abbrev0 # Offset Into Abbrev. Section |
|
+ .byte 0x8 # Pointer Size (in bytes) |
|
+ .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) |
|
+ .long .LASF3 # DW_AT_producer: "GNU C 4.9.1 20140813 (Red Hat 4.9.1-7) -mtune=generic -march=x86-64 -g" |
|
+ .byte 0x1 # DW_AT_language |
|
+ .long .LASF4 # DW_AT_name: "py-framefilter-invalidarg.c" |
|
+ .long .LASF5 # DW_AT_comp_dir: "" |
|
+ .quad .Ltext0 # DW_AT_low_pc |
|
+ .quad .Letext0-.Ltext0 # DW_AT_high_pc |
|
+ .long .Ldebug_line0 # DW_AT_stmt_list |
|
+die2d: |
|
+ .uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram) |
|
+ # DW_AT_external |
|
+ .long .LASF6 # DW_AT_name: "main" |
|
+ .byte 0x1 # DW_AT_decl_file (py-framefilter-invalidarg.c) |
|
+ .byte 0x1 # DW_AT_decl_line |
|
+ # DW_AT_prototyped |
|
+ .long die6b-.Ldebug_info0 # DW_AT_type |
|
+ .quad .LFB0 # DW_AT_low_pc |
|
+ .quad .LFE0-.LFB0 # DW_AT_high_pc |
|
+ .uleb128 0x1 # DW_AT_frame_base |
|
+ .byte 0x9c # DW_OP_call_frame_cfa |
|
+ # DW_AT_GNU_all_call_sites |
|
+die4e: |
|
+ .uleb128 0x3 # (DIE (0x4e) DW_TAG_formal_parameter) |
|
+ .long .LASF0 # DW_AT_name: "argc" |
|
+ .byte 0x1 # DW_AT_decl_file (py-framefilter-invalidarg.c) |
|
+ .byte 0x1 # DW_AT_decl_line |
|
+ .long die6b-.Ldebug_info0 # DW_AT_type |
|
+#if 0 |
|
+ .uleb128 0x2 # DW_AT_location |
|
+ .byte 0x91 # DW_OP_fbreg |
|
+ .sleb128 -20 |
|
+#endif |
|
+#if 0 |
|
+ .uleb128 1f - 2f # DW_AT_location |
|
+2: |
|
+ .byte 0x03 # DW_OP_addr |
|
+ .quad 0 |
|
+1: |
|
+#endif |
|
+#if 1 |
|
+ .uleb128 1f - 2f # DW_AT_location |
|
+2: |
|
+ .byte 0x13 # DW_OP_drop |
|
+ .quad 0 |
|
+1: |
|
+#endif |
|
+die5c: |
|
+ .uleb128 0x3 # (DIE (0x5c) DW_TAG_formal_parameter) |
|
+ .long .LASF1 # DW_AT_name: "argv" |
|
+ .byte 0x1 # DW_AT_decl_file (py-framefilter-invalidarg.c) |
|
+ .byte 0x1 # DW_AT_decl_line |
|
+ .long die72-.Ldebug_info0 # DW_AT_type |
|
+ .uleb128 0x2 # DW_AT_location |
|
+ .byte 0x91 # DW_OP_fbreg |
|
+ .sleb128 -32 |
|
+ .byte 0 # end of children of DIE 0x2d |
|
+die6b: |
|
+ .uleb128 0x4 # (DIE (0x6b) DW_TAG_base_type) |
|
+ .byte 0x4 # DW_AT_byte_size |
|
+ .byte 0x5 # DW_AT_encoding |
|
+ .ascii "int\0" # DW_AT_name |
|
+die72: |
|
+ .uleb128 0x5 # (DIE (0x72) DW_TAG_pointer_type) |
|
+ .byte 0x8 # DW_AT_byte_size |
|
+ .long die78-.Ldebug_info0 # DW_AT_type |
|
+die78: |
|
+ .uleb128 0x5 # (DIE (0x78) DW_TAG_pointer_type) |
|
+ .byte 0x8 # DW_AT_byte_size |
|
+ .long die7e-.Ldebug_info0 # DW_AT_type |
|
+die7e: |
|
+ .uleb128 0x6 # (DIE (0x7e) DW_TAG_base_type) |
|
+ .byte 0x1 # DW_AT_byte_size |
|
+ .byte 0x6 # DW_AT_encoding |
|
+ .long .LASF2 # DW_AT_name: "char" |
|
+ .byte 0 # end of children of DIE 0xb |
|
+.Le: |
|
+ .section .debug_abbrev,"",@progbits |
|
+.Ldebug_abbrev0: |
|
+ .uleb128 0x1 # (abbrev code) |
|
+ .uleb128 0x11 # (TAG: DW_TAG_compile_unit) |
|
+ .byte 0x1 # DW_children_yes |
|
+ .uleb128 0x25 # (DW_AT_producer) |
|
+ .uleb128 0xe # (DW_FORM_strp) |
|
+ .uleb128 0x13 # (DW_AT_language) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3 # (DW_AT_name) |
|
+ .uleb128 0xe # (DW_FORM_strp) |
|
+ .uleb128 0x1b # (DW_AT_comp_dir) |
|
+ .uleb128 0xe # (DW_FORM_strp) |
|
+ .uleb128 0x11 # (DW_AT_low_pc) |
|
+ .uleb128 0x1 # (DW_FORM_addr) |
|
+ .uleb128 0x12 # (DW_AT_high_pc) |
|
+ .uleb128 0x7 # (DW_FORM_data8) |
|
+ .uleb128 0x10 # (DW_AT_stmt_list) |
|
+ .uleb128 0x17 # (DW_FORM_sec_offset) |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .uleb128 0x2 # (abbrev code) |
|
+ .uleb128 0x2e # (TAG: DW_TAG_subprogram) |
|
+ .byte 0x1 # DW_children_yes |
|
+ .uleb128 0x3f # (DW_AT_external) |
|
+ .uleb128 0x19 # (DW_FORM_flag_present) |
|
+ .uleb128 0x3 # (DW_AT_name) |
|
+ .uleb128 0xe # (DW_FORM_strp) |
|
+ .uleb128 0x3a # (DW_AT_decl_file) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3b # (DW_AT_decl_line) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x27 # (DW_AT_prototyped) |
|
+ .uleb128 0x19 # (DW_FORM_flag_present) |
|
+ .uleb128 0x49 # (DW_AT_type) |
|
+ .uleb128 0x13 # (DW_FORM_ref4) |
|
+ .uleb128 0x11 # (DW_AT_low_pc) |
|
+ .uleb128 0x1 # (DW_FORM_addr) |
|
+ .uleb128 0x12 # (DW_AT_high_pc) |
|
+ .uleb128 0x7 # (DW_FORM_data8) |
|
+ .uleb128 0x40 # (DW_AT_frame_base) |
|
+ .uleb128 0x18 # (DW_FORM_exprloc) |
|
+ .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) |
|
+ .uleb128 0x19 # (DW_FORM_flag_present) |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .uleb128 0x3 # (abbrev code) |
|
+ .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) |
|
+ .byte 0 # DW_children_no |
|
+ .uleb128 0x3 # (DW_AT_name) |
|
+ .uleb128 0xe # (DW_FORM_strp) |
|
+ .uleb128 0x3a # (DW_AT_decl_file) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3b # (DW_AT_decl_line) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x49 # (DW_AT_type) |
|
+ .uleb128 0x13 # (DW_FORM_ref4) |
|
+ .uleb128 0x2 # (DW_AT_location) |
|
+ .uleb128 0x18 # (DW_FORM_exprloc) |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .uleb128 0x4 # (abbrev code) |
|
+ .uleb128 0x24 # (TAG: DW_TAG_base_type) |
|
+ .byte 0 # DW_children_no |
|
+ .uleb128 0xb # (DW_AT_byte_size) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3e # (DW_AT_encoding) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3 # (DW_AT_name) |
|
+ .uleb128 0x8 # (DW_FORM_string) |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .uleb128 0x5 # (abbrev code) |
|
+ .uleb128 0xf # (TAG: DW_TAG_pointer_type) |
|
+ .byte 0 # DW_children_no |
|
+ .uleb128 0xb # (DW_AT_byte_size) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x49 # (DW_AT_type) |
|
+ .uleb128 0x13 # (DW_FORM_ref4) |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .uleb128 0x6 # (abbrev code) |
|
+ .uleb128 0x24 # (TAG: DW_TAG_base_type) |
|
+ .byte 0 # DW_children_no |
|
+ .uleb128 0xb # (DW_AT_byte_size) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3e # (DW_AT_encoding) |
|
+ .uleb128 0xb # (DW_FORM_data1) |
|
+ .uleb128 0x3 # (DW_AT_name) |
|
+ .uleb128 0xe # (DW_FORM_strp) |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .byte 0 |
|
+ .section .debug_aranges,"",@progbits |
|
+ .long 0x2c # Length of Address Ranges Info |
|
+ .value 0x2 # DWARF Version |
|
+ .long .Ldebug_info0 # Offset of Compilation Unit Info |
|
+ .byte 0x8 # Size of Address |
|
+ .byte 0 # Size of Segment Descriptor |
|
+ .value 0 # Pad to 16 byte boundary |
|
+ .value 0 |
|
+ .quad .Ltext0 # Address |
|
+ .quad .Letext0-.Ltext0 # Length |
|
+ .quad 0 |
|
+ .quad 0 |
|
+ .section .debug_line,"",@progbits |
|
+.Ldebug_line0: |
|
+ .section .debug_str,"MS",@progbits,1 |
|
+.LASF1: |
|
+ .string "argv" |
|
+.LASF4: |
|
+ .string "py-framefilter-invalidarg.c" |
|
+.LASF5: |
|
+ .string "" |
|
+.LASF0: |
|
+ .string "argc" |
|
+.LASF3: |
|
+ .string "GNU C 4.9.1 20140813 (Red Hat 4.9.1-7) -mtune=generic -march=x86-64 -g" |
|
+.LASF6: |
|
+ .string "main" |
|
+.LASF2: |
|
+ .string "char" |
|
+ .ident "GCC: (GNU) 4.9.1 20140813 (Red Hat 4.9.1-7)" |
|
+ .section .note.GNU-stack,"",@progbits |
|
Index: gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-invalidarg-gdb.py.in |
|
=================================================================== |
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
|
+++ gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-invalidarg-gdb.py.in 2015-11-27 18:06:22.446231736 +0100 |
|
@@ -0,0 +1,48 @@ |
|
+# Copyright (C) 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 <http://www.gnu.org/licenses/>. |
|
+ |
|
+# This file is part of the GDB testsuite. It tests Python-based |
|
+# frame-filters. |
|
+import gdb |
|
+import itertools |
|
+from gdb.FrameDecorator import FrameDecorator |
|
+ |
|
+ |
|
+class FrameObjFile (): |
|
+ |
|
+ def __init__ (self): |
|
+ self.name = "Filter1" |
|
+ self.priority = 1 |
|
+ self.enabled = False |
|
+ gdb.current_progspace().frame_filters ["Progspace" + self.name] = self |
|
+ gdb.current_objfile().frame_filters ["ObjectFile" + self.name] = self |
|
+ |
|
+ def filter (self, frame_iter): |
|
+ return frame_iter |
|
+ |
|
+class FrameObjFile2 (): |
|
+ |
|
+ def __init__ (self): |
|
+ self.name = "Filter2" |
|
+ self.priority = 100 |
|
+ self.enabled = True |
|
+ gdb.current_progspace().frame_filters ["Progspace" + self.name] = self |
|
+ gdb.current_objfile().frame_filters ["ObjectFile" + self.name] = self |
|
+ |
|
+ def filter (self, frame_iter): |
|
+ return frame_iter |
|
+ |
|
+FrameObjFile() |
|
+FrameObjFile2() |
|
Index: gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp |
|
=================================================================== |
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
|
+++ gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp 2015-11-27 18:19:26.346625521 +0100 |
|
@@ -0,0 +1,86 @@ |
|
+# Copyright (C) 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 <http://www.gnu.org/licenses/>. |
|
+ |
|
+load_lib gdb-python.exp |
|
+ |
|
+standard_testfile amd64-py-framefilter-invalidarg.S |
|
+ |
|
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } { |
|
+ verbose "Skipping py-framefilter-invalidarg." |
|
+ return |
|
+} |
|
+ |
|
+# We cannot use prepare_for_testing as we have to set the safe-patch |
|
+# to check objfile and progspace printers. |
|
+if {[build_executable $testfile.exp $testfile $srcfile {}] == -1} { |
|
+ return -1 |
|
+} |
|
+ |
|
+# Start with a fresh gdb. |
|
+gdb_exit |
|
+gdb_start |
|
+ |
|
+# Skip all tests if Python scripting is not enabled. |
|
+if { [skip_python_tests] } { continue } |
|
+ |
|
+### IMPORT: |
|
+# Like remote_download but provides a gdb-specific behavior. If DEST |
|
+# is "host", and the host is not remote, and TOFILE is not specified, |
|
+# then the [file tail] of FROMFILE is passed through |
|
+# standard_output_file to compute the destination. |
|
+ |
|
+proc gdb_remote_download {dest fromfile {tofile {}}} { |
|
+ if {$dest == "host" && ![is_remote host] && $tofile == ""} { |
|
+ set tofile [standard_output_file [file tail $fromfile]] |
|
+ } |
|
+ |
|
+ if { $tofile == "" } { |
|
+ return [remote_download $dest $fromfile] |
|
+ } else { |
|
+ return [remote_download $dest $fromfile $tofile] |
|
+ } |
|
+} |
|
+### IMPORT^ |
|
+ |
|
+# Make the -gdb.py script available to gdb, it is automagically loaded by gdb. |
|
+# Care is taken to put it in the same directory as the binary so that |
|
+# gdb will find it. |
|
+set remote_obj_python_file \ |
|
+ [remote_download \ |
|
+ host ${srcdir}/${subdir}/${testfile}-gdb.py.in \ |
|
+ [standard_output_file ${testfile}-gdb.py]] |
|
+ |
|
+gdb_reinitialize_dir $srcdir/$subdir |
|
+gdb_test_no_output "set auto-load safe-path ${remote_obj_python_file}" \ |
|
+ "set auto-load safe-path" |
|
+gdb_load ${binfile} |
|
+# Verify gdb loaded the script. |
|
+gdb_test "info auto-load python-scripts" "Yes.*/${testfile}-gdb.py.*" \ |
|
+ "Test auto-load had loaded python scripts" |
|
+ |
|
+if ![runto_main] then { |
|
+ perror "couldn't run to breakpoint" |
|
+ return |
|
+} |
|
+gdb_test_no_output "set python print-stack full" \ |
|
+ "Set python print-stack to full" |
|
+ |
|
+# Load global frame-filters |
|
+set remote_python_file [gdb_remote_download host \ |
|
+ ${srcdir}/${subdir}/${testfile}.py] |
|
+gdb_test_no_output "python exec (open ('${remote_python_file}').read ())" \ |
|
+ "Load python file" |
|
+ |
|
+gdb_test "bt" " in niam \\(argc=<error reading variable: dwarf expression stack underflow>, argv=0x\[0-9a-f\]+\\) at py-framefilter-invalidarg.c:\[0-9\]+" "bt full with filters" |
|
Index: gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-invalidarg.py |
|
=================================================================== |
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
|
+++ gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-invalidarg.py 2015-11-27 18:06:22.447231742 +0100 |
|
@@ -0,0 +1,59 @@ |
|
+# Copyright (C) 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 <http://www.gnu.org/licenses/>. |
|
+ |
|
+# This file is part of the GDB testsuite. It tests Python-based |
|
+# frame-filters. |
|
+import gdb |
|
+import itertools |
|
+from gdb.FrameDecorator import FrameDecorator |
|
+import copy |
|
+ |
|
+class Reverse_Function (FrameDecorator): |
|
+ |
|
+ def __init__(self, fobj): |
|
+ super(Reverse_Function, self).__init__(fobj) |
|
+ self.fobj = fobj |
|
+ |
|
+ def function (self): |
|
+ fname = str (self.fobj.function()) |
|
+ if (fname == None or fname == ""): |
|
+ return None |
|
+ if fname == 'end_func': |
|
+ extra = self.fobj.inferior_frame().read_var('str').string() |
|
+ else: |
|
+ extra = '' |
|
+ fname = fname[::-1] + extra |
|
+ return fname |
|
+ |
|
+class FrameFilter (): |
|
+ |
|
+ def __init__ (self): |
|
+ self.name = "Reverse" |
|
+ self.priority = 100 |
|
+ self.enabled = True |
|
+ gdb.frame_filters [self.name] = self |
|
+ |
|
+ def filter (self, frame_iter): |
|
+ # Python 3.x moved the itertools.imap functionality to map(), |
|
+ # so check if it is available. |
|
+ if hasattr(itertools, "imap"): |
|
+ frame_iter = itertools.imap (Reverse_Function, |
|
+ frame_iter) |
|
+ else: |
|
+ frame_iter = map(Reverse_Function, frame_iter) |
|
+ |
|
+ return frame_iter |
|
+ |
|
+FrameFilter()
|
|
|