[7/7] gdb: startup commands to control Python extension language

Message ID baa30a387c74179380976d32b59df22f8768d300.1619125261.git.andrew.burgess@embecosm.com
State New
Headers show
Series
  • New options to control how Python is initialized
Related show

Commit Message

Andrew Burgess April 22, 2021, 9:02 p.m.
Add two new commands to GDB that can be placed into the early
initialization to control how Python starts up.  The new options are:

  set python ignore-environment on|off
  set python dont-write-bytecode auto|on|off

  show python ignore-environment
  show python dont-write-bytecode

These can be used from GDB's startup file to control how the Python
extension language behaves.  These options are equivalent to the -E
and -B flags to python respectively, their descriptions from the
Python man page:

  -E     Ignore environment variables like PYTHONPATH and PYTHONHOME
         that modify the  behavior  of  the  interpreter.

  -B     Don't write .pyc files on import.

gdb/ChangeLog:

	* NEWS: Mention new commands.
	* python/python.c (python_ignore_environment): New static global.
	(show_python_ignore_environment): New function.
	(set_python_ignore_environment): New function.
	(python_dont_write_bytecode): New static global.
	(show_python_dont_write_bytecode): New function.
	(set_python_dont_write_bytecode): New function.
	(_initialize_python): Register new commands.

gdb/doc/ChangeLog:

	* python.texinfo (Python Commands): Mention new commands.

gdb/testsuite/ChangeLog:

	* gdb.python/py-startup-opt.exp: New file.
---
 gdb/ChangeLog                               |  11 ++
 gdb/NEWS                                    |  16 +++
 gdb/doc/ChangeLog                           |   4 +
 gdb/doc/python.texi                         |  38 +++++++
 gdb/python/python.c                         |  98 ++++++++++++++++
 gdb/testsuite/ChangeLog                     |   4 +
 gdb/testsuite/gdb.python/py-startup-opt.exp | 118 ++++++++++++++++++++
 7 files changed, 289 insertions(+)
 create mode 100644 gdb/testsuite/gdb.python/py-startup-opt.exp

-- 
2.25.4

Comments

Vasili Burdo via Gdb-patches April 23, 2021, 10:31 a.m. | #1
> From: Andrew Burgess <andrew.burgess@embecosm.com>

> Date: Thu, 22 Apr 2021 22:02:48 +0100

> 

> gdb/ChangeLog:

> 

> 	* NEWS: Mention new commands.

> 	* python/python.c (python_ignore_environment): New static global.

> 	(show_python_ignore_environment): New function.

> 	(set_python_ignore_environment): New function.

> 	(python_dont_write_bytecode): New static global.

> 	(show_python_dont_write_bytecode): New function.

> 	(set_python_dont_write_bytecode): New function.

> 	(_initialize_python): Register new commands.

> 

> gdb/doc/ChangeLog:

> 

> 	* python.texinfo (Python Commands): Mention new commands.

> 

> gdb/testsuite/ChangeLog:

> 

> 	* gdb.python/py-startup-opt.exp: New file.


Thanks.  The documentation parts are approved, provided that the few
minor nits below are taken care of.

> +@kindex set python ignore-environment

> +@item set python ignore-environment @r{[}on@r{|}off@r{]}

> +By default this option is @samp{off}, and, when @value{GDBN}

> +initializes its internal Python interpreter, the Python interpreter

> +will check the environment for variables that will effect how it

> +behaves, for example @samp{PYTHONHOME}, and

> +@samp{PYTHONPATH}@footnote{See the ENVIRONMENT VARIABLES section of

> +@code{man 1 python} for a comprehensive list.}.


Please use @env as markup for environment variables, not @samp.

> +This option is equivalent to passing @samp{-E} to the real

                                        ^^^^^^^^^
@option{-E}

> +@samp{python} executable.

   ^^^^^^^^^^^^^
@command{python}

> +@kindex set python dont-write-bytecode

> +@item set python dont-write-bytecode @r{[}auto@r{|}on@r{|}off@r{]}

> +When this option is @samp{off}, then, once @value{GDBN} has

> +initialized the Python interpreter, the interpreter will byte-compile

> +any Python modules that it imports and write the byte code to disk in

> +@code{.pyc} files.

   ^^^^^^^^^^^
@file{*.pyc}

> +By default this option is set to @samp{auto}, in this mode Python will

> +check the environment variable @samp{PYTHONDONTWRITEBYTECODE} to see

                                  ^^^^^
@env

