[2/2] remote.c, QCatchSyscalls: Build std::string instead of unique_xmalloc_ptr (Re: [RFA 4/6] Simple cleanup removals in remote.c)

Message ID 474c4998-c732-ad97-18ef-904170a68e53@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Oct. 16, 2017, 11:38 p.m. UTC
  On 10/17/2017 12:00 AM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
> 
> Pedro> This suggests to me that we're missing a string_printf variant
> Pedro> that appends to a preexisting string:
> Pedro>   void string_appendf (std::string &dest, const char* fmt, ...);
> Pedro> See (untested) patch below.
> 
> Seems like a good idea FWIW.

And here's the remote.c bit making use of string_appendf, slit out as
a proper patch.

Forgot to mention in 1/2, but this applies on top of:
  https://sourceware.org/ml/gdb-patches/2017-10/msg00485.html

From 19283964911072c76ee530c58a46fd4b87dfbaae Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Tue, 17 Oct 2017 00:28:46 +0100
Subject: [PATCH] remote.c, QCatchSyscalls: Build std::string instead of
 unique_xmalloc_ptr

Simplify the code a little bit using std::string + string_appendf.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>
	    Simon Marchi <simon.marchi@ericsson.com>

	* remote.c (remote_set_syscall_catchpoint): Build a std::string
	instead of a gdb::unique_xmalloc_ptr, using string_appendf.
---
 gdb/remote.c | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)
  

Comments

Simon Marchi Oct. 19, 2017, 3:17 a.m. UTC | #1
On 2017-10-16 19:38, Pedro Alves wrote:
> diff --git a/gdb/remote.c b/gdb/remote.c
> index 6b77a9f..a6cb724 100644
> --- a/gdb/remote.c
> +++ b/gdb/remote.c
> @@ -2086,40 +2086,32 @@ remote_set_syscall_catchpoint (struct 
> target_ops *self,
>  			  pid, needed, any_count, n_sysno);
>      }
> 
> -  gdb::unique_xmalloc_ptr<char> built_packet;
> +  std::string built_packet;
>    if (needed)
>      {
>        /* Prepare a packet with the sysno list, assuming max 8+1
>  	 characters for a sysno.  If the resulting packet size is too
>  	 big, fallback on the non-selective packet.  */
>        const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9 + 
> 1;
> -
> -      built_packet.reset ((char *) xmalloc (maxpktsz));
> -      strcpy (built_packet.get (), "QCatchSyscalls:1");
> +      built_packet.reserve (maxpktsz);
> +      built_packet = "QCatchSyscalls:1";
>        if (!any_count)
>  	{
> -	  int i;
> -	  char *p;
> -
> -	  p = built_packet.get ();
> -	  p += strlen (p);
> -
>  	  /* Add in catch_packet each syscall to be caught (table[i] != 0).  
> */
> -	  for (i = 0; i < table_size; i++)
> +	  for (int i = 0; i < table_size; i++)
>  	    {
>  	      if (table[i] != 0)
> -		p += xsnprintf (p, built_packet.get () + maxpktsz - p,
> -				";%x", i);
> +		string_appendf (built_packet, ";%x", i);
>  	    }
>  	}
> -      if (strlen (built_packet.get ()) > get_remote_packet_size ())
> +      if (built_packet.size () > get_remote_packet_size ())
>  	{
>  	  /* catch_packet too big.  Fallback to less efficient
>  	     non selective mode, with GDB doing the filtering.  */
>  	  catch_packet = "QCatchSyscalls:1";
>  	}
>        else
> -	catch_packet = built_packet.get ();
> +	catch_packet = built_packet.c_str ();

You can get rid of built_packet, and make catch_packet the std::string.  
And then this last else branch can be removed.

Simon
  
Pedro Alves Oct. 30, 2017, 11:49 a.m. UTC | #2
On 10/19/2017 04:17 AM, Simon Marchi wrote:
> On 2017-10-16 19:38, Pedro Alves wrote:
>> diff --git a/gdb/remote.c b/gdb/remote.c
>> index 6b77a9f..a6cb724 100644
>> --- a/gdb/remote.c
>> +++ b/gdb/remote.c
>> @@ -2086,40 +2086,32 @@ remote_set_syscall_catchpoint (struct
>> target_ops *self,
>>                pid, needed, any_count, n_sysno);
>>      }
>>
>> -  gdb::unique_xmalloc_ptr<char> built_packet;
>> +  std::string built_packet;
>>    if (needed)
>>      {
>>        /* Prepare a packet with the sysno list, assuming max 8+1
>>       characters for a sysno.  If the resulting packet size is too
>>       big, fallback on the non-selective packet.  */
>>        const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9
>> + 1;
>> -
>> -      built_packet.reset ((char *) xmalloc (maxpktsz));
>> -      strcpy (built_packet.get (), "QCatchSyscalls:1");
>> +      built_packet.reserve (maxpktsz);
>> +      built_packet = "QCatchSyscalls:1";
>>        if (!any_count)
>>      {
>> -      int i;
>> -      char *p;
>> -
>> -      p = built_packet.get ();
>> -      p += strlen (p);
>> -
>>        /* Add in catch_packet each syscall to be caught (table[i] !=
>> 0).  */
>> -      for (i = 0; i < table_size; i++)
>> +      for (int i = 0; i < table_size; i++)
>>          {
>>            if (table[i] != 0)
>> -        p += xsnprintf (p, built_packet.get () + maxpktsz - p,
>> -                ";%x", i);
>> +        string_appendf (built_packet, ";%x", i);
>>          }
>>      }
>> -      if (strlen (built_packet.get ()) > get_remote_packet_size ())
>> +      if (built_packet.size () > get_remote_packet_size ())
>>      {
>>        /* catch_packet too big.  Fallback to less efficient
>>           non selective mode, with GDB doing the filtering.  */
>>        catch_packet = "QCatchSyscalls:1";
>>      }
>>        else
>> -    catch_packet = built_packet.get ();
>> +    catch_packet = built_packet.c_str ();
> 
> You can get rid of built_packet, and make catch_packet the std::string. 
> And then this last else branch can be removed.

The reason I didn't do that is because that'd introduce an
allocation + one deep string copy in the '!needed' case:

  else
    catch_packet = "QCatchSyscalls:0";

when it's very easy to avoid.

So I pushed the patch in as is.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/remote.c b/gdb/remote.c
index 6b77a9f..a6cb724 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2086,40 +2086,32 @@  remote_set_syscall_catchpoint (struct target_ops *self,
 			  pid, needed, any_count, n_sysno);
     }
 
