Opened 6 years ago

Closed 5 years ago

#2351 closed defect (fixed)

g.version segfaults when the build is not perfect

Reported by: wenzeslaus Owned by: grass-dev@…
Priority: normal Milestone: 7.0.0
Component: Compiling Version: unspecified
Keywords: GIS_H_VERSION, GIS_H_DATA, libgis, g.version Cc:
CPU: Unspecified Platform: Linux

Description

G7:g.version often fails, segfaults in particular, with some wrong builds. It seems that it is happening for one or more Ubuntu packages.

Here are some outputs I collected from the users.

> g.version -rge
version=7.0.svn
date=2013
revision=
build_date=2013-12-11
Segmentation fault (core dumped)
> g.gisenv set=DEBUG=5
bash: /usr/lib/grass70/etc/prompt.py: File o directory non esistente
> g.version -rge
D2/5: G_file_name(): path = /media/massarelli/sdb/Mappe/GRASS/Puglia_Landsat_nord/PERMANENT
version=7.0.0svn
date=2014
revision=
build_date=2014-06-24
build_platform=x86_64-pc-linux-gnu
Errore di segmentazione (core dump creato)
bash: /usr/lib/grass70/etc/prompt.py: File o directory non esistente

It seems that the strings GIS_H_VERSION and GIS_H_DATE are broken. I think that g.version should handle this since it is often used in cases when something is somehow broken.

Solution

I don't know how to reproduce it but I created a patch assuming that G_tokenize works well with any input and strstr is failing with NULL pointer. The new version wants the results from G_tokenize to be of length 2. If this is not fulfilled, it prints a message or empty values (with -g) and with g.gisenv set=DEBUG=5, it prints also the original strings. Perhaps the message can be replaced by waring which would be printed even with -g.

Patch attached. Let me know if I should commit this. Since I cannot test this much I'm not sure if it really helps.

Alternative solution

I don't know why GIS_H_VERSION and GIS_H_DATE are wrong in the first place but if the problem is really there, maybe they should be obtained in some less fragile way than as SVN $$ things. Anyway, parsing the variables is hard and even GRASS is not doing it right (there are spaces at the end of the output), so some simplification in format of variables might be helpful.

strstr function and NULL

#include <stdio.h>
#include <string.h>

int main ()
{
    char * a = NULL;
    a = "\0"; // comment to get segfault
    printf("a=\"%s\"\n", a); fflush(stdout);
    char* b = strstr(a, "X");
    printf("b=\"%s\"\n", b); fflush(stdout);
    printf("Done\n"); fflush(stdout);
    return 0;
}
gcc teststrstr.c -o teststrstr && ./teststrstr

With a = "\0";:

a=""
b="(null)"
Done

Without a = "\0";:

a="(null)"
Segmentation fault (core dumped)

See also

Attachments (1)

gversion_with_libgis_checks.diff (1.8 KB) - added by wenzeslaus 6 years ago.
if number of tokes is not 2, print empty svn revision and tell more in debug

Download all attachments as: .zip

Change History (6)

Changed 6 years ago by wenzeslaus

if number of tokes is not 2, print empty svn revision and tell more in debug

comment:1 in reply to:  description ; Changed 6 years ago by neteler

Replying to wenzeslaus:

G7:g.version often fails, segfaults in particular, with some wrong builds.

...

> g.gisenv set=DEBUG=5
bash: /usr/lib/grass70/etc/prompt.py: File o directory non esistente

...

}}}

The fact that etc/prompt.py indicates that the grass70 start script is outdated with respect to the SVN version. So, the "make install" has not been properly performed or the "grass70" script in the path is an old version (e.g old copy rather a link when using a non-installed compiled version from the source tree). Check that start script first.

comment:2 in reply to:  1 ; Changed 6 years ago by wenzeslaus

Replying to neteler:

Replying to wenzeslaus:

G7:g.version often fails, segfaults in particular, with some wrong builds.

...

> g.gisenv set=DEBUG=5
bash: /usr/lib/grass70/etc/prompt.py: File o directory non esistente

...

}}}

The fact that etc/prompt.py indicates that the grass70 start script is outdated with respect to the SVN version. So, the "make install" has not been properly performed or the "grass70" script in the path is an old version (e.g old copy rather a link when using a non-installed compiled version from the source tree). Check that start script first.

I'm not sure if I fully understand what you are saying. Anyway, in this GRASS was installed from packages and the error message says that there is no promp.py file. This indeed seems like a broken build or installation, however g.version was failing even in the other case where this error was not reported and the point is to make g.version resistant to errors and strange configurations since it is often used within environments like this (for example it wouldn't be a good idea to write g.version in Python).

comment:3 in reply to:  2 Changed 6 years ago by glynn

Replying to wenzeslaus:

The fact that etc/prompt.py indicates that the grass70 start script is outdated with respect to the SVN version. So, the "make install" has not been properly performed or the "grass70" script in the path is an old version (e.g old copy rather a link when using a non-installed compiled version from the source tree). Check that start script first.

I'm not sure if I fully understand what you are saying. Anyway, in this GRASS was installed from packages and the error message says that there is no promp.py file.

lib/init/grass.py used to write "PROMPT_COMMAND=<gisbase>/etc/prompt.py" into the local .bashrc file which it generates. r60216 removed the prompt.py script and instead defines a bash function to generate the prompt.

The error message suggests that only part of r60216 is in effect; specifically, prompt.py has been removed but PROMPT_COMMAND still refers to it. This could be caused by the local .bashrc not being generated at startup and an old version left over from a previous session being used instead.

This indeed seems like a broken build or installation, however g.version was failing even in the other case

The prompt.py error may well be unrelated to the problems with g.version. However, it suggests problems with the build or installation, and g.version is sensitive to the build and installation.

The problem appears to arise from a combination of two issues: g.version not being robust against bad input data, and g.version getting bad input data. The prompt.py issue hints at a possible reason for the latter.

comment:4 Changed 5 years ago by wenzeslaus

g.version improved in r61589 (diff similar to the provided one but it has additional waring). prompt.py issue should be already solved and is not part of this ticket.

I'm not sure if it make sense to wait for confirmation that it works as expected (i.e. it reports something and does not break the dependent things). It may take some time before we get the distribution with problems as the ones before but it might be soon...

comment:5 Changed 5 years ago by wenzeslaus

Resolution: fixed
Status: newclosed

There were no objections, so I backported r61589 in r61683. Closing.

Note: See TracTickets for help on using tickets.