> +This option is equivalent to passing @samp{-B} to the real

> +@samp{python} executable.


@option and @command, as before.
Tom Tromey April 23, 2021, 2:32 p.m. | #2
>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:


Andrew> gdb/ChangeLog:

Andrew> 	* NEWS: Mention new commands.
Andrew> 	* python/python.c (python_ignore_environment): New static global.
Andrew> 	(show_python_ignore_environment): New function.
Andrew> 	(set_python_ignore_environment): New function.
Andrew> 	(python_dont_write_bytecode): New static global.
Andrew> 	(show_python_dont_write_bytecode): New function.
Andrew> 	(set_python_dont_write_bytecode): New function.
Andrew> 	(_initialize_python): Register new commands.

I think this probably fixes PR python/22503.
Other than that it looks good.  Thanks for doing this.

Tom
Tom de Vries April 29, 2021, 8:32 a.m. | #3
On 4/22/21 11:02 PM, Andrew Burgess wrote:
> +set python ignore-environment on|off

> +show python ignore-environment

> +  When 'on', this causes GDB's builtin Python to ignore any

> +  environment variables that would otherwise effect how Python


affect?

> +  behaves.  This command needs to be added to an early initialization

> +  file (e.g. ~/.config/gdb/gdbearlyinit) in order to affect GDB.

> +

> +set python dont-write-bytecode auto|on|off

> +show python dont-write-bytecode

> +  When 'on', this causes GDB's builtin Python to not write any

> +  byte-code (.pyc files) to disk.  This command needs to be added to

> +  an early initialization file (e.g. ~/.config/gdb/gdbearlyinit) in

> +  order to affect GDB.  When 'off' byte-code will always be written.

> +  When set to 'auto' (the default) Python will check the

> +  PYTHONDONTWRITEBYTECODE. environment variable.


Dot at end of variable name.

> +


I ran into https://sourceware.org/bugzilla/show_bug.cgi?id=27788 due to
having PYTHONDONTWRITEBYTECODE set in my environment.  My guess at this
point is that this is a test-case issue.

I played around a bit with the options and did:
...
$ echo $PYTHONDONTWRITEBYTECODE
1

$ gdb -q -batch \
    -iex "set python ignore-environment on" \
    -iex "show python dont-write-bytecode"
Python's dont-write-bytecode setting is auto (currently off).

$ gdb -q -batch \
    -iex "set python ignore-environment off" \
    -iex "show python dont-write-bytecode"
Python's dont-write-bytecode setting is auto (currently on).
...
which shows that there is an interaction between the two commands.
AFAICT, this is not evident from either the NEWS item, or the docs, and
I just wonder whether it's a good idea to make this explicit.

Thanks,
- Tom
Andrew Burgess April 29, 2021, 9:35 a.m. | #4
* Tom de Vries <tdevries@suse.de> [2021-04-29 10:32:05 +0200]:

> On 4/22/21 11:02 PM, Andrew Burgess wrote:

> > +set python ignore-environment on|off

> > +show python ignore-environment

> > +  When 'on', this causes GDB's builtin Python to ignore any

> > +  environment variables that would otherwise effect how Python

> 

> affect?

> 

> > +  behaves.  This command needs to be added to an early initialization

> > +  file (e.g. ~/.config/gdb/gdbearlyinit) in order to affect GDB.

> > +

> > +set python dont-write-bytecode auto|on|off

> > +show python dont-write-bytecode

> > +  When 'on', this causes GDB's builtin Python to not write any

> > +  byte-code (.pyc files) to disk.  This command needs to be added to

> > +  an early initialization file (e.g. ~/.config/gdb/gdbearlyinit) in

> > +  order to affect GDB.  When 'off' byte-code will always be written.

> > +  When set to 'auto' (the default) Python will check the

> > +  PYTHONDONTWRITEBYTECODE. environment variable.

> 

> Dot at end of variable name.


Thanks for pointing out these two issues, I pushed the patch below as
obvious to address them.

Thanks,
Andrew

---

commit 8eb82ba1fdc052d2bb08ec6f0d98b8d2c10edd17
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Thu Apr 29 10:29:41 2021 +0100

    gdb/NEWS: Fix typo and stray full stop
    
    Some errors introduced in commit:
    
      commit edeaceda7b2f33b2c3bf78c732e67f3188e7f0b9
      Date:   Thu Aug 27 16:53:13 2020 +0100
    
          gdb: startup commands to control Python extension language
    
    gdb/ChangeLog:
    
            * NEWS: Fix typo and stray full stop.

