Opened 5 years ago

Closed 4 years ago

#3740 closed defect (fixed)

The "Quit GRASS GIS" button does not close the GRASS shell/session

Reported by: pmav99 Owned by: grass-dev@…
Priority: normal Milestone: 7.8.3
Component: Startup Version: svn-trunk
Keywords: Cc:
CPU: x86-64 Platform: Linux

Description

After closing the GRASS GUI the user account's local env is not being restored. E.g.

$ echo $PATH
/home/pmav99/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/lib/xpra:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

$ which python
/usr/bin/python

$ cat src2/grass/run_gui.sh
#!/usr/bin/env bash
#
# Run the GRASS GUI, after activating the virtualenv

# the 'dirname readlink' line finds the directory where this script is located.
# https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within
GRASS_SRC="$(dirname $(readlink -f $0))"

source "${GRASS_SRC}"/venv/bin/activate
exec "${GRASS_SRC}"/bin.x86_64-pc-linux-gnu/grass77

$ src2/grass/run_gui.sh
Starting GRASS GIS...
Cleaning up temporary files...

Welcome to GRASS GIS 7.7.svn (r74037)
...
[closing the gui]
...

$ echo $PATH
/home/pmav99/.local/bin:/home/pmav99/src2/grass/dist.x86_64-pc-linux-gnu/bin:/home/pmav99/src2/grass/dist.x86_64-pc-linux-gnu/scripts:/home/pmav99/.grass7/addons/bin:/home/pmav99/.grass7/addons/scripts:/home/pmav99/src2/grass/venv/bin:/home/pmav99/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/lib/xpra:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

$ which python
/home/pmav99/src2/grass/venv/bin/python

As you can see $PATH has changed. Is this by design? Shouldn't the original session be completely restored?

PS. Sorry if this has been mentioned before, but I couldn't find anything relevant.

Change History (14)

comment:1 by pmav99, 5 years ago

I checked again, without the exec this time and the problem is still there, so that's not the culprit. Nevertheless, after quitting GRASS (I made sure that I did not press close GUI button) grass is still running:

pmav99   24041  0.0  0.0  15244  3152 pts/2    S    19:16   0:00 bash src2/grass/run_gui.sh
pmav99   24045  0.0  0.1  35200 12480 pts/2    S    19:16   0:00 python /home/pmav99/src2/grass/bin.x86_64-pc-linux-gnu/grass77
pmav99   24515  0.0  0.0  16792  2064 pts/2    S+   19:17   0:00 grep --color=auto grass

PS. In the ticket description, I used the term "closing the GUI". I meant that I quit GRASS, not that I just closed the GUI and remained with the text interface, but I can't find how to edit the ticket...

comment:2 by pmav99, 5 years ago

OK, after writing exit on the console, the GRASS session finally exits.

exit

Cleaning up default sqlite database ...
Cleaning up temporary files...
Done.

Goodbye from GRASS GIS

if this is how this is supposed to work, I would suggest changing the menu/dialog messages, because they are misleading.

in reply to:  2 ; comment:3 by mmetz, 5 years ago

Replying to pmav99:

OK, after writing exit on the console, the GRASS session finally exits.

The script run_gui.sh calls grass77 which establishes a GRASS session on the command line. The GUI is only started with grass77 --gui, or if the stored settings indicate that the last time GRASS was started with a GUI. That means the name run_gui.sh is misleading because it establishes a GRASS session on the command line and maybe starts the GUI, maybe not. In order to terminate the script grass77 and thus leave the GRASS session, you need to type exit in the command line. This has been standard GRASS behaviour for decades.

in reply to:  3 ; comment:4 by pmav99, 5 years ago

Replying to mmetz:

Replying to pmav99:

OK, after writing exit on the console, the GRASS session finally exits.

The script run_gui.sh calls grass77 which establishes a GRASS session on the command line. The GUI is only started with grass77 --gui, or if the stored settings indicate that the last time GRASS was started with a GUI.

I am sorry but I think this is not accurate. Please correct me if I am wrong, but the very first time you run the grass77 executable, you don't get the CLI, you get the GUI. At least that's what I observe. If you want to change the behavior you need to call grass77 with the --text/--gtext argument. So the --gui argument is the default one, not the other way around.

