diff --git a/gdb-babeltrace-minsize.patch b/gdb-babeltrace-minsize.patch new file mode 100644 index 0000000..d261277 --- /dev/null +++ b/gdb-babeltrace-minsize.patch @@ -0,0 +1,237 @@ +http://sourceware.org/ml/gdb-patches/2014-08/msg00376.html +Subject: Re: --with-babeltrace generates many FAILs + +On 08/19/2014 10:07 PM, Jan Kratochvil wrote: +> * '#if HAVE_LIBBABELTRACE1_1_0' could have a comment that >=1.1.1 rejects the +> faked packet (what you described in the mail but not in the patch). + +Fixed. To be precise, >= 1.1.2 rejects the faked packet, 1.1.1 +doesn't. See the table I posted. + +> * It is always better to check for feature/defect than to check for version. +> For example because various distros backport various fixes (unfortunately +> including their possible regressions/defects) and so version checks may be +> misleading then. At least in this case it seems to me as possible to check +> how libbacktrace behaves from configure; although maybe it is not easy +> enough, not sure. + +In order to check libbabeltrace's behaviour in configure, we have to write +a c program to generate CTF data and read the trace data via +babeltrace or any program (using libbabeltrace) written by ourselves. +It is not easy to do so. + +The patch is updated. OK to apply? + +-- +Yao (齐尧) + +Subject: [PATCH] Check babeltrace 1.1.0 +Subject: [PATCH] Check babeltrace 1.1.0 + +When GDB uses recent version of babeltrace, such as 1.2.x, we'll see +such error emitted from babeltrace library, + + (gdb) target ctf .../gdb/testsuite/gdb.trace/actions.ctf + [error] Invalid CTF stream: content size is smaller than +packet headers. + [error] Stream index creation error. + [error] Open file stream error. + +The problem can be reproduce out of GDB too, using babeltrace, + + $ babeltrace ./fake-packet.ctf/ + [error] Invalid CTF stream: content size is smaller than packet headers. + [error] Stream index creation error. + [error] Open file stream error. + +Recent babeltrace library becomes more strict on CTF, and complains +about one "faked packet" GDB adds, when saving trace data in ctf +format from GDB. babeltrace 1.1.0 has a bug that it can't read trace +data smaller than a certain size (see https://bugs.lttng.org/issues/450). +We workaround it in GDB to append some meaningless data in a faked +packet to make sure trace file is large enough (see ctf.c:ctf_end). +The babeltrace issue was fixed in 1.1.1 release. However, babeltrace +recent release (since 1.1.2) starts to complain about such faked +packet. Here is a table shows that whether faked packet or no faked +packet is supported by various babeltrace releases, + + faked packet no faked packet +1.1.0 Yes No +1.1.1 Yes Yes +1.1.2 No Yes +1.2.0 No Yes + +We decide to include the code to workaround 1.1.0 issue only if 1.1.0 +is used. We choose pkg-config to check babeltrace's version in +configure. + +gdb: + +2014-08-20 Yao Qi + + * configure.ac: Disable babeltrace support if pkg-config is + missing. Use pkg-config to check whether libbabeltrace is + 1.1.0. + * config.in: Regenerate. + * configure: Regenerate. + * ctf.c (CTF_FILE_MIN_SIZE): Remove. + (ctf_end): Wrap the code with + #if HAVE_LIBBABELTRACE1_1_0 #endif. + [HAVE_LIBBABELTRACE1_1_0] (CTF_FILE_MIN_SIZE): New macro. +--- + gdb/config.in | 3 +++ + gdb/configure | 25 +++++++++++++++++++++++++ + gdb/configure.ac | 22 ++++++++++++++++++++++ + gdb/ctf.c | 25 ++++++++++++++++--------- + 4 files changed, 66 insertions(+), 9 deletions(-) + +diff --git a/gdb/config.in b/gdb/config.in +index b853412..54152cd 100644 +--- a/gdb/config.in ++++ b/gdb/config.in +@@ -183,6 +183,9 @@ + /* Define if you have the babeltrace library. */ + #undef HAVE_LIBBABELTRACE + ++/* Define to 1 if you have libbabeltrace 1.1.0 */ ++#undef HAVE_LIBBABELTRACE1_1_0 ++ + /* Define to 1 if you have the `dl' library (-ldl). */ + #undef HAVE_LIBDL + +diff --git a/gdb/configure b/gdb/configure +index 9253e28..d4e2c6e 100755 +--- a/gdb/configure ++++ b/gdb/configure +@@ -14817,6 +14817,11 @@ $as_echo "$with_babeltrace" >&6; } + if test "x$with_babeltrace" = "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: babletrace support disabled; GDB is unable to read CTF data." >&5 + $as_echo "$as_me: WARNING: babletrace support disabled; GDB is unable to read CTF data." >&2;} ++elif test "${pkg_config_prog_path}" = "missing"; then ++ # pkg-config is used to check the version of libbabeltrace. If pkg-config ++ # is missing, we have to disable babeltrace support. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not found, babletrace support disabled" >&5 ++$as_echo "$as_me: WARNING: pkg-config not found, babletrace support disabled" >&2;} + else + # Append -Werror to CFLAGS so that configure can catch the warning + # "assignment from incompatible pointer type", which is related to +@@ -15307,6 +15312,26 @@ $as_echo "$LIBBABELTRACE" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: babeltrace is missing or unusable; GDB is unable to read CTF data." >&5 + $as_echo "$as_me: WARNING: babeltrace is missing or unusable; GDB is unable to read CTF data." >&2;} + fi ++ else ++ # Need to know whether libbabeltrace is 1.1.0. ++ pkg_config_path= ++ for x in $LTLIBBABELTRACE; do ++ case "$x" in ++ -L*) ++ dir=`echo "X$x" | sed -e 's/^X-L//'` ++ if test -d "$dir/pkgconfig"; then ++ pkg_config_path="${pkg_config_path}${pkg_config_path:+:}$dir/pkgconfig" ++ fi ++ ;; ++ esac ++ done ++ ++ `PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$pkg_config_path ${pkg_config_prog_path} babeltrace = 1.1.0` ++ if test "$?" -eq 0 ; then ++ ++$as_echo "#define HAVE_LIBBABELTRACE1_1_0 1" >>confdefs.h ++ ++ fi + fi + fi + +diff --git a/gdb/configure.ac b/gdb/configure.ac +index 61919b4..1d8d400 100644 +--- a/gdb/configure.ac ++++ b/gdb/configure.ac +@@ -2420,6 +2420,10 @@ AC_MSG_RESULT([$with_babeltrace]) + + if test "x$with_babeltrace" = "xno"; then + AC_MSG_WARN([babletrace support disabled; GDB is unable to read CTF data.]) ++elif test "${pkg_config_prog_path}" = "missing"; then ++ # pkg-config is used to check the version of libbabeltrace. If pkg-config ++ # is missing, we have to disable babeltrace support. ++ AC_MSG_WARN([pkg-config not found, babletrace support disabled]) + else + # Append -Werror to CFLAGS so that configure can catch the warning + # "assignment from incompatible pointer type", which is related to +@@ -2450,6 +2454,24 @@ else + else + AC_MSG_WARN([babeltrace is missing or unusable; GDB is unable to read CTF data.]) + fi ++ else ++ # Need to know whether libbabeltrace is 1.1.0. ++ pkg_config_path= ++ for x in $LTLIBBABELTRACE; do ++ case "$x" in ++ -L*) ++ dir=`echo "X$x" | sed -e 's/^X-L//'` ++ if test -d "$dir/pkgconfig"; then ++ pkg_config_path="${pkg_config_path}${pkg_config_path:+:}$dir/pkgconfig" ++ fi ++ ;; ++ esac ++ done ++ ++ `PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$pkg_config_path ${pkg_config_prog_path} babeltrace = 1.1.0` ++ if test "$?" -eq 0 ; then ++ AC_DEFINE([HAVE_LIBBABELTRACE1_1_0], [1], [Define to 1 if you have libbabeltrace 1.1.0]) ++ fi + fi + fi + +diff --git a/gdb/ctf.c b/gdb/ctf.c +index df645c0..684da50 100644 +--- a/gdb/ctf.c ++++ b/gdb/ctf.c +@@ -623,11 +623,6 @@ ctf_write_definition_end (struct trace_file_writer *self) + self->ops->frame_ops->end (self); + } + +-/* The minimal file size of data stream. It is required by +- babeltrace. */ +- +-#define CTF_FILE_MIN_SIZE 4096 +- + /* This is the implementation of trace_file_write_ops method + end. */ + +@@ -637,10 +632,21 @@ ctf_end (struct trace_file_writer *self) + struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self; + + gdb_assert (writer->tcs.content_size == 0); +- /* The babeltrace requires or assumes that the size of datastream +- file is greater than 4096 bytes. If we don't generate enough +- packets and events, create a fake packet which has zero event, +- to use up the space. */ ++ ++#if HAVE_LIBBABELTRACE1_1_0 ++ /* The babeltrace-1.1.0 requires or assumes that the size of datastream ++ file is greater than 4096 bytes. This was fixed after 1.1.0 release. ++ See https://bugs.lttng.org/issues/450 ++ If we don't generate enough packets and events, create a fake packet ++ which has zero event, to use up the space. However, babeltrace ++ release (since 1.1.2) starts to complain about such faked packet, ++ we include this workaround only for babeltrace 1.1.0. */ ++ ++ /* The minimal file size of data stream. It is required by ++ babeltrace. */ ++ ++#define CTF_FILE_MIN_SIZE 4096 ++ + if (writer->tcs.packet_start < CTF_FILE_MIN_SIZE) + { + uint32_t u32; +@@ -681,6 +687,7 @@ ctf_end (struct trace_file_writer *self) + ctf_save_write (&writer->tcs, &b, 1); + } + } ++#endif /* HAVE_LIBBABELTRACE1_1_0 */ + } + + /* This is the implementation of trace_frame_write_ops method +-- +1.9.3 + diff --git a/gdb.spec b/gdb.spec index 728d95f..ebab169 100644 --- a/gdb.spec +++ b/gdb.spec @@ -26,7 +26,7 @@ Version: 7.8 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 19%{?dist} +Release: 20%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain and GFDL Group: Development/Debuggers @@ -525,11 +525,16 @@ Patch921: gdb-python-completer-2of2.patch Patch925: gdb-fortran-frame-string.patch # Fix -Werror=unused-variable error configuring babeltrace. +# Fix babeltrace errors (Yao Qi). Patch926: gdb-babeltrace-configure.patch +Patch928: gdb-babeltrace-minsize.patch # Fix Python GIL with gdb.execute("continue") (Phil Muldoon, BZ 1116957). Patch927: gdb-python-gil.patch +# Fix crash on Python frame filters with unreadable arg (BZ 1126177). +Patch929: python-framefilter-invalidarg.patch + %if 0%{!?rhel:1} || 0%{?rhel} > 6 # RL_STATE_FEDORA_GDB would not be found for: # Patch642: gdb-readline62-ask-more-rh.patch @@ -814,7 +819,9 @@ find -name "*.info*"|xargs rm -f %patch921 -p1 %patch925 -p1 %patch926 -p1 +%patch928 -p1 %patch927 -p1 +%patch929 -p1 %patch848 -p1 %if 0%{!?el6:1} @@ -1310,6 +1317,10 @@ then fi %changelog +* Wed Aug 20 2014 Jan Kratochvil - 7.8-20.fc21 +- Fix babeltrace errors (Yao Qi). +- Fix crash on Python frame filters with unreadable arg (BZ 1126177). + * Sat Aug 16 2014 Fedora Release Engineering - 7.8-19 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild diff --git a/python-framefilter-invalidarg.patch b/python-framefilter-invalidarg.patch new file mode 100644 index 0000000..4c1f16b --- /dev/null +++ b/python-framefilter-invalidarg.patch @@ -0,0 +1,596 @@ +http://sourceware.org/ml/gdb-patches/2014-08/msg00364.html +Subject: [patch+7.8?] Fix crash on Python frame filters with unreadable arg + + +--d6Gm4EdcadzBjdND +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +Hi, + +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. + +I tried to somehow separate it to two patches first but it in the end kept +them merged. + +No regressions on {x86_64,x86_64-m32,i686}-fedorarawhide-linux-gnu. + +It is probably 7.7 regression (I have not verified it) due to the introduction +of Python frame filters. + +I am not sure if it is more suitable for gdb.arch/ or gdb.python/ , used the +latter. + + +Thanks, +Jan + +--d6Gm4EdcadzBjdND +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline; filename="pyinvalidarg.patch" + +gdb/ +2014-08-19 Jan Kratochvil + + * python/py-framefilter.c (py_print_single_arg): Handle NULL FA->VAL. + Fix goto out of TRY_CATCH. + +gdb/testsuite/ +2014-08-19 Jan Kratochvil + + * 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. + +diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c +index 9db83c7..d53282f 100644 +--- a/gdb/python/py-framefilter.c ++++ b/gdb/python/py-framefilter.c +@@ -365,9 +365,12 @@ py_print_single_arg (struct ui_out *out, + { + struct value *val; + volatile struct gdb_exception except; ++ enum ext_lang_bt_status retval = EXT_LANG_BT_OK; + + if (fa != NULL) + { ++ if (fa->val == NULL && fa->error == NULL) ++ return EXT_LANG_BT_OK; + language = language_def (SYMBOL_LANGUAGE (fa->sym)); + val = fa->val; + } +@@ -433,16 +436,18 @@ py_print_single_arg (struct ui_out *out, + /* 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) == EXT_LANG_BT_ERROR) + { ++ retval = EXT_LANG_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 @@ py_print_single_arg (struct ui_out *out, + for the case of MI_PRINT_NO_VALUES. */ + if (args_type != NO_VALUES) + { +- if (py_print_value (out, val, opts, 0, args_type, language) +- == EXT_LANG_BT_ERROR) ++ if (val == NULL) + { +- do_cleanups (cleanups); +- goto error; ++ gdb_assert (fa != NULL && fa->error != NULL); ++ ui_out_field_fmt (out, "value", ++ _(""), ++ fa->error); + } ++ else if (py_print_value (out, val, opts, 0, args_type, language) ++ == EXT_LANG_BT_ERROR) ++ retval = EXT_LANG_BT_ERROR; + } + } + + do_cleanups (cleanups); + } + if (except.reason < 0) +- { +- gdbpy_convert_exception (except); +- goto error; +- } +- +- return EXT_LANG_BT_OK; ++ gdbpy_convert_exception (except); + +- error: +- return EXT_LANG_BT_ERROR; ++ return retval; + } + + /* Helper function to loop over frame arguments provided by the +diff --git a/gdb/testsuite/gdb.python/amd64-py-framefilter-invalidarg.S b/gdb/testsuite/gdb.python/amd64-py-framefilter-invalidarg.S +new file mode 100755 +index 0000000..3ac1b23 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/amd64-py-framefilter-invalidarg.S +@@ -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 . */ ++ ++/* 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 +diff --git a/gdb/testsuite/gdb.python/py-framefilter-invalidarg-gdb.py.in b/gdb/testsuite/gdb.python/py-framefilter-invalidarg-gdb.py.in +new file mode 100644 +index 0000000..1fa6ffc +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-framefilter-invalidarg-gdb.py.in +@@ -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 . ++ ++# 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() +diff --git a/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp b/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp +new file mode 100644 +index 0000000..f70d16e +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp +@@ -0,0 +1,67 @@ ++# 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 . ++ ++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 } ++ ++# 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=, argv=0x\[0-9a-f\]+\\) at py-framefilter-invalidarg.c:\[0-9\]+" "bt full with filters" +diff --git a/gdb/testsuite/gdb.python/py-framefilter-invalidarg.py b/gdb/testsuite/gdb.python/py-framefilter-invalidarg.py +new file mode 100644 +index 0000000..d5f92cb +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-framefilter-invalidarg.py +@@ -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 . ++ ++# 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() + +--d6Gm4EdcadzBjdND-- +