diff --git a/gdb/NEWS b/gdb/NEWS
index 6550ea352ac..19cb444e7fe 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -109,7 +109,7 @@ show print type hex
 set python ignore-environment on|off
 show python ignore-environment
   When 'on', this causes GDB's builtin Python to ignore any
-  environment variables that would otherwise effect how Python
+  environment variables that would otherwise affect how Python
   behaves.  This command needs to be added to an early initialization
   file (e.g. ~/.config/gdb/gdbearlyinit) in order to affect GDB.
 
@@ -120,7 +120,7 @@ show python dont-write-bytecode
   an early initialization file (e.g. ~/.config/gdb/gdbearlyinit) in
   order to affect GDB.  When 'off' byte-code will always be written.
   When set to 'auto' (the default) Python will check the
-  PYTHONDONTWRITEBYTECODE. environment variable.
+  PYTHONDONTWRITEBYTECODE environment variable.
 
 * Changed commands
Andrew Burgess April 29, 2021, 9:46 a.m. | #5
* Tom de Vries <tdevries@suse.de> [2021-04-29 10:32:05 +0200]:

> I ran into https://sourceware.org/bugzilla/show_bug.cgi?id=27788 due to

> having PYTHONDONTWRITEBYTECODE set in my environment.  My guess at this

> point is that this is a test-case issue.

> 

> I played around a bit with the options and did:

> ...

> $ echo $PYTHONDONTWRITEBYTECODE

> 1

> 

> $ gdb -q -batch \

>     -iex "set python ignore-environment on" \

>     -iex "show python dont-write-bytecode"

> Python's dont-write-bytecode setting is auto (currently off).

> 

> $ gdb -q -batch \

>     -iex "set python ignore-environment off" \

>     -iex "show python dont-write-bytecode"

> Python's dont-write-bytecode setting is auto (currently on).

> ...

> which shows that there is an interaction between the two commands.

> AFAICT, this is not evident from either the NEWS item, or the docs, and

> I just wonder whether it's a good idea to make this explicit.


Hi Tom,

Thanks for looking at this feature.

The docs for dont-write-bytecode say:

  <snip>

  By default this option is set to @samp{auto}, in this mode Python will
  check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
  if it should write out byte-code or not.

  <snip>

I guess you saw this, but it still didn't seem clear enough?

What if this was extended to something like:

  By default this option is set to @samp{auto}, in this mode Python will
  check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
  if it should write out byte-code or not.  When @command{set python
  ignore-environment on} has been used then Python will ignore
  the environment variable and write out the byte-code files.

I've included the patch below that would make this change.

Thanks,
Andrew

---

commit 1557998d9d8e9b0587500980bd8731bb55a1c299
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Thu Apr 29 10:45:17 2021 +0100

    gdb/doc: improve description of set python dont-write-bytecode
    
    Extend the description of 'set python dont-write-bytecode' to make the
    interaction with 'set python ignore-environment' clearer.
    
    gdb/doc/ChangeLog:
    
            * python.texinfo (Python Commands): Extend description of 'set
            python dont-write-bytecode'.

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 20d65742964..26e1446f005 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -136,8 +136,10 @@
 (@pxref{Initialization Files}) to have the desired effect.
 
 By default this option is set to @samp{auto}, in this mode Python will
-check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
-if it should write out byte-code or not.
+check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see if
+it should write out byte-code or not.  When @command{set python
+ignore-environment on} has been used then Python will ignore the
+environment variable and write out the byte-code files.
 
 This option is equivalent to passing @option{-B} to the real
 @command{python} executable.
Tom de Vries April 29, 2021, 10:08 a.m. | #6
On 4/29/21 11:46 AM, Andrew Burgess wrote:
> * Tom de Vries <tdevries@suse.de> [2021-04-29 10:32:05 +0200]:

> 

>> I ran into https://sourceware.org/bugzilla/show_bug.cgi?id=27788 due to

>> having PYTHONDONTWRITEBYTECODE set in my environment.  My guess at this

>> point is that this is a test-case issue.

>>

>> I played around a bit with the options and did:

>> ...

>> $ echo $PYTHONDONTWRITEBYTECODE

>> 1

>>

>> $ gdb -q -batch \

>>     -iex "set python ignore-environment on" \

>>     -iex "show python dont-write-bytecode"

>> Python's dont-write-bytecode setting is auto (currently off).

>>

>> $ gdb -q -batch \

>>     -iex "set python ignore-environment off" \

