[3/4] Change thread_to_thread_object to return a new reference

Message ID 20180913053007.11780-4-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey Sept. 13, 2018, 5:30 a.m. UTC
  This changes thread_to_thread_object to return a new reference and
fixes up all the callers.

2018-09-12  Tom Tromey  <tom@tromey.com>

	* python/python-internal.h (thread_to_thread_object): Change
	return type.
	* python/py-inferior.c (thread_to_thread_object): Return a new
	reference.
	(infpy_thread_from_thread_handle): Update.
	* python/py-infthread.c (gdbpy_selected_thread): Update.
	* python/py-stopevent.c (create_stop_event_object): Update.
	* python/py-threadevent.c (py_get_event_thread): Return a new
	reference.
	(py_get_event_thread): Update.
	* python/py-event.h (py_get_event_thread): Change return type.
	* python/py-continueevent.c (create_continue_event_object):
	Update.
---
 gdb/ChangeLog                 | 16 ++++++++++++
 gdb/python/py-continueevent.c |  5 ++--
 gdb/python/py-event.h         |  5 ++--
 gdb/python/py-inferior.c      | 46 ++++++++++++++++-------------------
 gdb/python/py-infthread.c     | 10 +-------
 gdb/python/py-stopevent.c     |  4 +--
 gdb/python/py-threadevent.c   |  8 +++---
 gdb/python/python-internal.h  |  3 +--
 8 files changed, 50 insertions(+), 47 deletions(-)
  

Comments

Simon Marchi Sept. 16, 2018, 2:11 a.m. UTC | #1
I have some comments about style, correctness-wise is looks good to me.