That being said, and I guess that this is the main issue here, the dialog you get when you press ctrl+Q is IMHO confusing. As far as I can tell, both the Close GUI and the Quit GRASS GIS button do the exact same thing, i.e. they return me to the GRASS shell, from which I need to exit in order to return to my regular shell. I could be wrong though. Perhaps there is some other difference which I don't know about.

Nevertheless, I do find confusing that I have to Quit GRASS twice. Once in the GUI and once in the console. I would expect that the Quit GRASS button returns me to my own shell. If not, what is the point of having both that one and the Close GUI button?

https://i.imgur.com/NlLfc44.png

comment:5 by pmav99, 5 years ago

The relevant code seems to be this (_1):

2599	    def _quitGRASS(self):
2600	        """Quit GRASS terminal"""
2601	        try:
2602	            shellPid = int(grass.gisenv()['PID'])
2603	        except:
2604	            grass.warning(_("Unable to exit GRASS shell: unknown PID"))
2605	            return
2606	
2607	        Debug.msg(1, "Exiting shell with pid={0}".format(shellPid))
2608	        import signal
2609	        os.kill(shellPid, signal.SIGTERM)

The logic of the code that calls _quitGRASS seems AFAI can tell correct. I don't see the warning on the console, so assuming that warnings do get logged by default, the problem could be in the os.kill call. To be honest, the main reason I was using exec in the first place was to have proper signal propagation (_2).

For the record I tried this without the script. I.e. I activated the virtualenv manually and executed grass77. The behavior is still the same. I need to exit twice. So it is not related to the wrapper script. Could someone tell me how can I increase the log level?

_1: https://trac.osgeo.org/grass/browser/grass/trunk/gui/wxpython/lmgr/frame.py#L2599

_2: https://unix.stackexchange.com/a/196053/37579

Last edited 5 years ago by pmav99 (previous) (diff)

in reply to:  4 ; comment:6 by mmetz, 5 years ago

Replying to pmav99:

Replying to mmetz:

Replying to pmav99:

OK, after writing exit on the console, the GRASS session finally exits.

The script run_gui.sh calls grass77 which establishes a GRASS session on the command line. The GUI is only started with grass77 --gui, or if the stored settings indicate that the last time GRASS was started with a GUI.

I am sorry but I think this is not accurate. Please correct me if I am wrong, but the very first time you run the grass77 executable, you don't get the CLI, you get the GUI. At least that's what I observe.

Here, on Linux, I always get a CLI, and sometimes also a GUI, if I wish to have one. I don't get a GUI without a CLI.

That being said, and I guess that this is the main issue here, the dialog you get when you press ctrl+Q is IMHO confusing. As far as I can tell, both the Close GUI and the Quit GRASS GIS button do the exact same thing, i.e. they return me to the GRASS shell, from which I need to exit in order to return to my regular shell. I could be wrong though. Perhaps there is some other difference which I don't know about.

When I click the Quit GRASS GIS button, both the GUI and the CLI GRASS session are closed.

Nevertheless, I do find confusing that I have to Quit GRASS twice. Once in the GUI and once in the console. I would expect that the Quit GRASS button returns me to my own shell.

This is what happens for me: the Quit GRASS GIS button returns me to my own shell.

Hint: type exit in the CLI, this closes the GUI and returns you to your own shell.

in reply to:  6 comment:7 by pmav99, 5 years ago

Replying to mmetz:

This is what happens for me: the Quit GRASS GIS button returns me to my own shell.

I don't doubt you, but I am afraid this is not the behavior I am observing though. The complete setup on my end is the following:

  1. Create a fresh VM running ubuntu 18.04
  2. Check out trunk
  3. Compile

Note: In order to avoid the overhead of running Xorg in the VM, I make the VM headless and connect via SSH. Whenever I need to run a gui application in the VM I launch an xpra server in the VM: https://xpra.org/

In case someone is not familiar with xpra, it is more or less the equivalent of X11 forwarding on SSH. I can't say that xpra is definitely not interfering, but I don't think it is very likely. I will try to test with plain X11 forwarding to rule that out.

So, when I want to e.g. launch the GRASS GUI, I start an instance of a terminal emulator (e.g. terminator) via xpra. Just to make sure that everything is clear, the terminal emulator is running on the VM; not on my laptop. It is being rendered on my laptop's Xorg though. But, at least in theory this should not be important.

