[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