On 2018-09-13 1:30 a.m., Tom Tromey wrote:
> diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
> index 1cf37296973..bf8ac75a316 100644
> --- a/gdb/python/py-inferior.c
> +++ b/gdb/python/py-inferior.c
> @@ -306,7 +306,7 @@ find_inferior_object (int pid)
>    return NULL;
>  }
>  
> -thread_object *
> +gdbpy_ref<>
>  thread_to_thread_object (thread_info *thr)
>  {
>    gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (thr->inf));
> @@ -317,7 +317,7 @@ thread_to_thread_object (thread_info *thr)
>         thread != NULL;
>         thread = thread->next)
>      if (thread->thread_obj->thread == thr)
> -      return thread->thread_obj;
> +      return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj);
>  
>    return NULL;
>  }
> @@ -817,7 +817,7 @@ infpy_is_valid (PyObject *self, PyObject *args)
>  PyObject *
>  infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
>  {
> -  PyObject *handle_obj, *result;
> +  PyObject *handle_obj;
>    inferior_object *inf_obj = (inferior_object *) self;
>    static const char *keywords[] = { "thread_handle", NULL };
>  
> @@ -826,8 +826,6 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
>    if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
>      return NULL;
>  
> -  result = Py_None;
> -
>    if (!gdbpy_is_value_object (handle_obj))
>      {
>        PyErr_SetString (PyExc_TypeError,
> @@ -835,29 +833,27 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
>  
>        return NULL;
>      }
> -  else
> +
> +  gdbpy_ref<> result;
> +  TRY
> +    {
> +      struct thread_info *thread_info;
> +      struct value *val = value_object_to_value (handle_obj);
> +
> +      thread_info = find_thread_by_handle (val, inf_obj->inferior);
> +      if (thread_info != NULL)
> +	result = thread_to_thread_object (thread_info);
> +    }
> +  CATCH (except, RETURN_MASK_ALL)
>      {
> -      TRY
> -	{
> -	  struct thread_info *thread_info;
> -	  struct value *val = value_object_to_value (handle_obj);
> -
> -	  thread_info = find_thread_by_handle (val, inf_obj->inferior);
> -	  if (thread_info != NULL)
> -	    {
> -	      result = (PyObject *) thread_to_thread_object (thread_info);
> -	      if (result != NULL)
> -		Py_INCREF (result);
> -	    }
> -	}
> -      CATCH (except, RETURN_MASK_ALL)
> -	{
> -	  GDB_PY_HANDLE_EXCEPTION (except);
> -	}
> -      END_CATCH
> +      GDB_PY_HANDLE_EXCEPTION (except);
>      }
> +  END_CATCH
>  
> -  return result;
> +  if (result == NULL)
> +    result = gdbpy_ref<>::new_reference (Py_None);

I would suggest using Py_RETURN_NONE, which we already use at many places.

Instead of setting that result variable, is there something preventing you
from returning directly above, like this?

      if (thread_info != NULL)
	return thread_to_thread_object (thread_info).release ();

The bottom line could just be unconditionally Py_RETURN_NONE.

> +
> +  return result.release ();
>  }
>  
>  
> diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
> index 36ae71b6358..4b2705a0af6 100644
> --- a/gdb/python/py-infthread.c
> +++ b/gdb/python/py-infthread.c
> @@ -284,15 +284,7 @@ PyObject *
>  gdbpy_selected_thread (PyObject *self, PyObject *args)
>  {
>    if (inferior_ptid != null_ptid)
> -    {
> -      PyObject *thread_obj
> -	= (PyObject *) thread_to_thread_object (inferior_thread ());
> -      if (thread_obj != NULL)
> -	{
> -	  Py_INCREF (thread_obj);
> -	  return thread_obj;
> -	}
> -    }
> +    return thread_to_thread_object (inferior_thread ()).release ();

I know it's logically not supposed to happen, but here it's possible for
thread_to_thread_object to return NULL.  Returning NULL to Python is the
way to have it throw an exception, I believe, is that what you want to do
here?  The previous code would return None in that case.

>  
>    Py_RETURN_NONE;
>  }
> diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c
> index f6bd207f3b8..cbdf7b7e7e0 100644
> --- a/gdb/python/py-stopevent.c
> +++ b/gdb/python/py-stopevent.c
> @@ -23,8 +23,8 @@
>  gdbpy_ref<>
>  create_stop_event_object (PyTypeObject *py_type)
>  {
> -  return create_thread_event_object (py_type,
> -				     py_get_event_thread (inferior_ptid));
> +  gdbpy_ref<> thread = py_get_event_thread (inferior_ptid);
> +  return create_thread_event_object (py_type, thread.get ());
>  }
>  
>  /* Callback observers when a stop event occurs.  This function will create a
> diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c
> index 4f822b4ae09..13af1c840ba 100644
> --- a/gdb/python/py-threadevent.c
> +++ b/gdb/python/py-threadevent.c
> @@ -22,19 +22,19 @@
>  
>  /* See py-event.h.  */
>  
> -PyObject *
> +gdbpy_ref<>
>  py_get_event_thread (ptid_t ptid)
>  {
> -  PyObject *pythread = nullptr;
> +  gdbpy_ref<> pythread;
>  
>    if (non_stop)
>      {
>        thread_info *thread = find_thread_ptid (ptid);
>        if (thread != nullptr)
> -	pythread = (PyObject *) thread_to_thread_object (thread);
> +	pythread = thread_to_thread_object (thread);
>      }
>    else
> -    pythread = Py_None;
> +    pythread = gdbpy_ref<>::new_reference (Py_None);

Again, I would suggest Py_RETURN_NONE.

I would also propose moving the code below in the if, to show that it only
really applies to the non-stop case (if I understand the code correctly).

>  
>    if (pythread == nullptr)
>      {

Simon
  
Tom Tromey Sept. 16, 2018, 1:31 p.m. UTC | #2
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

Simon> I have some comments about style, correctness-wise is looks good to me.

Oops, I missed this note and pushed the patch in.

I will write a new patch to address the comments a bit later.
Sorry about that.

Tom
  

Patch

diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c
index 759b4831366..9708c0d4059 100644
--- a/gdb/python/py-continueevent.c
+++ b/gdb/python/py-continueevent.c
@@ -32,12 +32,13 @@ 
 static gdbpy_ref<>
 create_continue_event_object (ptid_t ptid)
 {
-  PyObject *py_thr = py_get_event_thread (ptid);
+  gdbpy_ref<> py_thr = py_get_event_thread (ptid);
 
   if (py_thr == nullptr)
     return nullptr;
 
-  return create_thread_event_object (&continue_event_object_type, py_thr);
+  return create_thread_event_object (&continue_event_object_type,
+				     py_thr.get ());
 }
 
 /* Callback function which notifies observers when a continue event occurs.
diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h
index 56003e8785f..96be83b44c5 100644
--- a/gdb/python/py-event.h
+++ b/gdb/python/py-event.h
@@ -68,9 +68,8 @@  extern gdbpy_ref<> create_event_object (PyTypeObject *py_type);
    running in non-stop mode then the event is thread specific, otherwise
    it is process wide.
    This function returns the currently stopped thread in non-stop mode and
-   Py_None otherwise.  In each case it returns a borrowed reference.  */
-extern PyObject *py_get_event_thread (ptid_t ptid)
-  CPYCHECKER_RETURNS_BORROWED_REF;
+   Py_None otherwise.  */
+extern gdbpy_ref<> py_get_event_thread (ptid_t ptid);
 
 extern gdbpy_ref<> create_thread_event_object (PyTypeObject *py_type,
 					       PyObject *thread);
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 1cf37296973..bf8ac75a316 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -306,7 +306,7 @@  find_inferior_object (int pid)
   return NULL;
 }
 
-thread_object *
+gdbpy_ref<>
 thread_to_thread_object (thread_info *thr)
 {
   gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (thr->inf));
@@ -317,7 +317,7 @@  thread_to_thread_object (thread_info *thr)
        thread != NULL;
        thread = thread->next)
     if (thread->thread_obj->thread == thr)
-      return thread->thread_obj;
+      return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj);
 
   return NULL;
 }