>>     -iex "show python dont-write-bytecode"

>> Python's dont-write-bytecode setting is auto (currently on).

>> ...

>> which shows that there is an interaction between the two commands.

>> AFAICT, this is not evident from either the NEWS item, or the docs, and

>> I just wonder whether it's a good idea to make this explicit.

> 

> Hi Tom,

> 

> Thanks for looking at this feature.

> 

> The docs for dont-write-bytecode say:

> 

>   <snip>

> 

>   By default this option is set to @samp{auto}, in this mode Python will

>   check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

>   if it should write out byte-code or not.

> 

>   <snip>

> 

> I guess you saw this, but it still didn't seem clear enough?

> 

> What if this was extended to something like:

> 

>   By default this option is set to @samp{auto}, in this mode Python will

>   check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

>   if it should write out byte-code or not.  When @command{set python

>   ignore-environment on} has been used then Python will ignore

>   the environment variable and write out the byte-code files.

> 

> I've included the patch below that would make this change.

> 


Hi Andrew,

LGTM, I just wonder if something like this is not more clear, that is,
reformulate in terms of already explained option value off, rather than
verbosely repeating the off behaviour.  So, something like this:
...
By default this option is set to @samp{auto}, in this mode Python will
check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
if it should write out byte-code or not.  When @command{set python
ignore-environment on} has been used then auto has the same behaviour as
off.
...

But then again, this may be a bad idea, I'm not sure.

Thanks,
- Tom
Vasili Burdo via Gdb-patches April 29, 2021, 12:17 p.m. | #7
> Date: Thu, 29 Apr 2021 10:46:42 +0100

> From: Andrew Burgess <andrew.burgess@embecosm.com>

> Cc: gdb-patches@sourceware.org

> 

> --- a/gdb/doc/python.texi

> +++ b/gdb/doc/python.texi

> @@ -136,8 +136,10 @@

>  (@pxref{Initialization Files}) to have the desired effect.

>  

>  By default this option is set to @samp{auto}, in this mode Python will

> -check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

> -if it should write out byte-code or not.

> +check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see if

> +it should write out byte-code or not.  When @command{set python

> +ignore-environment on} has been used then Python will ignore the

> +environment variable and write out the byte-code files.


@command is the markup for programs, not for command lines.  Command
lines should be in @kbd, as that is what the user types on the
keyboard.

Thanks.
Vasili Burdo via Gdb-patches April 29, 2021, 12:32 p.m. | #8
> Date: Thu, 29 Apr 2021 15:17:00 +0300

> From: Eli Zaretskii via Gdb-patches <gdb-patches@sourceware.org>

> Cc: gdb-patches@sourceware.org

> 

> @command is the markup for programs, not for command lines.


To clarify, by "programs" I mean names of program executable files.
Like @command{gdb}, @command{gcc}, @command{make}, etc.  The Texinfo
manual says:

  Use the '@command' command to indicate command names, such as 'ls' or
  'cc'.
Andrew Burgess May 2, 2021, 10:31 a.m. | #9
* Tom de Vries <tdevries@suse.de> [2021-04-29 12:08:50 +0200]:

> On 4/29/21 11:46 AM, Andrew Burgess wrote:

> > * Tom de Vries <tdevries@suse.de> [2021-04-29 10:32:05 +0200]:

> > 

> >> I ran into https://sourceware.org/bugzilla/show_bug.cgi?id=27788 due to

> >> having PYTHONDONTWRITEBYTECODE set in my environment.  My guess at this

> >> point is that this is a test-case issue.

> >>

> >> I played around a bit with the options and did:

> >> ...

> >> $ echo $PYTHONDONTWRITEBYTECODE

> >> 1

> >>

> >> $ gdb -q -batch \

> >>     -iex "set python ignore-environment on" \

> >>     -iex "show python dont-write-bytecode"

> >> Python's dont-write-bytecode setting is auto (currently off).

> >>

> >> $ gdb -q -batch \

> >>     -iex "set python ignore-environment off" \

> >>     -iex "show python dont-write-bytecode"

> >> Python's dont-write-bytecode setting is auto (currently on).

> >> ...

> >> which shows that there is an interaction between the two commands.

> >> AFAICT, this is not evident from either the NEWS item, or the docs, and

> >> I just wonder whether it's a good idea to make this explicit.

> > 

> > Hi Tom,

> > 

> > Thanks for looking at this feature.

> > 

> > The docs for dont-write-bytecode say:

> > 

> >   <snip>

> > 

