[5/8] gdbserver/linux-x86: make is_64bit_tdesc accept thread as a parameter

Message ID 20221117194241.1776125-6-simon.marchi@efficios.com
State New
Headers
Series Fix some commit_resumed_state assertion failures (PR 28275) |

Commit Message

Simon Marchi Nov. 17, 2022, 7:42 p.m. UTC
  ps_get_thread_area receives as a parameter the lwpid it must work on.
It then calls is_64bit_tdesc, which uses the current_thread as the
thread to work on.  However, it is not said that both are the same.

This became a problem when working in a following patch that pmakes
find_one_thread switch to a process but to no thread (current_thread ==
nullptr).  When libthread_db needed to get the thread area,
is_64bit_tdesc would try to get the regcache of a nullptr thread.

Fix that by making is_64bit_tdesc accept the thread to work on as a
parameter.  Find the right thread from the context, when possible (when
we know the lwpid to work on).  Otherwise, pass "current_thread", to
retain the existing behavior.

Change-Id: I44394d6be92392fa28de71982fd04517ce8a3007
---
 gdbserver/linux-x86-low.cc | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)
  

Comments

Andrew Burgess Nov. 18, 2022, 11:32 a.m. UTC | #1
Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

> ps_get_thread_area receives as a parameter the lwpid it must work on.
> It then calls is_64bit_tdesc, which uses the current_thread as the
> thread to work on.  However, it is not said that both are the same.
>
> This became a problem when working in a following patch that pmakes

s/pmakes/makes/

> find_one_thread switch to a process but to no thread (current_thread ==
> nullptr).  When libthread_db needed to get the thread area,
> is_64bit_tdesc would try to get the regcache of a nullptr thread.
>
> Fix that by making is_64bit_tdesc accept the thread to work on as a
> parameter.  Find the right thread from the context, when possible (when
> we know the lwpid to work on).  Otherwise, pass "current_thread", to
> retain the existing behavior.
>
> Change-Id: I44394d6be92392fa28de71982fd04517ce8a3007
> ---
>  gdbserver/linux-x86-low.cc | 27 +++++++++++++++------------
>  1 file changed, 15 insertions(+), 12 deletions(-)
>
> diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
> index d2b55f6f0d2..c98a7a461fe 100644
> --- a/gdbserver/linux-x86-low.cc
> +++ b/gdbserver/linux-x86-low.cc
> @@ -275,9 +275,9 @@ static /*const*/ int i386_regmap[] =
>     per the tdesc.  */
>  
>  static int
> -is_64bit_tdesc (void)
> +is_64bit_tdesc (thread_info *thread)

I think the comment for this function needs updating, the reference to
"current inferior" probably needs to be replaced with THREAD.

With those changes, LGTM.

Reviewed-By: Andrew Burgess <aburgess@redhat.com>

Thanks,
Andrew