@@ -817,7 +817,7 @@  infpy_is_valid (PyObject *self, PyObject *args)
 PyObject *
 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
 {
-  PyObject *handle_obj, *result;
+  PyObject *handle_obj;
   inferior_object *inf_obj = (inferior_object *) self;
   static const char *keywords[] = { "thread_handle", NULL };
 
@@ -826,8 +826,6 @@  infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
     return NULL;
 
-  result = Py_None;
-
   if (!gdbpy_is_value_object (handle_obj))
     {
       PyErr_SetString (PyExc_TypeError,
@@ -835,29 +833,27 @@  infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
 
       return NULL;
     }
-  else
+
+  gdbpy_ref<> result;
+  TRY
+    {
+      struct thread_info *thread_info;
+      struct value *val = value_object_to_value (handle_obj);
+
+      thread_info = find_thread_by_handle (val, inf_obj->inferior);
+      if (thread_info != NULL)
+	result = thread_to_thread_object (thread_info);
+    }
+  CATCH (except, RETURN_MASK_ALL)
     {
-      TRY
-	{
-	  struct thread_info *thread_info;
-	  struct value *val = value_object_to_value (handle_obj);
-
-	  thread_info = find_thread_by_handle (val, inf_obj->inferior);
-	  if (thread_info != NULL)
-	    {
-	      result = (PyObject *) thread_to_thread_object (thread_info);
-	      if (result != NULL)
-		Py_INCREF (result);
-	    }
-	}
-      CATCH (except, RETURN_MASK_ALL)
-	{
-	  GDB_PY_HANDLE_EXCEPTION (except);
-	}
-      END_CATCH
+      GDB_PY_HANDLE_EXCEPTION (except);
     }
+  END_CATCH
 
-  return result;
+  if (result == NULL)
+    result = gdbpy_ref<>::new_reference (Py_None);
+
+  return result.release ();
 }
 
 
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 36ae71b6358..4b2705a0af6 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -284,15 +284,7 @@  PyObject *
 gdbpy_selected_thread (PyObject *self, PyObject *args)
 {
   if (inferior_ptid != null_ptid)
-    {
-      PyObject *thread_obj
-	= (PyObject *) thread_to_thread_object (inferior_thread ());
-      if (thread_obj != NULL)
-	{
-	  Py_INCREF (thread_obj);
-	  return thread_obj;
-	}
-    }
+    return thread_to_thread_object (inferior_thread ()).release ();
 
   Py_RETURN_NONE;
 }
diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c
index f6bd207f3b8..cbdf7b7e7e0 100644
--- a/gdb/python/py-stopevent.c
+++ b/gdb/python/py-stopevent.c
@@ -23,8 +23,8 @@ 
 gdbpy_ref<>
 create_stop_event_object (PyTypeObject *py_type)
 {
-  return create_thread_event_object (py_type,
-				     py_get_event_thread (inferior_ptid));
+  gdbpy_ref<> thread = py_get_event_thread (inferior_ptid);
+  return create_thread_event_object (py_type, thread.get ());
 }
 
 /* Callback observers when a stop event occurs.  This function will create a
diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c
index 4f822b4ae09..13af1c840ba 100644
--- a/gdb/python/py-threadevent.c
+++ b/gdb/python/py-threadevent.c
@@ -22,19 +22,19 @@ 
 
 /* See py-event.h.  */
 
-PyObject *
+gdbpy_ref<>
 py_get_event_thread (ptid_t ptid)
 {
-  PyObject *pythread = nullptr;
+  gdbpy_ref<> pythread;
 
   if (non_stop)
     {
       thread_info *thread = find_thread_ptid (ptid);
       if (thread != nullptr)
-	pythread = (PyObject *) thread_to_thread_object (thread);
+	pythread = thread_to_thread_object (thread);
     }
   else
-    pythread = Py_None;
+    pythread = gdbpy_ref<>::new_reference (Py_None);
 
   if (pythread == nullptr)
     {
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index cbba3ff8ef6..dc8d7cdd32a 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -533,8 +533,7 @@  PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);
 PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch);
 
 thread_object *create_thread_object (struct thread_info *tp);
-thread_object *thread_to_thread_object (thread_info *thr)
-  CPYCHECKER_RETURNS_BORROWED_REF;
+gdbpy_ref<> thread_to_thread_object (thread_info *thr);;
 inferior_object *inferior_to_inferior_object (inferior *inf);
 
 const struct block *block_object_to_block (PyObject *obj);