> >   By default this option is set to @samp{auto}, in this mode Python will

> >   check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

> >   if it should write out byte-code or not.

> > 

> >   <snip>

> > 

> > I guess you saw this, but it still didn't seem clear enough?

> > 

> > What if this was extended to something like:

> > 

> >   By default this option is set to @samp{auto}, in this mode Python will

> >   check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

> >   if it should write out byte-code or not.  When @command{set python

> >   ignore-environment on} has been used then Python will ignore

> >   the environment variable and write out the byte-code files.

> > 

> > I've included the patch below that would make this change.

> > 

> 

> Hi Andrew,

> 

> LGTM, I just wonder if something like this is not more clear, that is,

> reformulate in terms of already explained option value off, rather than

> verbosely repeating the off behaviour.  So, something like this:

> ...

> By default this option is set to @samp{auto}, in this mode Python will

> check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

> if it should write out byte-code or not.  When @command{set python

> ignore-environment on} has been used then auto has the same behaviour as

> off.

> ...

> 

> But then again, this may be a bad idea, I'm not sure.


That seems like a good idea to me.

Here's the patch I propose to push then (pending doc review from Eli).

Thanks,
Andrew

--

commit 98508d108b973838a7d02029e6686756605affd8
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Thu Apr 29 10:45:17 2021 +0100

    gdb/doc: improve description of set python dont-write-bytecode
    
    Extend the description of 'set python dont-write-bytecode' to make the
    interaction with 'set python ignore-environment' clearer.
    
    gdb/doc/ChangeLog:
    
            * python.texinfo (Python Commands): Extend description of 'set
            python dont-write-bytecode'.

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 20d65742964..91c9c121117 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -136,8 +136,10 @@
 (@pxref{Initialization Files}) to have the desired effect.
 
 By default this option is set to @samp{auto}, in this mode Python will
-check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
-if it should write out byte-code or not.
+check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see if
+it should write out byte-code or not.  When @kbd{set python
+ignore-environment on} has been used then @samp{auto} has the same
+behaviour as @samp{off}.
 
 This option is equivalent to passing @option{-B} to the real
 @command{python} executable.
Tom de Vries May 2, 2021, 6:15 p.m. | #10
On 5/2/21 12:31 PM, Andrew Burgess wrote:
> * Tom de Vries <tdevries@suse.de> [2021-04-29 12:08:50 +0200]:

> 

>> On 4/29/21 11:46 AM, Andrew Burgess wrote:

>>> * Tom de Vries <tdevries@suse.de> [2021-04-29 10:32:05 +0200]:

>>>

>>>> I ran into https://sourceware.org/bugzilla/show_bug.cgi?id=27788 due to

>>>> having PYTHONDONTWRITEBYTECODE set in my environment.  My guess at this

>>>> point is that this is a test-case issue.

>>>>

>>>> I played around a bit with the options and did:

>>>> ...

>>>> $ echo $PYTHONDONTWRITEBYTECODE

>>>> 1

>>>>

>>>> $ gdb -q -batch \

>>>>     -iex "set python ignore-environment on" \

>>>>     -iex "show python dont-write-bytecode"

>>>> Python's dont-write-bytecode setting is auto (currently off).

>>>>

>>>> $ gdb -q -batch \

>>>>     -iex "set python ignore-environment off" \

>>>>     -iex "show python dont-write-bytecode"

>>>> Python's dont-write-bytecode setting is auto (currently on).

>>>> ...

>>>> which shows that there is an interaction between the two commands.

>>>> AFAICT, this is not evident from either the NEWS item, or the docs, and

>>>> I just wonder whether it's a good idea to make this explicit.

>>>

>>> Hi Tom,

>>>

>>> Thanks for looking at this feature.

>>>

>>> The docs for dont-write-bytecode say:

>>>

>>>   <snip>

>>>

>>>   By default this option is set to @samp{auto}, in this mode Python will

>>>   check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

>>>   if it should write out byte-code or not.

>>>

>>>   <snip>

>>>

>>> I guess you saw this, but it still didn't seem clear enough?

>>>

>>> What if this was extended to something like:

>>>

>>>   By default this option is set to @samp{auto}, in this mode Python will

>>>   check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

>>>   if it should write out byte-code or not.  When @command{set python

>>>   ignore-environment on} has been used then Python will ignore

>>>   the environment variable and write out the byte-code files.

>>>

>>> I've included the patch below that would make this change.

>>>

>>

>> Hi Andrew,

>>