>  {
> -  struct regcache *regcache = get_thread_regcache (current_thread, 0);
> +  struct regcache *regcache = get_thread_regcache (thread, 0);
>  
>    return register_size (regcache->tdesc, 0) == 8;
>  }
> @@ -292,7 +292,9 @@ ps_get_thread_area (struct ps_prochandle *ph,
>  		    lwpid_t lwpid, int idx, void **base)
>  {
>  #ifdef __x86_64__
> -  int use_64bit = is_64bit_tdesc ();
> +  lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
> +  gdb_assert (lwp != nullptr);
> +  int use_64bit = is_64bit_tdesc (get_lwp_thread (lwp));
>  
>    if (use_64bit)
>      {
> @@ -335,7 +337,9 @@ int
>  x86_target::low_get_thread_area (int lwpid, CORE_ADDR *addr)
>  {
>  #ifdef __x86_64__
> -  int use_64bit = is_64bit_tdesc ();
> +  lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
> +  gdb_assert (lwp != nullptr);
> +  int use_64bit = is_64bit_tdesc (get_lwp_thread (lwp));
>  
>    if (use_64bit)
>      {
> @@ -351,7 +355,6 @@ x86_target::low_get_thread_area (int lwpid, CORE_ADDR *addr)
>  #endif
>  
>    {
> -    struct lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
>      struct thread_info *thr = get_lwp_thread (lwp);
>      struct regcache *regcache = get_thread_regcache (thr, 1);
>      unsigned int desc[4];
> @@ -379,7 +382,7 @@ bool
>  x86_target::low_cannot_store_register (int regno)
>  {
>  #ifdef __x86_64__
> -  if (is_64bit_tdesc ())
> +  if (is_64bit_tdesc (current_thread))
>      return false;
>  #endif
>  
> @@ -390,7 +393,7 @@ bool
>  x86_target::low_cannot_fetch_register (int regno)
>  {
>  #ifdef __x86_64__
> -  if (is_64bit_tdesc ())
> +  if (is_64bit_tdesc (current_thread))
>      return false;
>  #endif
>  
> @@ -815,7 +818,7 @@ x86_target::low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
>    int is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
>  
>    /* Is the inferior 32-bit?  If so, then fixup the siginfo object.  */
> -  if (!is_64bit_tdesc ())
> +  if (!is_64bit_tdesc (current_thread))
>        return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
>  					       FIXUP_32);
>    /* No fixup for native x32 GDB.  */
> @@ -1078,7 +1081,7 @@ const regs_info *
>  x86_target::get_regs_info ()
>  {
>  #ifdef __x86_64__
> -  if (is_64bit_tdesc ())
> +  if (is_64bit_tdesc (current_thread))
>      return &amd64_linux_regs_info;
>    else
>  #endif
> @@ -1553,7 +1556,7 @@ x86_target::install_fast_tracepoint_jump_pad (CORE_ADDR tpoint,
>  					      char *err)
>  {
>  #ifdef __x86_64__
> -  if (is_64bit_tdesc ())
> +  if (is_64bit_tdesc (current_thread))
>      return amd64_install_fast_tracepoint_jump_pad (tpoint, tpaddr,
>  						   collector, lockaddr,
>  						   orig_size, jump_entry,
> @@ -1587,7 +1590,7 @@ x86_target::get_min_fast_tracepoint_insn_len ()
>  #ifdef __x86_64__
>    /*  On x86-64, 5-byte jump instructions with a 4-byte offset are always
>        used for fast tracepoints.  */
> -  if (is_64bit_tdesc ())
> +  if (is_64bit_tdesc (current_thread))
>      return 5;
>  #endif
>  
> @@ -2931,7 +2934,7 @@ emit_ops *
>  x86_target::emit_ops ()
>  {
>  #ifdef __x86_64__
> -  if (is_64bit_tdesc ())
> +  if (is_64bit_tdesc (current_thread))
>      return &amd64_emit_ops;
>    else
>  #endif
> -- 
> 2.37.3
  
Simon Marchi Nov. 18, 2022, 4:12 p.m. UTC | #2
On 11/18/22 06:32, Andrew Burgess via Gdb-patches wrote:
> Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
>> ps_get_thread_area receives as a parameter the lwpid it must work on.
>> It then calls is_64bit_tdesc, which uses the current_thread as the
>> thread to work on.  However, it is not said that both are the same.
>>
>> This became a problem when working in a following patch that pmakes
> 
> s/pmakes/makes/

Fixed.

>> find_one_thread switch to a process but to no thread (current_thread ==
>> nullptr).  When libthread_db needed to get the thread area,
>> is_64bit_tdesc would try to get the regcache of a nullptr thread.
>>
>> Fix that by making is_64bit_tdesc accept the thread to work on as a
>> parameter.  Find the right thread from the context, when possible (when
>> we know the lwpid to work on).  Otherwise, pass "current_thread", to
>> retain the existing behavior.
>>
>> Change-Id: I44394d6be92392fa28de71982fd04517ce8a3007
>> ---
>>  gdbserver/linux-x86-low.cc | 27 +++++++++++++++------------
>>  1 file changed, 15 insertions(+), 12 deletions(-)
>>
>> diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
>> index d2b55f6f0d2..c98a7a461fe 100644
>> --- a/gdbserver/linux-x86-low.cc
>> +++ b/gdbserver/linux-x86-low.cc
>> @@ -275,9 +275,9 @@ static /*const*/ int i386_regmap[] =
>>     per the tdesc.  */
>>  
>>  static int
>> -is_64bit_tdesc (void)
>> +is_64bit_tdesc (thread_info *thread)
> 
> I think the comment for this function needs updating, the reference to
> "current inferior" probably needs to be replaced with THREAD.

Indeed, fixed.

> 
> With those changes, LGTM.
> 
> Reviewed-By: Andrew Burgess <aburgess@redhat.com>

Thanks, pushed.

Simon
  

Patch

diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
index d2b55f6f0d2..c98a7a461fe 100644
--- a/gdbserver/linux-x86-low.cc
+++ b/gdbserver/linux-x86-low.cc
@@ -275,9 +275,9 @@  static /*const*/ int i386_regmap[] =
    per the tdesc.  */
 
 static int
-is_64bit_tdesc (void)
+is_64bit_tdesc (thread_info *thread)
 {
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache (thread, 0);
 
   return register_size (regcache->tdesc, 0) == 8;
 }
@@ -292,7 +292,9 @@  ps_get_thread_area (struct ps_prochandle *ph,
 		    lwpid_t lwpid, int idx, void **base)
 {
 #ifdef __x86_64__
-  int use_64bit = is_64bit_tdesc ();
+  lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
+  gdb_assert (lwp != nullptr);
+  int use_64bit = is_64bit_tdesc (get_lwp_thread (lwp));
 
   if (use_64bit)
     {
@@ -335,7 +337,9 @@  int
 x86_target::low_get_thread_area (int lwpid, CORE_ADDR *addr)
 {
 #ifdef __x86_64__
-  int use_64bit = is_64bit_tdesc ();
+  lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
+  gdb_assert (lwp != nullptr);
+  int use_64bit = is_64bit_tdesc (get_lwp_thread (lwp));
 
   if (use_64bit)
     {
@@ -351,7 +355,6 @@  x86_target::low_get_thread_area (int lwpid, CORE_ADDR *addr)
 #endif
 
   {
-    struct lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
     struct thread_info *thr = get_lwp_thread (lwp);
     struct regcache *regcache = get_thread_regcache (thr, 1);
     unsigned int desc[4];
@@ -379,7 +382,7 @@  bool
 x86_target::low_cannot_store_register (int regno)
 {
 #ifdef __x86_64__
-  if (is_64bit_tdesc ())
+  if (is_64bit_tdesc (current_thread))
     return false;
 #endif
 
@@ -390,7 +393,7 @@  bool
 x86_target::low_cannot_fetch_register (int regno)
 {
 #ifdef __x86_64__
-  if (is_64bit_tdesc ())
+  if (is_64bit_tdesc (current_thread))
     return false;
 #endif
 
@@ -815,7 +818,7 @@  x86_target::low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
   int is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
 
   /* Is the inferior 32-bit?  If so, then fixup the siginfo object.  */
-  if (!is_64bit_tdesc ())
+  if (!is_64bit_tdesc (current_thread))
       return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
 					       FIXUP_32);
   /* No fixup for native x32 GDB.  */
@@ -1078,7 +1081,7 @@  const regs_info *
 x86_target::get_regs_info ()
 {
 #ifdef __x86_64__
-  if (is_64bit_tdesc ())
+  if (is_64bit_tdesc (current_thread))
     return &amd64_linux_regs_info;
   else
 #endif
@@ -1553,7 +1556,7 @@  x86_target::install_fast_tracepoint_jump_pad (CORE_ADDR tpoint,
 					      char *err)
 {
 #ifdef __x86_64__
-  if (is_64bit_tdesc ())
+  if (is_64bit_tdesc (current_thread))
     return amd64_install_fast_tracepoint_jump_pad (tpoint, tpaddr,
 						   collector, lockaddr,
 						   orig_size, jump_entry,
@@ -1587,7 +1590,7 @@  x86_target::get_min_fast_tracepoint_insn_len ()
 #ifdef __x86_64__
   /*  On x86-64, 5-byte jump instructions with a 4-byte offset are always
       used for fast tracepoints.  */
-  if (is_64bit_tdesc ())
+  if (is_64bit_tdesc (current_thread))
     return 5;
 #endif
 
@@ -2931,7 +2934,7 @@  emit_ops *
 x86_target::emit_ops ()
 {
 #ifdef __x86_64__
-  if (is_64bit_tdesc ())
+  if (is_64bit_tdesc (current_thread))
     return &amd64_emit_ops;
   else
 #endif