-  gdb::unique_xmalloc_ptr<char> built_packet;
+  std::string built_packet;
   if (needed)
     {
       /* Prepare a packet with the sysno list, assuming max 8+1
 	 characters for a sysno.  If the resulting packet size is too
 	 big, fallback on the non-selective packet.  */
       const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9 + 1;
-
-      built_packet.reset ((char *) xmalloc (maxpktsz));
-      strcpy (built_packet.get (), "QCatchSyscalls:1");
+      built_packet.reserve (maxpktsz);
+      built_packet = "QCatchSyscalls:1";
       if (!any_count)
 	{
-	  int i;
-	  char *p;
-
-	  p = built_packet.get ();
-	  p += strlen (p);
-
 	  /* Add in catch_packet each syscall to be caught (table[i] != 0).  */
-	  for (i = 0; i < table_size; i++)
+	  for (int i = 0; i < table_size; i++)
 	    {
 	      if (table[i] != 0)
-		p += xsnprintf (p, built_packet.get () + maxpktsz - p,
-				";%x", i);
+		string_appendf (built_packet, ";%x", i);
 	    }
 	}
-      if (strlen (built_packet.get ()) > get_remote_packet_size ())
+      if (built_packet.size () > get_remote_packet_size ())
 	{
 	  /* catch_packet too big.  Fallback to less efficient
 	     non selective mode, with GDB doing the filtering.  */
 	  catch_packet = "QCatchSyscalls:1";
 	}
       else
-	catch_packet = built_packet.get ();
+	catch_packet = built_packet.c_str ();
     }
   else
     catch_packet = "QCatchSyscalls:0";