>> LGTM, I just wonder if something like this is not more clear, that is,

>> reformulate in terms of already explained option value off, rather than

>> verbosely repeating the off behaviour.  So, something like this:

>> ...

>> By default this option is set to @samp{auto}, in this mode Python will

>> check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

>> if it should write out byte-code or not.  When @command{set python

>> ignore-environment on} has been used then auto has the same behaviour as

>> off.

>> ...

>>

>> But then again, this may be a bad idea, I'm not sure.

> 

> That seems like a good idea to me.

> 

> Here's the patch I propose to push then (pending doc review from Eli).

> 


LGTM, thanks.
- Tom

> Thanks,

> Andrew

> 

> --

> 

> commit 98508d108b973838a7d02029e6686756605affd8

> Author: Andrew Burgess <andrew.burgess@embecosm.com>

> Date:   Thu Apr 29 10:45:17 2021 +0100

> 

>     gdb/doc: improve description of set python dont-write-bytecode

>     

>     Extend the description of 'set python dont-write-bytecode' to make the

>     interaction with 'set python ignore-environment' clearer.

>     

>     gdb/doc/ChangeLog:

>     

>             * python.texinfo (Python Commands): Extend description of 'set

>             python dont-write-bytecode'.

> 

> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi

> index 20d65742964..91c9c121117 100644

> --- a/gdb/doc/python.texi

> +++ b/gdb/doc/python.texi

> @@ -136,8 +136,10 @@

>  (@pxref{Initialization Files}) to have the desired effect.

>  

>  By default this option is set to @samp{auto}, in this mode Python will

> -check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see

> -if it should write out byte-code or not.

> +check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see if

> +it should write out byte-code or not.  When @kbd{set python

> +ignore-environment on} has been used then @samp{auto} has the same

> +behaviour as @samp{off}.

>  

>  This option is equivalent to passing @option{-B} to the real

>  @command{python} executable.

>

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index faccf40dd41..a1b83ad9fce 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -101,6 +101,22 @@  show startup-quietly
   initialization file (e.g. ~/.config/gdb/gdbearlyinit) in order to
   affect GDB.
 
+set python ignore-environment on|off
+show python ignore-environment
+  When 'on', this causes GDB's builtin Python to ignore any
+  environment variables that would otherwise effect how Python
+  behaves.  This command needs to be added to an early initialization
+  file (e.g. ~/.config/gdb/gdbearlyinit) in order to affect GDB.
+
+set python dont-write-bytecode auto|on|off
+show python dont-write-bytecode
+  When 'on', this causes GDB's builtin Python to not write any
+  byte-code (.pyc files) to disk.  This command needs to be added to
+  an early initialization file (e.g. ~/.config/gdb/gdbearlyinit) in
+  order to affect GDB.  When 'off' byte-code will always be written.
+  When set to 'auto' (the default) Python will check the
+  PYTHONDONTWRITEBYTECODE. environment variable.
+
 * Changed commands
 
 break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM]
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 9135d415dd1..aa5dc55bb60 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -103,6 +103,44 @@ 
 full Python stack printing is enabled; if @code{none}, then Python stack
 and message printing is disabled; if @code{message}, the default, only
 the message component of the error is printed.
+
+@kindex set python ignore-environment
+@item set python ignore-environment @r{[}on@r{|}off@r{]}
+By default this option is @samp{off}, and, when @value{GDBN}
+initializes its internal Python interpreter, the Python interpreter
+will check the environment for variables that will effect how it
+behaves, for example @samp{PYTHONHOME}, and
+@samp{PYTHONPATH}@footnote{See the ENVIRONMENT VARIABLES section of
+@code{man 1 python} for a comprehensive list.}.
+
+If this option is set to @samp{on} before Python is initialized then
+Python will ignore all such environment variables.  As Python is
+initialized early during @value{GDBN}'s startup process, then this
+option must be placed into the early initialization file
+(@pxref{Initialization Files}) to have the desired effect.
+
+This option is equivalent to passing @samp{-E} to the real
+@samp{python} executable.
+
+@kindex set python dont-write-bytecode
+@item set python dont-write-bytecode @r{[}auto@r{|}on@r{|}off@r{]}
+When this option is @samp{off}, then, once @value{GDBN} has
+initialized the Python interpreter, the interpreter will byte-compile
+any Python modules that it imports and write the byte code to disk in
+@code{.pyc} files.
+
+If this option is set to @samp{on} before Python is initialized then
+Python will no longer write the byte code to disk.  As Python is
+initialized early during @value{GDBN}'s startup process, then this
+option must be placed into the early initialization file
+(@pxref{Initialization Files}) to have the desired effect.
+
+By default this option is set to @samp{auto}, in this mode Python will
+check the environment variable @samp{PYTHONDONTWRITEBYTECODE} to see
+if it should write out byte-code or not.
+
+This option is equivalent to passing @samp{-B} to the real
+@samp{python} executable.
 @end table
 
 It is also possible to execute a Python script from the @value{GDBN}
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 1d0d86d5c49..c46d68b73ed 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1578,6 +1578,80 @@  python_command (const char *arg, int from_tty)
 
 #endif /* HAVE_PYTHON */
 
