Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Sergio Durigan Junior <sergiodj@redhat.com>
To: Simon Marchi <simon.marchi@polymtl.ca>
Cc: GDB Patches <gdb-patches@sourceware.org>,
	 Pedro Alves <palves@redhat.com>,  Eli Zaretskii <eliz@gnu.org>
Subject: Re: [PATCH v2] Implement the ability to set/unset environment variables to GDBserver when starting the inferior
Date: Tue, 01 Aug 2017 02:43:00 -0000	[thread overview]
Message-ID: <87shhc9ffa.fsf@redhat.com> (raw)
In-Reply-To: <d9dae60ba5a7e1aca29f15fe865f4110@polymtl.ca> (Simon Marchi's	message of "Sun, 30 Jul 2017 00:35:58 +0200")

On Saturday, July 29 2017, Simon Marchi wrote:

> Hi Sergio,
>
> I took a closer look at set/unset, I have a few comments.

Thanks, Simon.

>> @@ -99,32 +107,104 @@ gdb_environ::get (const char *var) const
>>  void
>>  gdb_environ::set (const char *var, const char *value)
>>  {
>> +  char *fullvar = concat (var, "=", value, NULL);
>> +
>>    /* We have to unset the variable in the vector if it exists.  */
>> -  unset (var);
>> +  unset (var, false);
>>
>>    /* Insert the element before the last one, which is always NULL.  */
>> -  m_environ_vector.insert (m_environ_vector.end () - 1,
>> -			   concat (var, "=", value, NULL));
>> +  m_environ_vector.insert (m_environ_vector.end () - 1, fullvar);
>> +
>> +  /* Mark this environment variable as having been set by the user.
>> +     This will be useful when we deal with setting environment
>> +     variables on the remote target.  */
>> +  m_user_set_env_list.push_back (fullvar);
>> +
>> +  /* If this environment variable is marked as unset by the user, then
>> +     remove it from the list, because now the user wants to set
>> +     it.  */
>> +  for (std::vector<const char *>::iterator iter_user_unset
>> +	 = m_user_unset_env_list.begin ();
>> +       iter_user_unset != m_user_unset_env_list.end ();
>> +       ++iter_user_unset)
>> +    if (strcmp (var, *iter_user_unset) == 0)
>> +      {
>> +	void *v = (void *) *iter_user_unset;
>> +
>> +	m_user_unset_env_list.erase (iter_user_unset);
>> +	xfree (v);
>> +	break;
>> +      }
>>  }
>>
>>  /* See common/environ.h.  */
>>
>>  void
>> -gdb_environ::unset (const char *var)
>> +gdb_environ::unset (const char *var, bool update_unset_list)
>>  {
>>    size_t len = strlen (var);
>> +  std::vector<char *>::iterator it_env;
>>
>>    /* We iterate until '.end () - 1' because the last element is
>>       always NULL.  */
>> -  for (std::vector<char *>::iterator el = m_environ_vector.begin ();
>> -       el != m_environ_vector.end () - 1;
>> -       ++el)
>> -    if (match_var_in_string (*el, var, len))
>> -      {
>> -	xfree (*el);
>> -	m_environ_vector.erase (el);
>> -	break;
>> -      }
>> +  for (it_env = m_environ_vector.begin ();
>> +       it_env != m_environ_vector.end () - 1;
>> +       ++it_env)
>> +    if (match_var_in_string (*it_env, var, len))
>> +      break;
>> +
>> +  if (it_env == m_environ_vector.end () - 1)
>> +    {
>> +      /* No element has been found.  */
>> +      return;
>> +    }
>
> Do we want to support the use case to unset an environment variable
> that is defined on the remote system, but not on the local system?  If
> so, the function should probably not return immediately if the
> variable is not found in the env vector, so that the unset request
> ends up in the list of variables to unset.

I guess I hadn't thought about this use case.  It makes sense to me.  I
will make the proper modifications.

>> +
>> +  std::vector<const char *>::iterator it_user_set_env;
>> +  char *found_var = *it_env;
>> +
>> +  it_user_set_env = std::remove (m_user_set_env_list.begin (),
>> +				 m_user_set_env_list.end (),
>> +				 found_var);
>> +  if (it_user_set_env != m_user_set_env_list.end ())
>> +    {
>> +      /* We found (and removed) the element from the user_set_env
>> +	 vector.  */
>> +      m_user_set_env_list.erase (it_user_set_env,
>> m_user_set_env_list.end ());
>> +    }
>> +
>> +  if (update_unset_list)
>> +    {
>> +      bool found_in_unset = false;
>> +
>> +      for (const char *el : m_user_unset_env_list)
>> +	if (strcmp (el, var) == 0)
>> +	  {
>> +	    found_in_unset = true;
>> +	    break;
>> +	  }
>> +
>> +      if (!found_in_unset)
>> +	m_user_unset_env_list.push_back (xstrdup (var));
>> +    }
>> +
>> +  m_environ_vector.erase (it_env);
>> +  xfree (found_var);
>> +}
>
> I have the feeling that we can reduce the amount of boilerplate code
> in the set and unset methods by using std::set instead of std::vector.
> Performance-wise this may not be very good, since for any reasonable
> amount of variables, the vector would probably be more efficient.  But
> its interface makes the code clearer and lighter, in my opinion.  I
> suppose we could always make something with a set-like interface and
> behavior implemented on top of a vector.

I thought about using std::set, but given that I was recently called out
for doing "premature pessimization", I chose to stick with std::vector.
I agree that for some cases std::set would make things easier to
implement/understand.

>
>> +
>> +/* See common/environ.h.  */
>> +
>> +void
>> +gdb_environ::clear_user_set_env ()
>> +{
>> +  std::vector<const char *> copy = m_user_set_env_list;
>> +
>> +  for (const char *var : copy)
>> +    {
>> +      std::string varname (var);
>> +
>> +      varname.erase (varname.find ('='), std::string::npos);
>> +      unset (varname.c_str (), false);
>> +    }
>
> I am not sure having a method like this is correct.  It is used in
> gdbserver when we want to "reset" the environment, that is forget all
> user-made modifications, both set and unset.  To do it correctly, it
> should include restoring the variables that have been unset or
> overwritten.  But as I said in my other mail, I think the simplest
> solution will be to restore the environment from a backup copy of the
> original env.  If we do that, this method won't be needed.
>
> I have prototyped some of my suggestions to make sure they made sense.
> I thought I would push them somewhere, feel free to use whatever you
> want if that's useful to you:
>
> https://github.com/simark/binutils-gdb/commits/remote-env

Thanks, that's very useful.  I have code for most of what you requested,
but I'll use some ideas from your branch.

Cheers,

-- 
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF  31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/


  reply	other threads:[~2017-08-01  2:43 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-29 19:41 [PATCH] Implement the ability to transmit " Sergio Durigan Junior
2017-07-10 21:32 ` Sergio Durigan Junior
2017-07-13 21:47 ` Simon Marchi
2017-07-14 17:34   ` Sergio Durigan Junior
2017-07-27  3:36 ` [PATCH v2] Implement the ability to set/unset " Sergio Durigan Junior
2017-07-27 17:10   ` Eli Zaretskii
2017-07-27 22:05   ` Simon Marchi
2017-08-01  2:33     ` Sergio Durigan Junior
2017-08-01  9:35       ` Simon Marchi
2017-08-04 22:56         ` Sergio Durigan Junior
2017-07-29 22:36   ` Simon Marchi
2017-08-01  2:43     ` Sergio Durigan Junior [this message]
2017-08-01  9:54       ` Simon Marchi
2017-08-04 23:03         ` Sergio Durigan Junior
2017-08-05 18:14           ` Simon Marchi
2017-08-12  4:34             ` Sergio Durigan Junior
2017-08-12  8:11               ` Simon Marchi
     [not found]   ` <256083325d9f9c4cc4f5518fe6e5292d@polymtl.ca>
2017-08-12  4:19     ` Sergio Durigan Junior
2017-08-13  6:19 ` [PATCH v3] " Sergio Durigan Junior
2017-08-21 19:11   ` Sergio Durigan Junior
2017-08-24 19:25   ` Simon Marchi
2017-08-28 21:25     ` Sergio Durigan Junior
2017-08-28 23:13 ` [PATCH v4] " Sergio Durigan Junior
2017-08-31 19:37   ` Simon Marchi
2017-08-31 20:34     ` Sergio Durigan Junior
2017-08-31 20:39       ` Simon Marchi
2017-08-31 20:49 ` [PATCH v5] " Sergio Durigan Junior
2017-08-31 21:03   ` Simon Marchi
2017-08-31 21:26     ` Sergio Durigan Junior
2017-09-05 15:33       ` Thomas Preudhomme
2017-09-05 16:26         ` Simon Marchi
2017-09-05 17:09           ` Thomas Preudhomme
2017-09-05 18:41             ` Simon Marchi
2017-09-06  8:36               ` Thomas Preudhomme
2017-09-01  6:19   ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87shhc9ffa.fsf@redhat.com \
    --to=sergiodj@redhat.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    --cc=simon.marchi@polymtl.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox