OSGeo / grass-addons

GRASS GIS Addons Repository
https://grass.osgeo.org/grass-stable/manuals/addons/
GNU General Public License v2.0
99 stars 150 forks source link

[Bug] i.rotate addon: Segmentation fault (core dumped) #823

Open neteler opened 1 year ago

neteler commented 1 year ago

Name of the addon i.rotate

Describe the bug The program crashes with a Segmentation fault (core dumped).

With larger maps, the out-of-memory-kill (OOM-killer) is activated by Linux.

To Reproduce

grass ~/grassdata/nc_spm_08_grass7/user1/
g.extension i.rotate
g.region raster=elevation -p
i.rotate input=elevation output=elevation_rot angle=90
Segmentation fault (core dumped)

GRASS nc_spm_08_grass7/user1:~ > gdb i.rotate

Debugging:

(gdb) r input=elevation output=elevation_rot angle=90
Starting program: /home/mneteler/.grass8/addons/bin/i.rotate input=elevation output=elevation_rot angle=90
...
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401a5e in main (argc=4, argv=0x7fffffffd378) at main.c:142
142 main.c: Directory not empty.
(gdb) r input=elevation output=elevation_rot angle=90 --o
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/mneteler/.grass8/addons/bin/i.rotate input=elevation output=elevation_rot angle=90 --o
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401a5e in main (argc=5, argv=0x7fffffffd378) at main.c:142
142 in main.c
(gdb) bt full
#0  0x0000000000401a5e in main (argc=5, argv=0x7fffffffd378) at main.c:142
        nrows = 1350
        ncols = 1500
        row = 0
        col = 1426
        module = 0x7ffff7f6ff08 <state+40>
        in = 0x7ffff7f6ff68 <state+136>
        out = 0x482570
        n = 0x4826a0
        history = {fields = {0x454c5954534d4944 <error: Cannot access memory at address 0x454c5954534d4944>, 0x0, 
            0x46 <error: Cannot access memory at address 0x46>, 0x47ee20 "user1", 0x13 <error: Cannot access memory at address 0x13>, 
            0x13 <error: Cannot access memory at address 0x13>, 0x47e270 "\001", 
            0x725668891f615047 <error: Cannot access memory at address 0x725668891f615047>}, nlines = -12096, lines = 0xa}
        infd = 0
        outfd = 1
        inrast = 0x48dda0
        outrast = 0x490c90
        outName = "`\321\377\377\377\177\000\000l\225\251\367\377\177\000\000DUMMY\000\000\000\340\214\277\367\377\177\000\000!", '\000' <repeats 15 times>, "p\355G\000\000\000\000\000 \000\000\000\000\000\000\000\200\303\320\367\377\177\000\000 \004\000\000\000\000\000\000\200\214\277\367\377\177\000\000\020\004\000\000\000\000\000\000@\000\000\000\000\000\000\000pf\200\367\377\177\000\000\000\000\000\000\000\000\000\000M©\367\377\177\000\000\005\000\000\000\000\000\000\000@\nH\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\377\177\000\000\000\322\377\377\377\177\000\000\020\004\000\000\000\000\000\000\060\nH\000\000\000\000\000\320\365\000\000\000\000\000\000\200\214\277\367\377\177\000\000p"...
        proj_info = 0x484230
        unit_info = 0x484800
        proj = {pj = 0x8054800, meters = 1, zone = 0, 
          proj = "lcc\000\350\320\377\377\377\177\000\000\005\000\000\000\000\000\000\000GROUP\000\000\000`\025\300\364\377\177\000\000IӮ\364\377\177\000\000\020\321\377\377\377\177\000\000\n\000\000\000\000\000\000\000MLINESTYLE\000\364\377\177\000\000J\321D\000\000\000\000\000\070\321\377\377\377\177\000\000\t\000\000\000\000\000\000", 
          def = 0x406740 "+proj=lcc +lat_1=36.1", '6' <repeats 13 times>, " +lat_2=34.", '3' <repeats 13 times>, "4 +lat_0=33.75 +lon_0=-79 +x_0=609601.22 +y_0=0 +no_defs +a=6378137 +rf=298.257222101 +towgs84=0.000,0.000,0.000 +type=crs ", srid = 0x484920 "EPSG:3358", wkt = 0x0}
        matnrows = 2700
        matncols = 3000
        deltarow = 675
        deltacol = 750
        matin = 0x49bef0
        matout = 0x4278120
        d = 85.554786682128906
        theta = 90
        thetarad = 1.5707963267948966
        costheta = 6.123233995736766e-17
        sintheta = 1
        newrow = -1
        newcol = 75
(gdb) 

Expected behavior No crash :)

It happens here: https://github.com/OSGeo/grass-addons/blob/ee8fbcb1a06f57d6197b6a11d327dca8289fda89/src/imagery/i.rotate/main.c#L142

As far as I can see, the allocated memory in https://github.com/OSGeo/grass-addons/blob/ee8fbcb1a06f57d6197b6a11d327dca8289fda89/src/imagery/i.rotate/main.c#L32

is never freed.

Screenshots If applicable, add screenshots to help explain your problem.

System description (please complete the following information):

nilason commented 1 year ago

Just a quick glance at this, inserting the values from dump to main.c:142:

matout[-1][75] = matin[0][1426];

with negative value for 'newrow' which obviously cannot work...

metzm commented 1 year ago

i.rotate increases the number of rows and columns in https://github.com/OSGeo/grass-addons/blob/grass8/src/imagery/i.rotate/main.c#L86 ff but should instead increase the current region's extents for the output raster. Thus the workflow would be to use the current region as input window, calculate the output window extents and set the output window accordingly, load the input raster using the input window, do the rotation by translating current input window row/col to coordinates, convert translated coordinates to output window row/col, update output matrix with a test that output row/col are within the allowed range, write output matrix to output raster.

nilason commented 1 year ago

Probably related thread in ML archives: https://lists.osgeo.org/pipermail/grass-dev/2012-November/060912.html .