+/* When this is turned on before Python is initialised then Python will
+   ignore any environment variables related to Python.  This is equivalent
+   to passing `-E' to the python program.  */
+static bool python_ignore_environment = false;
+
+/* Implement 'show python ignore-environment'.  */
+
+static void
+show_python_ignore_environment (struct ui_file *file, int from_tty,
+				struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Python's ignore-environment setting is %s.\n"),
+		    value);
+}
+
+/* Implement 'set python ignore-environment'.  This sets Python's internal
+   flag no matter when the command is issued, however, if this is used
+   after Py_Initialize has been called then most of the environment will
+   already have been read.  */
+
+static void
+set_python_ignore_environment (const char *args, int from_tty,
+			       struct cmd_list_element *c)
+{
+#ifdef HAVE_PYTHON
+  Py_IgnoreEnvironmentFlag = python_ignore_environment ? 1 : 0;
+#endif
+}
+
+/* When this is turned on before Python is initialised then Python will
+   not write `.pyc' files on import of a module.  */
+static enum auto_boolean python_dont_write_bytecode = AUTO_BOOLEAN_AUTO;
+
+/* Implement 'show python dont-write-bytecode'.  */
+
+static void
+show_python_dont_write_bytecode (struct ui_file *file, int from_tty,
+				 struct cmd_list_element *c, const char *value)
+{
+  if (python_dont_write_bytecode == AUTO_BOOLEAN_AUTO)
+    {
+      const char *auto_string
+	= (python_ignore_environment
+	   || getenv ("PYTHONDONTWRITEBYTECODE") == nullptr) ? "off" : "on";
+
+      fprintf_filtered (file,
+			_("Python's dont-write-bytecode setting is %s (currently %s).\n"),
+			value, auto_string);
+    }
+  else
+    fprintf_filtered (file, _("Python's dont-write-bytecode setting is %s.\n"),
+		      value);
+}
+
+/* Implement 'set python dont-write-bytecode'.  This sets Python's internal
+   flag no matter when the command is issued, however, if this is used
+   after Py_Initialize has been called then many modules could already
+   have been imported and their byte code written out.  */
+
+static void
+set_python_dont_write_bytecode (const char *args, int from_tty,
+				struct cmd_list_element *c)
+{
+#ifdef HAVE_PYTHON
+  if (python_dont_write_bytecode == AUTO_BOOLEAN_AUTO)
+    Py_DontWriteBytecodeFlag
+      = (!python_ignore_environment
+	 && getenv ("PYTHONDONTWRITEBYTECODE") != nullptr) ? 1 : 0;
+  else
+    Py_DontWriteBytecodeFlag
+      = python_dont_write_bytecode == AUTO_BOOLEAN_TRUE ? 1 : 0;
+#endif /* HAVE_PYTHON */
+}
+
 
 
 /* Lists for 'set python' commands.  */
@@ -1880,6 +1954,30 @@  message == an error message without a stack will be printed."),
 			NULL, NULL,
 			&user_set_python_list,
 			&user_show_python_list);
+
+  add_setshow_boolean_cmd ("ignore-environment", no_class,
+			   &python_ignore_environment, _("\
+Set whether the Python interpreter should ignore environment variables."), _(" \
+Show whether the Python interpreter showlist ignore environment variables."), _(" \
+When enabled GDB's Python interpreter will ignore any Python related\n	\
+flags in the environment.  This is equivalent to passing `-E' to a\n	\
+python executable."),
+			   set_python_ignore_environment,
+			   show_python_ignore_environment,
+			   &user_set_python_list,
+			   &user_show_python_list);
+
+  add_setshow_auto_boolean_cmd ("dont-write-bytecode", no_class,
+				&python_dont_write_bytecode, _("\
+Set whether the Python interpreter should ignore environment variables."), _(" \
+Show whether the Python interpreter showlist ignore environment variables."), _(" \
+When enabled GDB's Python interpreter will ignore any Python related\n	\
+flags in the environment.  This is equivalent to passing `-E' to a\n	\
+python executable."),
+				set_python_dont_write_bytecode,
+				show_python_dont_write_bytecode,
+				&user_set_python_list,
+				&user_show_python_list);
 }
 
 #ifdef HAVE_PYTHON