So from within this terminal emulator I launch GRASS using my script. As I said in a previous message, I did try to launch grass77 directly from the emulator's shell (i.e. without the script) but this didn't change anything. Anyway, while the GRASS GUI is running, the relevant processes on the VM are:

pmav99    8770  2.7  2.3 1131716 192136 ?      Sl   12:02   0:04 /usr/bin/python2 /usr/bin/xpra start --speaker=disabled --start-child=terminator --microphone=disabled --webcam=disabled --pulseaudio=no --env=XPR
pmav99    8772  3.1  2.9 1196104 239844 ?      Ssl  12:02   0:04  \_ /usr/lib/xorg/Xorg-for-Xpra-S8753 -noreset -novtswitch -nolisten tcp +extension GLX +extension RANDR +extension RENDER -auth /home/pmav99/.Xau
pmav99    8896  0.3  0.9 1132248 76916 ?       Sl   12:02   0:00  \_ /usr/bin/python /usr/bin/terminator
pmav99    8921  0.4  0.0  54412  6684 pts/1    Ss   12:02   0:00      \_ /bin/zsh
pmav99    9094  0.0  0.0  15244  3116 pts/1    S    12:04   0:00          \_ bash src2/grass/run_gui.sh
pmav99    9098  0.1  0.1  35200 12344 pts/1    S    12:04   0:00              \_ python /home/pmav99/src2/grass/bin.x86_64-pc-linux-gnu/grass77
pmav99    9151  0.3  0.0  49808  5980 pts/1    S+   12:04   0:00                  \_ /bin/zsh
pmav99    9152  4.2  2.0 1087160 169400 pts/1  Sl   12:04   0:01                  \_ python /home/pmav99/src2/grass/dist.x86_64-pc-linux-gnu/gui/wxpython/wxgui.py

As you can see, grass77 starts two child processes ,9151 and 9152. Both of them are functioning as they should (the process states are S+ and Sl respectively). Now, when I click on Quit GRASS GIS, the GUI closes, but the shell remains. And this is how the process tree is looking:

pmav99    8770  1.4  2.2 1116340 183864 ?      Sl   12:02   0:05 /usr/bin/python2 /usr/bin/xpra start --speaker=disabled --start-child=terminator --microphone=disabled --webcam=disabled --pulseaudio=no --env=XPR
pmav99    8772  1.3  2.6 1089848 213520 ?      Ssl  12:02   0:05  \_ /usr/lib/xorg/Xorg-for-Xpra-S8753 -noreset -novtswitch -nolisten tcp +extension GLX +extension RANDR +extension RENDER -auth /home/pmav99/.Xau
pmav99    8896  0.1  0.9 1132248 76916 ?       Sl   12:02   0:00  \_ /usr/bin/python /usr/bin/terminator
pmav99    8921  0.1  0.0  54412  6684 pts/1    Ss   12:02   0:00      \_ /bin/zsh
pmav99    9094  0.0  0.0  15244  3116 pts/1    S    12:04   0:00          \_ bash src2/grass/run_gui.sh
pmav99    9098  0.0  0.1  35200 12344 pts/1    S    12:04   0:00              \_ python /home/pmav99/src2/grass/bin.x86_64-pc-linux-gnu/grass77
pmav99    9151  0.0  0.0  49808  5980 pts/1    S+   12:04   0:00                  \_ /bin/zsh
pmav99    9152  0.8  0.0      0     0 pts/1    Z    12:04   0:02                  \_ [python] <defunct>

9151 is still running (state S+) while 9152 is a zombie process

I would be happy to hear any suggestions to debug this

comment:8 by pmav99, 5 years ago

CPU: Unspecifiedx86-64
Summary: The GRASS session is "leaking" to the environmentThe "Quit GRASS GIS" button does not close the GRASS shell/session

comment:9 by cmbarton, 5 years ago

FWIW, it has always not worked on the Mac. Whether you quit GRASS or quit the GUI, you still get bumped back to the terminal where you must type "exit" to end the session.

