[gdb/f14/master] - Fix python stale error state, also fix its save/restore (BZ 639089). - Fix inferior exec of new PI
Jan Kratochvil
jkratoch at fedoraproject.org
Tue Oct 12 16:32:05 UTC 2010
commit 23eda4b29e2ec6e36b0b7d12b3f9ac19092fc660
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date: Tue Oct 12 18:32:11 2010 +0200
- Fix python stale error state, also fix its save/restore (BZ 639089).
- Fix inferior exec of new PIE x86_64 (BZ 638979).
gdb-exec-pie-amd64.patch | 418 +++++++++++++++++++++++++++++
gdb-python-error-state.patch | 592 ++++++++++++++++++++++++++++++++++++++++++
gdb.spec | 14 +-
3 files changed, 1023 insertions(+), 1 deletions(-)
---
diff --git a/gdb-exec-pie-amd64.patch b/gdb-exec-pie-amd64.patch
new file mode 100644
index 0000000..e8403ad
--- /dev/null
+++ b/gdb-exec-pie-amd64.patch
@@ -0,0 +1,418 @@
+http://sourceware.org/ml/gdb-patches/2010-09/msg00519.html
+Subject: [patch] Fix inferior execl of new PIE x86_64
+
+Hi,
+
+gcc -o 1 1.c -Wall -g -fPIE -pie; gdb -nx ./1 -ex 'b main' -ex r -ex c
+
+Starting program: .../gdb/1
+Breakpoint 1, main (argc=1, argv=0x7fffffffdff8) at 1.c:7
+7 setbuf (stdout, NULL);
+Continuing.
+re-exec
+process 28056 is executing new program: .../gdb/1
+Error in re-setting breakpoint 1: Cannot access memory at address 0x80c
+exit
+Program exited normally.
+(gdb) _
+
+while it should be:
+
+re-exec
+process 28095 is executing new program: .../gdb/1
+Breakpoint 1, main (argc=2, argv=0x7fffffffe008) at 1.c:7
+7 setbuf (stdout, NULL);
+(gdb) _
+
+The error comes from:
+
+throw_error <- memory_error <- read_memory <- read_memory_unsigned_integer <-
+amd64_analyze_prologue <- amd64_skip_prologue <- gdbarch_skip_prologue <-
+skip_prologue_sal <- find_function_start_sal <- symbol_found <- decode_variable
+<- decode_line_1 <- breakpoint_re_set_one <- catch_errors <- breakpoint_re_set
+<- clear_symtab_users <- new_symfile_objfile <-
+symbol_file_add_with_addrs_or_offsets <- symbol_file_add_from_bfd <-
+symbol_file_add <- symbol_file_add_main_1 <- symbol_file_add_main <-
+follow_exec
+
+
+I understand this hack is not nice, the correct way would be to unify more
+follow_exec with post_create_inferior. But I could break it for non-GNU/Linux
+targets a lot.
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora14snapshot-linux-gnu.
+
+
+Thanks,
+Jan
+
+
+for the demo above:
+------------------------------------------------------------------------------
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+int
+main (int argc, char **argv)
+{
+ setbuf (stdout, NULL);
+ if (argc == 1)
+ {
+ puts ("re-exec");
+ execl ("/proc/self/exe", argv[0], "foo", NULL);
+ assert (0);
+ }
+ puts ("exit");
+ return 0;
+}
+------------------------------------------------------------------------------
+
+
+gdb/
+2010-09-30 Jan Kratochvil <jan.kratochvil at redhat.com>
+
+ * infrun.c (follow_exec): Replace symbol_file_add_main by
+ symbol_file_add with SYMFILE_DEFER_BP_RESET, set_initial_language and
+ breakpoint_re_set.
+ * m32r-rom.c (m32r_load, m32r_upload_command): Use parameter 0 for
+ clear_symtab_users.
+ * objfiles.c (free_all_objfiles): Likewise.
+ * remote-m32r-sdi.c (m32r_load): Likewise.
+ * solib-som.c (som_solib_create_inferior_hook): Likewise.
+ * symfile.c (new_symfile_objfile): New comment for add_flags. Call
+ clear_symtab_users with ADD_FLAGS.
+ (reread_symbols): Use parameter 0 for clear_symtab_users.
+ (clear_symtab_users): New parameter add_flags. Do not call
+ breakpoint_re_set if SYMFILE_DEFER_BP_RESET.
+ (clear_symtab_users_cleanup): Use parameter 0 for clear_symtab_users.
+ * symtab.h (clear_symtab_users): New parameter add_flags.
+
+gdb/testsuite/
+2010-09-30 Jan Kratochvil <jan.kratochvil at redhat.com>
+
+ * gdb.base/pie-execl.exp: New file.
+ * gdb.base/pie-execl.c: New file.
+
+Index: gdb-7.2/gdb/infrun.c
+===================================================================
+--- gdb-7.2.orig/gdb/infrun.c 2010-10-12 18:27:58.000000000 +0200
++++ gdb-7.2/gdb/infrun.c 2010-10-12 18:29:24.000000000 +0200
+@@ -840,8 +840,15 @@ follow_exec (ptid_t pid, char *execd_pat
+ /* That a.out is now the one to use. */
+ exec_file_attach (execd_pathname, 0);
+
+- /* Load the main file's symbols. */
+- symbol_file_add_main (execd_pathname, 0);
++ /* SYMFILE_DEFER_BP_RESET is used as the proper displacement for PIE
++ (Position Independent Executable) main symbol file will get applied by
++ solib_create_inferior_hook below. breakpoint_re_set would fail to insert
++ the breakpoints with the zero displacement. */
++
++ symbol_file_add (execd_pathname, SYMFILE_MAINLINE | SYMFILE_DEFER_BP_RESET,
++ NULL, 0);
++
++ set_initial_language ();
+
+ #ifdef SOLIB_CREATE_INFERIOR_HOOK
+ SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+@@ -851,6 +858,8 @@ follow_exec (ptid_t pid, char *execd_pat
+
+ jit_inferior_created_hook ();
+
++ breakpoint_re_set ();
++
+ /* Reinsert all breakpoints. (Those which were symbolic have
+ been reset to the proper address in the new a.out, thanks
+ to symbol_file_command...) */
+Index: gdb-7.2/gdb/m32r-rom.c
+===================================================================
+--- gdb-7.2.orig/gdb/m32r-rom.c 2010-01-01 08:31:37.000000000 +0100
++++ gdb-7.2/gdb/m32r-rom.c 2010-10-12 18:29:24.000000000 +0200
+@@ -188,7 +188,7 @@ m32r_load (char *filename, int from_tty)
+ the stack may not be valid, and things would get horribly
+ confused... */
+
+- clear_symtab_users ();
++ clear_symtab_users (0);
+ }
+
+ static void
+@@ -551,7 +551,7 @@ m32r_upload_command (char *args, int fro
+ the stack may not be valid, and things would get horribly
+ confused... */
+
+- clear_symtab_users ();
++ clear_symtab_users (0);
+ }
+
+ /* Provide a prototype to silence -Wmissing-prototypes. */
+Index: gdb-7.2/gdb/objfiles.c
+===================================================================
+--- gdb-7.2.orig/gdb/objfiles.c 2010-10-12 18:27:56.000000000 +0200
++++ gdb-7.2/gdb/objfiles.c 2010-10-12 18:29:39.000000000 +0200
+@@ -699,7 +699,7 @@ free_all_objfiles (void)
+ {
+ free_objfile (objfile);
+ }
+- clear_symtab_users ();
++ clear_symtab_users (0);
+ }
+
+ /* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
+Index: gdb-7.2/gdb/remote-m32r-sdi.c
+===================================================================
+--- gdb-7.2.orig/gdb/remote-m32r-sdi.c 2010-07-07 18:15:16.000000000 +0200
++++ gdb-7.2/gdb/remote-m32r-sdi.c 2010-10-12 18:29:24.000000000 +0200
+@@ -1377,7 +1377,7 @@ m32r_load (char *args, int from_tty)
+ might be to call normal_stop, except that the stack may not be valid,
+ and things would get horribly confused... */
+
+- clear_symtab_users ();
++ clear_symtab_users (0);
+
+ if (!nostart)
+ {
+Index: gdb-7.2/gdb/solib-som.c
+===================================================================
+--- gdb-7.2.orig/gdb/solib-som.c 2010-05-17 01:49:58.000000000 +0200
++++ gdb-7.2/gdb/solib-som.c 2010-10-12 18:29:24.000000000 +0200
+@@ -354,7 +354,7 @@ keep_going:
+ /* Make the breakpoint at "_start" a shared library event breakpoint. */
+ create_solib_event_breakpoint (target_gdbarch, anaddr);
+
+- clear_symtab_users ();
++ clear_symtab_users (0);
+ }
+
+ static void
+Index: gdb-7.2/gdb/symfile.c
+===================================================================
+--- gdb-7.2.orig/gdb/symfile.c 2010-10-12 18:27:57.000000000 +0200
++++ gdb-7.2/gdb/symfile.c 2010-10-12 18:29:24.000000000 +0200
+@@ -1036,7 +1036,7 @@ syms_from_objfile (struct objfile *objfi
+
+ /* Perform required actions after either reading in the initial
+ symbols for a new objfile, or mapping in the symbols from a reusable
+- objfile. */
++ objfile. ADD_FLAGS is a bitmask of enum symfile_add_flags. */
+
+ void
+ new_symfile_objfile (struct objfile *objfile, int add_flags)
+@@ -1049,7 +1049,7 @@ new_symfile_objfile (struct objfile *obj
+ /* OK, make it the "real" symbol file. */
+ symfile_objfile = objfile;
+
+- clear_symtab_users ();
++ clear_symtab_users (add_flags);
+ }
+ else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
+ {
+@@ -2527,7 +2527,7 @@ reread_symbols (void)
+ /* Notify objfiles that we've modified objfile sections. */
+ objfiles_changed ();
+
+- clear_symtab_users ();
++ clear_symtab_users (0);
+ /* At least one objfile has changed, so we can consider that
+ the executable we're debugging has changed too. */
+ observer_notify_executable_changed ();
+@@ -2745,10 +2745,10 @@ allocate_symtab (char *filename, struct
+
+
+ /* Reset all data structures in gdb which may contain references to symbol
+- table data. */
++ table data. ADD_FLAGS is a bitmask of enum symfile_add_flags. */
+
+ void
+-clear_symtab_users (void)
++clear_symtab_users (int add_flags)
+ {
+ /* Someday, we should do better than this, by only blowing away
+ the things that really need to be blown. */
+@@ -2758,7 +2758,8 @@ clear_symtab_users (void)
+ clear_current_source_symtab_and_line ();
+
+ clear_displays ();
+- breakpoint_re_set ();
++ if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
++ breakpoint_re_set ();
+ set_default_breakpoint (0, NULL, 0, 0, 0);
+ clear_pc_function_cache ();
+ observer_notify_new_objfile (NULL);
+@@ -2777,7 +2778,7 @@ clear_symtab_users (void)
+ static void
+ clear_symtab_users_cleanup (void *ignore)
+ {
+- clear_symtab_users ();
++ clear_symtab_users (0);
+ }
+
+ /* OVERLAYS:
+Index: gdb-7.2/gdb/symtab.h
+===================================================================
+--- gdb-7.2.orig/gdb/symtab.h 2010-10-12 18:27:56.000000000 +0200
++++ gdb-7.2/gdb/symtab.h 2010-10-12 18:29:24.000000000 +0200
+@@ -1170,7 +1170,7 @@ extern void skip_prologue_sal (struct sy
+
+ /* symfile.c */
+
+-extern void clear_symtab_users (void);
++extern void clear_symtab_users (int add_flags);
+
+ extern enum language deduce_language_from_filename (const char *);
+
+Index: gdb-7.2/gdb/testsuite/gdb.base/pie-execl.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.2/gdb/testsuite/gdb.base/pie-execl.c 2010-10-12 18:29:24.000000000 +0200
+@@ -0,0 +1,51 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++ Copyright 2010 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/>. */
++
++#include <stdio.h>
++#include <unistd.h>
++#include <assert.h>
++
++static void pie_execl_marker (void);
++
++int
++main (int argc, char **argv)
++{
++ setbuf (stdout, NULL);
++
++#if BIN == 1
++ if (argc == 2)
++ {
++ printf ("pie-execl: re-exec: %s\n", argv[1]);
++ execl (argv[1], argv[1], NULL);
++ assert (0);
++ }
++#endif
++
++ pie_execl_marker ();
++
++ return 0;
++}
++
++/* pie_execl_marker must be on a different address than in `pie-execl2.c'. */
++
++volatile int v;
++
++static void
++pie_execl_marker (void)
++{
++ v = 1;
++}
+Index: gdb-7.2/gdb/testsuite/gdb.base/pie-execl.exp
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.2/gdb/testsuite/gdb.base/pie-execl.exp 2010-10-12 18:29:24.000000000 +0200
+@@ -0,0 +1,94 @@
++# Copyright 2010 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/>.
++
++# The problem was due to amd64_skip_prologue attempting to access inferior
++# memory before the PIE (Position Independent Executable) gets relocated.
++
++if { ![istarget *-linux*]} {
++ continue
++}
++
++set testfile "pie-execl"
++set srcfile ${testfile}.c
++set executable1 ${testfile}1
++set executable2 ${testfile}2
++set binfile1 ${objdir}/${subdir}/${executable1}
++set binfile2 ${objdir}/${subdir}/${executable2}
++
++# Use conditional compilation according to `BIN' as GDB remembers the source
++# file name of the breakpoint.
++
++set opts [list debug {additional_flags=-fPIE -pie}]
++if {[build_executable ${testfile}.exp $executable1 $srcfile [concat $opts {additional_flags=-DBIN=1}]] == ""
++ || [build_executable ${testfile}.exp $executable2 $srcfile [concat $opts {additional_flags=-DBIN=2}]] == ""} {
++ return -1
++}
++
++clean_restart ${executable1}
++
++gdb_test_no_output "set args ${binfile2}"
++
++if ![runto_main] {
++ return -1
++}
++
++# Do not stop on `main' after re-exec.
++delete_breakpoints
++
++gdb_breakpoint "pie_execl_marker"
++gdb_test "info breakpoints" ".*" ""
++
++set addr1 ""
++set test "pie_execl_marker address first"
++gdb_test_multiple "p/x &pie_execl_marker" $test {
++ -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" {
++ set addr1 $expect_out(1,string)
++ pass $test
++ }
++}
++verbose -log "addr1 is $addr1"
++
++set test "continue"
++gdb_test_multiple $test $test {
++ -re "Error in re-setting breakpoint" {
++ fail $test
++ }
++ -re "Cannot access memory" {
++ fail $test
++ }
++ -re "pie-execl: re-exec.*executing new program.*\r\nBreakpoint \[0-9\]+,\[^\r\n\]* pie_execl_marker .*\r\n$gdb_prompt $" {
++ pass $test
++ }
++}
++
++gdb_test "info breakpoints" ".*" ""
++
++set addr2 ""
++set test "pie_execl_marker address second"
++gdb_test_multiple "p/x &pie_execl_marker" $test {
++ -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" {
++ set addr2 $expect_out(1,string)
++ pass $test
++ }
++}
++verbose -log "addr2 is $addr2"
++
++# Ensure we cannot get a false PASS and the inferior has really changed.
++set test "pie_execl_marker address has changed"
++if [string equal $addr1 $addr2] {
++ fail $test
++} else {
++ pass $test
++}
diff --git a/gdb-python-error-state.patch b/gdb-python-error-state.patch
new file mode 100644
index 0000000..d3df518
--- /dev/null
+++ b/gdb-python-error-state.patch
@@ -0,0 +1,592 @@
+http://sourceware.org/ml/gdb-patches/2010-10/msg00175.html
+Subject: Re: [patch] python: save/restore/fix error state
+
+On Fri, 08 Oct 2010 22:08:27 +0200, Doug Evans wrote:
+> The comment above this code says:
+>
+> /* Note: If an exception occurs python will print the traceback and
+> clear the error indicator. */
+>
+> ISTM that either this comment is wrong or the above patch is wrong, or
+> some combination thereof.
+
+This comment is right, Python has no bug there, other gdb/python/ code has
+bugs. That is some gdb/python/ code returned success value while still
+leaving the python exception set. Such case is undefined and unchecked by
+Python. Python error state does not follow the errno POSIX semantics
+ The setting of errno after a successful call to a function is
+ unspecified [...].
+as Python requires instead:
+ The Python error state after a successful call to a function must be
+ cleared.
+
+I have checked callers of these functions, as a closure on the callers of the
+top py-utils.c functions. That does not mean this Python error state handling
+verification is complete:
+ python_string_to_unicode unicode_to_encoded_string
+ unicode_to_encoded_python_string unicode_to_target_string
+ unicode_to_target_python_string python_string_to_target_string
+ python_string_to_target_python_string python_string_to_host_string
+ target_string_to_unicode gdbpy_obj_to_string gdbpy_exception_to_string
+ get_addr_from_python convert_value_from_python frapy_read_var
+ gdbpy_get_display_hint valpy_getitem FIXME set_parameter_value
+ compute_enum_values infpy_read_memory infpy_write_memory
+ infpy_search_memory valpy_new valpy_call valpy_binop valpy_richcompare
+ pretty_print_one_value set_attr parmpy_init
+
+Therefore I have removed the check after PyRun_SimpleFile.
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora14snapshot-linux-gnu.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2010-10-09 Jan Kratochvil <jan.kratochvil at redhat.com>
+
+ * python/py-breakpoint.c (bppy_set_condition): New comment.
+ * python/py-cmd.c (cmdpy_function): Call also gdbpy_print_stack for
+ failed PyUnicode_Decode.
+ (cmdpy_completer): Skip element for failed
+ python_string_to_host_string.
+ (cmdpy_init): Return -1 on failed python_string_to_host_string.
+ * python/py-frame.c (frapy_read_var): Extend the function comment.
+ * python/py-function.c (fnpy_init): Return -1 on failed
+ python_string_to_host_string.
+ * python/py-inferior.c (infpy_read_memory, infpy_write_memory): Extend
+ the function comment.
+ (infpy_search_memory): Extend the function comment. Remove the
+ PyErr_SetString call on already set error state.
+ * python/py-param.c (set_parameter_value): Extend the function
+ comment. Return -1 on failed python_string_to_host_string, twice.
+ (set_attr): Extend the function comment.
+ (compute_enum_values): Extend the function comment. New variable
+ back_to. Protect self->enumeration by BACK_TO cleanups. Return 0 on
+ failed python_string_to_host_string.
+ (get_doc_string): Call gdbpy_print_stack on failed
+ python_string_to_host_string.
+ (parmpy_init): Extend the function comment.
+ * python/py-prettyprint.c (pretty_print_one_value): Likewise.
+ (gdbpy_get_display_hint, print_children): Call gdbpy_print_stack on
+ failed python_string_to_host_string.
+ * python/py-value.c (valpy_new, valpy_getitem, valpy_call)
+ (valpy_binop, valpy_richcompare): Extend the function comment.
+ * python/python.c
+ (struct python_env) <error_type, error_value, error_traceback>: New
+ fields.
+ (restore_python_env): Handle PyErr_Occurred. Call PyErr_Restore.
+ (ensure_python_env): Call PyErr_Fetch.
+ * varobj.c (update_dynamic_varobj_children): Call gdbpy_print_stack on
+ failed convert_value_from_python.
+ (value_get_print_value): Call gdbpy_print_stack on failed
+ python_string_to_target_python_string.
+
+gdb/testsuite/
+2010-10-09 Jan Kratochvil <jan.kratochvil at redhat.com>
+
+ * gdb.python/py-error.exp: New file.
+ * gdb.python/py-error.py: New file.
+
+Index: gdb-7.2/gdb/python/py-breakpoint.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-breakpoint.c 2010-10-12 18:27:54.000000000 +0200
++++ gdb-7.2/gdb/python/py-breakpoint.c 2010-10-12 18:28:58.000000000 +0200
+@@ -420,6 +420,9 @@ bppy_get_condition (PyObject *self, void
+ return PyString_Decode (str, strlen (str), host_charset (), NULL);
+ }
+
++/* Returns 0 on success. Returns -1 on error, with a python exception set.
++ */
++
+ static int
+ bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
+ {
+Index: gdb-7.2/gdb/python/py-cmd.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-cmd.c 2010-10-12 18:27:54.000000000 +0200
++++ gdb-7.2/gdb/python/py-cmd.c 2010-10-12 18:28:58.000000000 +0200
+@@ -138,7 +138,10 @@ cmdpy_function (struct cmd_list_element
+ args = "";
+ argobj = PyUnicode_Decode (args, strlen (args), host_charset (), NULL);
+ if (! argobj)
+- error (_("Could not convert arguments to Python string."));
++ {
++ gdbpy_print_stack ();
++ error (_("Could not convert arguments to Python string."));
++ }
+
+ ttyobj = from_tty ? Py_True : Py_False;
+ Py_INCREF (ttyobj);
+@@ -255,6 +258,12 @@ cmdpy_completer (struct cmd_list_element
+ continue;
+ }
+ result[out] = python_string_to_host_string (elt);
++ if (result[out] == NULL)
++ {
++ /* Skip problem elements. */
++ PyErr_Clear ();
++ continue;
++ }
+ ++out;
+ }
+ result[out] = NULL;
+@@ -465,7 +474,15 @@ cmdpy_init (PyObject *self, PyObject *ar
+ PyObject *ds_obj = PyObject_GetAttr (self, gdbpy_doc_cst);
+
+ if (ds_obj && gdbpy_is_string (ds_obj))
+- docstring = python_string_to_host_string (ds_obj);
++ {
++ docstring = python_string_to_host_string (ds_obj);
++ if (docstring == NULL)
++ {
++ xfree (cmd_name);
++ xfree (pfx_name);
++ return -1;
++ }
++ }
+ }
+ if (! docstring)
+ docstring = xstrdup (_("This command is not documented."));
+Index: gdb-7.2/gdb/python/py-frame.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-frame.c 2010-06-28 23:16:03.000000000 +0200
++++ gdb-7.2/gdb/python/py-frame.c 2010-10-12 18:28:58.000000000 +0200
+@@ -385,7 +385,8 @@ frapy_find_sal (PyObject *self, PyObject
+ start the search from that block, otherwise search from the frame's
+ current block (determined by examining the resume address of the
+ frame). The variable argument must be a string or an instance of a
+- gdb.Symbol. The block argument must be an instance of gdb.Block. */
++ gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
++ NULL on error, with a python exception set. */
+ static PyObject *
+ frapy_read_var (PyObject *self, PyObject *args)
+ {
+Index: gdb-7.2/gdb/python/py-function.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-function.c 2010-05-17 23:23:25.000000000 +0200
++++ gdb-7.2/gdb/python/py-function.c 2010-10-12 18:28:58.000000000 +0200
+@@ -113,7 +113,14 @@ fnpy_init (PyObject *self, PyObject *arg
+ {
+ PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__");
+ if (ds_obj && gdbpy_is_string (ds_obj))
+- docstring = python_string_to_host_string (ds_obj);
++ {
++ docstring = python_string_to_host_string (ds_obj);
++ if (docstring == NULL)
++ {
++ Py_DECREF (self);
++ return -1;
++ }
++ }
+ }
+ if (! docstring)
+ docstring = xstrdup (_("This function is not documented."));
+Index: gdb-7.2/gdb/python/py-inferior.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-inferior.c 2010-06-28 23:16:03.000000000 +0200
++++ gdb-7.2/gdb/python/py-inferior.c 2010-10-12 18:28:58.000000000 +0200
+@@ -293,7 +293,8 @@ gdbpy_inferiors (PyObject *unused, PyObj
+
+ /* Implementation of gdb.read_memory (address, length).
+ Returns a Python buffer object with LENGTH bytes of the inferior's
+- memory at ADDRESS. Both arguments are integers. */
++ memory at ADDRESS. Both arguments are integers. Returns NULL on error,
++ with a python exception set. */
+ static PyObject *
+ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
+ {
+@@ -361,7 +362,8 @@ infpy_read_memory (PyObject *self, PyObj
+ Writes the contents of BUFFER (a Python object supporting the read
+ buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
+ bytes from BUFFER, or its entire contents if the argument is not
+- provided. The function returns nothing. */
++ provided. The function returns nothing. Returns NULL on error, with
++ a python exception set. */
+ static PyObject *
+ infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
+ {
+@@ -473,7 +475,8 @@ get_char_buffer (PyObject *self, Py_ssiz
+ search from ADDRESS. PATTERN is the pattern to search for (and
+ must be a Python object supporting the buffer protocol).
+ Returns a Python Long object holding the address where the pattern
+- was located, or if the pattern was not found, returns None. */
++ was located, or if the pattern was not found, returns None. Returns NULL
++ on error, with a python exception set. */
+ static PyObject *
+ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
+ {
+@@ -511,12 +514,7 @@ infpy_search_memory (PyObject *self, PyO
+ }
+ }
+ else
+- {
+- PyErr_SetString (PyExc_RuntimeError,
+- _("Cannot get search address/range from Python."));
+-
+- return NULL;
+- }
++ return NULL;
+
+ if (!PyObject_CheckReadBuffer (pattern))
+ {
+Index: gdb-7.2/gdb/python/py-param.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-param.c 2010-05-17 23:23:25.000000000 +0200
++++ gdb-7.2/gdb/python/py-param.c 2010-10-12 18:28:58.000000000 +0200
+@@ -110,8 +110,8 @@ get_attr (PyObject *obj, PyObject *attr_
+ return PyObject_GenericGetAttr (obj, attr_name);
+ }
+
+-/* Set a parameter value from a Python value. Return 0 on success, -1
+- on failure. */
++/* Set a parameter value from a Python value. Return 0 on success. Returns
++ -1 on error, with a python exception set. */
+ static int
+ set_parameter_value (parmpy_object *self, PyObject *value)
+ {
+@@ -142,7 +142,11 @@ set_parameter_value (parmpy_object *self
+ self->value.stringval = NULL;
+ }
+ else
+- self->value.stringval = python_string_to_host_string (value);
++ {
++ self->value.stringval = python_string_to_host_string (value);
++ if (self->value.stringval == NULL)
++ return -1;
++ }
+ break;
+
+ case var_enum:
+@@ -158,6 +162,8 @@ set_parameter_value (parmpy_object *self
+ }
+
+ str = python_string_to_host_string (value);
++ if (str == NULL)
++ return -1;
+ for (i = 0; self->enumeration[i]; ++i)
+ if (! strcmp (self->enumeration[i], str))
+ break;
+@@ -258,7 +264,7 @@ set_parameter_value (parmpy_object *self
+ return 0;
+ }
+
+-/* Set an attribute. */
++/* Set an attribute. Returns -1 on error, with a python exception set. */
+ static int
+ set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
+ {
+@@ -358,12 +364,13 @@ add_setshow_generic (int parmclass, enum
+ }
+ }
+
+-/* A helper which computes enum values. Returns 1 on success, 0 on
+- error. */
++/* A helper which computes enum values. Returns 1 on success. Returns 0 on
++ error, with a python exception set. */
+ static int
+ compute_enum_values (parmpy_object *self, PyObject *enum_values)
+ {
+ Py_ssize_t size, i;
++ struct cleanup *back_to;
+
+ if (! enum_values)
+ {
+@@ -390,6 +397,7 @@ compute_enum_values (parmpy_object *self
+ }
+
+ self->enumeration = xmalloc ((size + 1) * sizeof (char *));
++ back_to = make_cleanup (free_current_contents, &self->enumeration);
+ memset (self->enumeration, 0, (size + 1) * sizeof (char *));
+
+ for (i = 0; i < size; ++i)
+@@ -397,16 +405,27 @@ compute_enum_values (parmpy_object *self
+ PyObject *item = PySequence_GetItem (enum_values, i);
+
+ if (! item)
+- return 0;
++ {
++ do_cleanups (back_to);
++ return 0;
++ }
+ if (! gdbpy_is_string (item))
+ {
++ do_cleanups (back_to);
+ PyErr_SetString (PyExc_RuntimeError,
+ _("The enumeration item not a string."));
+ return 0;
+ }
+ self->enumeration[i] = python_string_to_host_string (item);
++ if (self->enumeration[i] == NULL)
++ {
++ do_cleanups (back_to);
++ return 0;
++ }
++ make_cleanup (xfree, (char *) self->enumeration[i]);
+ }
+
++ discard_cleanups (back_to);
+ return 1;
+ }
+
+@@ -422,7 +441,11 @@ get_doc_string (PyObject *object, PyObje
+ PyObject *ds_obj = PyObject_GetAttr (object, attr);
+
+ if (ds_obj && gdbpy_is_string (ds_obj))
+- result = python_string_to_host_string (ds_obj);
++ {
++ result = python_string_to_host_string (ds_obj);
++ if (result == NULL)
++ gdbpy_print_stack ();
++ }
+ }
+ if (! result)
+ result = xstrdup (_("This command is not documented."));
+@@ -449,8 +472,9 @@ get_doc_string (PyObject *object, PyObje
+
+ The documentation for the parameter is taken from the doc string
+ for the python class.
+-
+-*/
++
++ Returns -1 on error, with a python exception set. */
++
+ static int
+ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+ {
+Index: gdb-7.2/gdb/python/py-prettyprint.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-prettyprint.c 2010-10-12 18:27:57.000000000 +0200
++++ gdb-7.2/gdb/python/py-prettyprint.c 2010-10-12 18:28:58.000000000 +0200
+@@ -185,8 +185,8 @@ find_pretty_printer (PyObject *value)
+ is returned. If the function returns Py_NONE that means the pretty
+ printer returned the Python None as a value. Otherwise, if the
+ function returns a value, *OUT_VALUE is set to the value, and NULL
+- is returned. On error, *OUT_VALUE is set to NULL, and NULL is
+- returned. */
++ is returned. On error, *OUT_VALUE is set to NULL, NULL is
++ returned, with a python exception set. */
+
+ static PyObject *
+ pretty_print_one_value (PyObject *printer, struct value **out_value)
+@@ -232,7 +232,11 @@ gdbpy_get_display_hint (PyObject *printe
+ if (hint)
+ {
+ if (gdbpy_is_string (hint))
+- result = python_string_to_host_string (hint);
++ {
++ result = python_string_to_host_string (hint);
++ if (result == NULL)
++ gdbpy_print_stack ();
++ }
+ Py_DECREF (hint);
+ }
+ else
+@@ -574,7 +578,10 @@ print_children (PyObject *printer, const
+ else
+ {
+ output = python_string_to_host_string (py_v);
+- fputs_filtered (output, stream);
++ if (!output)
++ gdbpy_print_stack ();
++ else
++ fputs_filtered (output, stream);
+ xfree (output);
+ }
+ }
+Index: gdb-7.2/gdb/python/py-value.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/py-value.c 2010-10-12 18:27:54.000000000 +0200
++++ gdb-7.2/gdb/python/py-value.c 2010-10-12 18:28:58.000000000 +0200
+@@ -114,7 +114,8 @@ note_value (value_object *value_obj)
+ values_in_python = value_obj;
+ }
+
+-/* Called when a new gdb.Value object needs to be allocated. */
++/* Called when a new gdb.Value object needs to be allocated. Returns NULL on
++ error, with a python exception set. */
+ static PyObject *
+ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
+ {
+@@ -334,7 +335,7 @@ valpy_length (PyObject *self)
+ }
+
+ /* Given string name of an element inside structure, return its value
+- object. */
++ object. Returns NULL on error, with a python exception set. */
+ static PyObject *
+ valpy_getitem (PyObject *self, PyObject *key)
+ {
+@@ -468,7 +469,8 @@ enum valpy_opcode
+ ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+
+ /* Returns a value object which is the result of applying the operation
+- specified by OPCODE to the given arguments. */
++ specified by OPCODE to the given arguments. Returns NULL on error, with
++ a python exception set. */
+ static PyObject *
+ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
+ {
+@@ -723,7 +725,8 @@ valpy_xor (PyObject *self, PyObject *oth
+ return valpy_binop (VALPY_BITXOR, self, other);
+ }
+
+-/* Implements comparison operations for value objects. */
++/* Implements comparison operations for value objects. Returns NULL on error,
++ with a python exception set. */
+ static PyObject *
+ valpy_richcompare (PyObject *self, PyObject *other, int op)
+ {
+Index: gdb-7.2/gdb/python/python.c
+===================================================================
+--- gdb-7.2.orig/gdb/python/python.c 2010-10-12 18:27:54.000000000 +0200
++++ gdb-7.2/gdb/python/python.c 2010-10-12 18:28:58.000000000 +0200
+@@ -82,6 +82,7 @@ struct python_env
+ PyGILState_STATE state;
+ struct gdbarch *gdbarch;
+ const struct language_defn *language;
++ PyObject *error_type, *error_value, *error_traceback;
+ };
+
+ static void
+@@ -89,6 +90,16 @@ restore_python_env (void *p)
+ {
+ struct python_env *env = (struct python_env *)p;
+
++ /* Leftover Python error is forbidden by Python Exception Handling. */
++ if (PyErr_Occurred ())
++ {
++ /* This order is similar to the one calling error afterwards. */
++ gdbpy_print_stack ();
++ warning (_("internal error: Unhandled Python exception"));
++ }
++
++ PyErr_Restore (env->error_type, env->error_value, env->error_traceback);
++
+ PyGILState_Release (env->state);
+ python_gdbarch = env->gdbarch;
+ python_language = env->language;
+@@ -111,6 +122,9 @@ ensure_python_env (struct gdbarch *gdbar
+ python_gdbarch = gdbarch;
+ python_language = language;
+
++ /* Save it and ensure ! PyErr_Occurred () afterwards. */
++ PyErr_Fetch (&env->error_type, &env->error_value, &env->error_traceback);
++
+ return make_cleanup (restore_python_env, env);
+ }
+
+Index: gdb-7.2/gdb/testsuite/gdb.python/py-error.exp
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.2/gdb/testsuite/gdb.python/py-error.exp 2010-10-12 18:28:58.000000000 +0200
+@@ -0,0 +1,56 @@
++# Copyright (C) 2010 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/>.
++
++# Test error while loading *-gdb.py. IBM1047 is chosen as possibly supported
++# by glibc but unsupported by Python
++
++set testfile "py-error"
++
++load_lib gdb-python.exp
++
++# Start with a fresh gdb.
++gdb_exit
++gdb_start
++
++# Skip all tests if Python scripting is not enabled.
++if { [skip_python_tests] } { continue }
++
++set charset "IBM1047"
++
++set test2 "main reached"
++
++set test "set host-charset $charset"
++set test_regex [string_to_regexp $test]
++gdb_test_multiple $test $test {
++ -re "^$test_regex\r\n$gdb_prompt $" {
++ pass $test
++ }
++ -re "^$test_regex\r\nUndefined item: \"$charset\"\\.\r\n$gdb_prompt $" {
++ xfail $test
++ untested $test2
++ set test2 ""
++ }
++}
++
++if {$test2 == ""} {
++ return 0
++}
++
++set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
++
++# argc=LookupError: unknown encoding: IBM1047
++gdb_test "source $remote_python_file" "Traceback.*ClassName.*\r\nLookupError: unknown encoding: $charset" $test2
++
++gdb_test "p 1" " = 1" "no delayed error"
+Index: gdb-7.2/gdb/testsuite/gdb.python/py-error.py
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.2/gdb/testsuite/gdb.python/py-error.py 2010-10-12 18:28:58.000000000 +0200
+@@ -0,0 +1,25 @@
++# Copyright (C) 2010 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/>.
++
++import gdb
++
++class ClassName(gdb.Command):
++ 'a'
++ def __init__(self):
++ gdb.Command.__init__ (self, "ClassName", gdb.COMMAND_DATA, prefix=True)
++ def invoke(self, args, from_tty):
++ print
++
++ClassName()
+Index: gdb-7.2/gdb/varobj.c
+===================================================================
+--- gdb-7.2.orig/gdb/varobj.c 2010-10-12 18:27:54.000000000 +0200
++++ gdb-7.2/gdb/varobj.c 2010-10-12 18:28:58.000000000 +0200
+@@ -1054,6 +1054,8 @@ update_dynamic_varobj_children (struct v
+ error (_("Invalid item from the child list"));
+
+ v = convert_value_from_python (py_v);
++ if (v == NULL)
++ gdbpy_print_stack ();
+ install_dynamic_child (var, can_mention ? changed : NULL,
+ can_mention ? new : NULL,
+ can_mention ? unchanged : NULL,
+@@ -2542,6 +2544,8 @@ value_get_print_value (struct value *val
+ type = builtin_type (gdbarch)->builtin_char;
+ Py_DECREF (py_str);
+ }
++ else
++ gdbpy_print_stack ();
+ }
+ Py_DECREF (output);
+ }
diff --git a/gdb.spec b/gdb.spec
index 845f70d..31a3b7f 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -27,7 +27,7 @@ Version: 7.2
# 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: 20%{?_with_upstream:.upstream}%{dist}
+Release: 21%{?_with_upstream:.upstream}%{dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and GFDL and BSD and Public Domain
Group: Development/Debuggers
@@ -459,6 +459,12 @@ Patch515: gdb-gdbindex-v2-to-v3.patch
# [ifunc] Fix crash on deleting watchpoint of an autovariable (BZ 637770).
Patch513: gdb-bz637770-ifunc-watchpoint-delete.patch
+# Fix python stale error state, also fix its save/restore (BZ 639089).
+Patch516: gdb-python-error-state.patch
+
+# Fix inferior exec of new PIE x86_64 (BZ 638979).
+Patch517: gdb-exec-pie-amd64.patch
+
BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa}
Requires: readline%{?_isa}
BuildRequires: readline-devel%{?_isa}
@@ -727,6 +733,8 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
%patch512 -p1
%patch515 -p1
%patch513 -p1
+%patch516 -p1
+%patch517 -p1
%patch393 -p1
%patch335 -p1
@@ -1097,6 +1105,10 @@ fi
%endif
%changelog
+* Tue Oct 12 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.2-21.fc14
+- Fix python stale error state, also fix its save/restore (BZ 639089).
+- Fix inferior exec of new PIE x86_64 (BZ 638979).
+
* Tue Oct 12 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.2-20.fc14
- Fixup Release for 20.fc14.
More information about the scm-commits
mailing list