diff --git a/gdb/testsuite/gdb.python/py-startup-opt.exp b/gdb/testsuite/gdb.python/py-startup-opt.exp
new file mode 100644
index 00000000000..842add30807
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-startup-opt.exp
@@ -0,0 +1,118 @@ 
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test the flags within GDB that can be used to control how Python is
+# initialized.
+
+gdb_start
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_exit
+
+# Return a list containing two directory paths for newly created home
+# directories.
+#
+# The first directory is a HOME style home directory, it contains a
+# .gdbearlyinit file containing CONTENT.
+#
+# The second directory is an XDG_CONFIG_HOME style home directory, it
+# contains a sub-directory gdb/, inside which is a file gdbearlyinit
+# that also contains CONTENT.
+#
+# The PREFIX is used in both directory names and should be unique for
+# each call to this function.
+proc setup_home_directories { prefix content } {
+    set home_dir [standard_output_file "${prefix}-home"]
+    set xdg_home_dir [standard_output_file "${prefix}-xdg"]
+
+    file mkdir $home_dir
+    file mkdir "$xdg_home_dir/gdb"
+
+    # Write the content into the HOME directory.
+    set fd [open "$home_dir/.gdbearlyinit" w]
+    puts $fd $content
+    close $fd
+
+    # Copy this from the HOME directory into the XDG_CONFIG_HOME
+    # directory.
+    file copy -force "$home_dir/.gdbearlyinit" "$xdg_home_dir/gdb/gdbearlyinit"
+
+    return [list $home_dir $xdg_home_dir]
+}
+
+# Start GDB and check the status of the Python system flags that we
+# can control from within GDB.
+proc test_python_settings { exp_state } {
+    gdb_start
+
+    gdb_test_no_output "python import sys"
+
+    foreach_with_prefix attr {ignore_environment dont_write_bytecode} {
+	gdb_test_multiline "testname" \
+	    "python" "" \
+	    "if hasattr(sys, 'flags') and getattr(sys.flags, '${attr}', False):" "" \
+	    "  print (\"${attr} is on\")" "" \
+	    "else:" "" \
+	    "  print (\"${attr} is off\")" "" \
+	    "end" "${attr} is ${exp_state}"
+    }
+
+    gdb_exit
+}
+
+save_vars { env(TERM) } {
+    # We need an ANSI-capable terminal to get the output.
+    setenv TERM ansi
+
+    # Check the features are off by default.
+    test_python_settings "off"
+
+    # Create an empty directory we can use as HOME for some of the
+    # tests below.  When we set XDG_CONFIG_HOME we still need to point
+    # HOME at something otherwise GDB complains that it doesn't know
+    # where to create the index cache.
+    set empty_home_dir [standard_output_file fake-empty-home]
+
+    # Create two directories to use for the style setting test.
+    set dirs [setup_home_directories "style" \
+		  [multi_line_input \
+		       "set python dont-write-bytecode on" \
+		       "set python ignore-environment on"]]
+    set home_dir [lindex $dirs 0]
+    set xdg_home_dir [lindex $dirs 1]
+
+    # Now arrange to use the fake home directory early init file.
+    save_vars { INTERNAL_GDBFLAGS env(HOME) env(XDG_CONFIG_HOME) } {
+	set INTERNAL_GDBFLAGS [string map {"-nx" ""} $INTERNAL_GDBFLAGS]
+
+	with_test_prefix "using HOME config" {
+	    # Now test GDB when using the HOME directory.
+	    set env(HOME) $home_dir
+	    unset -nocomplain env(XDG_CONFIG_HOME)
+	    test_python_settings "on"
+	}
+
+	with_test_prefix "using XDG_CONFIG_HOME config" {
+	    # Now test using the XDG_CONFIG_HOME folder.  We still need to
+	    # have a HOME directory set otherwise GDB will issue an error
+	    # about not knowing where to place the index cache.
+	    set env(XDG_CONFIG_HOME) $xdg_home_dir
+	    set env(HOME) $empty_home_dir
+	    test_python_settings "on"
+	}
+    }
+}