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/
next prev parent 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