It would be nice if selecting Quit GRASS actually exited from the GRASS shell and environment. Barring that, it would be better just to have the Quit GUI button, with an info box that says "Type 'exit' to quit GRASS entirely'.

comment:10 by pmav99, 5 years ago

Just tested this on my main PC: Archlinux + trunk + python 2

When I start the GUI there are two processes, 15369 and 15370:

feanor    2940  0.7  0.4 547480 75700 ?        Ssl  18:15   0:53 /usr/bin/python2 /usr/bin/terminator
feanor    2949  0.2  0.0  16336 11116 pts/0    Ss   18:15   0:20  \_ /bin/zsh
feanor   15305  0.5  0.0  21880 14140 pts/0    S    20:16   0:00      \_ python bin.x86_64-pc-linux-gnu/grass77
feanor   15369  3.4  0.0  14316  9416 pts/0    S    20:16   0:00          \_ /bin/zsh
feanor   15370 37.6  0.9 989800 148932 pts/0   Sl   20:16   0:01          \_ python /home/feanor/Prog/svn/grass_svn/dist.x86_64-pc-linux-gnu/gui/wxpython/wxgui.py

When I click Quit GRASS GIS, the shell continues to run, while the gui one becomes a zombie.

feanor    2940  0.7  0.4 547864 76220 ?        Ssl  18:15   0:54 /usr/bin/python2 /usr/bin/terminator
feanor    2949  0.2  0.0  16336 11116 pts/0    Ss   18:15   0:20  \_ /bin/zsh
feanor   15305  0.0  0.0  21880 14140 pts/0    S    20:16   0:00      \_ python bin.x86_64-pc-linux-gnu/grass77
feanor   15369  0.1  0.0  14316  9420 pts/0    S    20:16   0:00          \_ /bin/zsh
feanor   15370  1.8  0.0      0     0 pts/0    Z    20:16   0:02          \_ [python] <defunct>

Since I remain in the GRASS shell, I can restart the GUI with g.gui. If I do so, a new python process is spawned, which, interestingly enough, does not belong to the same process tree

feanor    2940  0.7  0.4 548432 76836 ?        Ssl  18:15   0:54 /usr/bin/python2 /usr/bin/terminator
feanor    2949  0.2  0.0  16336 11116 pts/0    Ss   18:15   0:20  \_ /bin/zsh
feanor   15305  0.0  0.0  21880 14140 pts/0    S    20:16   0:00      \_ python bin.x86_64-pc-linux-gnu/grass77
feanor   15369  0.1  0.0  14316  9420 pts/0    S    20:16   0:00          \_ /bin/zsh
feanor   15370  1.5  0.0      0     0 pts/0    Z    20:16   0:02          \_ [python] <defunct>
feanor   16326 37.8  0.9 989780 148956 pts/0   Sl   20:19   0:01 python /home/feanor/Prog/svn/grass_svn/dist.x86_64-pc-linux-gnu/gui/wxpython/wxgui.py

+

$ pstree -ps 16326
systemd(1)───python(16326)─┬─{python}(16346)
                           ├─{python}(16352)
                           ├─{python}(16353)
                           ├─{python}(16354)
                           └─{python}(16362)

Nevertheless, if I type exit in the shell, all processes die as expected.

comment:11 by pmav99, 5 years ago

I don't really understand why, but the problem might be related with zsh after all...

On zsh, which is what I mainly use, I get the problems I mentioned earlier. On bash though, the button exits GRASS just fine. I tested this both on the Ubuntu VM and on Archlinux.

Note: If you want to try this, you don't only need to start a zsh shell, you also need to export SHELL=/usr/bin/zsh too.

in reply to:  11 comment:12 by neteler, 5 years ago

Replying to pmav99:

I don't really understand why, but the problem might be related with zsh after all...

On zsh, which is what I mainly use, I get the problems I mentioned earlier. On bash though, the button exits GRASS just fine. I tested this both on the Ubuntu VM and on Archlinux.

Probably something is missing for zsh support in

lib/init/grass.py

?

comment:13 by neteler, 4 years ago

Milestone: 7.8.3

comment:14 by wenzeslaus, 4 years ago

Resolution: fixed
Status: newclosed

Z shell support added in PR:722. Closing as fixed. See also (already closed) #3009 for the exit issue.

Note: See TracTickets for help on using tickets.