EarthScope / evalresp

Evaluates instrument responses in FDSN and derivative formats
GNU Lesser General Public License v3.0
11 stars 2 forks source link

crash calling evalresp_filename_to_channels() #77

Closed ivor52 closed 2 years ago

ivor52 commented 4 years ago

calling evalresp_filename_to_channels(), with (options.sation_xml = 0) to force parsing of file in RESP format, results in crash. traceback provded below. sample trace file and RESP file attached.

richard

#0  0x00007ffffcf07207 in tcache_get (tc_idx=4) at malloc.c:2943
#1  0x00007ffffcf07207 in __GI___libc_malloc (bytes=88) at malloc.c:3050
#2  0x0000000008186ece in alloc_deci ()
#3  0x000000000818d990 in read_channel_data ()
#4  0x000000000818eb4a in collect_channels ()
#5  0x000000000818ef8f in evalresp_char_to_channels ()
#6  0x000000000818f063 in evalresp_file_to_channels ()
#7  0x000000000818f2c1 in evalresp_filename_to_channels ()

N.B. trace file has .txt added to force github to allow the upload

RESPHGN.txt XX114.txt

chad-earthscope commented 4 years ago

The options.sation_xml = 0 [sic] actually does auto-detection of file type, it doesn't force RESP.

I cannot reproduce this and have no trouble deconvolving the sample data with the sample response when options->station_xml = 0;. I tried on both macOS and Linux (Ubuntu).

Got any more information to go on?

ivor52 commented 4 years ago

i am collecting more details on this. it turns out to be a problem when calling evalresp in succession, not just on a single file.

i will report back more info after more investigations on my side.

ivor52 commented 4 years ago

not sure why this happens only when calling evalresp() a 2nd time, but running this through valgrind shows the following double-free:

==17966== Invalid free() / delete / delete[] / realloc()
==17966==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17966==    by 0x28F6CA: free_evalresp_blkt (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F819: free_stages (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F750: free_stages (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F750: free_stages (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F876: free_channel (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F97A: evalresp_free_channel (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28FB57: evalresp_free_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x2971FE: evalresp_char_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x2972A2: evalresp_file_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x297500: evalresp_filename_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x161D19: calcfr_resp (evalresp.c:128)
==17966==  Address 0xd9a0480 is 0 bytes inside a block of size 88 free'd
==17966==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17966==    by 0x28F6A8: free_ref (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F80D: free_stages (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F750: free_stages (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F750: free_stages (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F876: free_channel (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28F97A: evalresp_free_channel (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x28FB57: evalresp_free_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x2971FE: evalresp_char_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x2972A2: evalresp_file_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x297500: evalresp_filename_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x161D19: calcfr_resp (evalresp.c:128)
==17966==  Block was alloc'd at
==17966==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17966==    by 0x28EEE8: alloc_ref (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x295C49: read_channel_data (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x296D89: collect_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x2971CE: evalresp_char_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x2972A2: evalresp_file_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x297500: evalresp_filename_to_channels (in /home/sqlx/trunk/SQLX/src/srvr/pqlxSrvr/LINUX/sqlxSrvr)
==17966==    by 0x161D19: calcfr_resp (evalresp.c:128)
==17966==    by 0x125F1D: remResp (response.c:59)
==17966==    by 0x12258F: an_psd (PSDentry.c:74)
==17966==    by 0x11DA23: pqlxEventProc (pqlxEvent.c:87)
==17966==    by 0x11BB46: scanLoop (pqlxSrvr.c:414)

following this to its source (no pun intended), i cannot see why the two different free functions are called on the same pointer, at line 734 in alloc_fctns.c::free_stages().

modifying the code as:

      case REFERENCE:
        free_ref (this_blkt);
//        free_evalresp_blkt (this_blkt);
        this_blkt = NULL;
        break;

fixes the problem, calling evalresp() repeatedly no longer results in a crash.

richard

ivor52 commented 4 years ago

my fix is naive, of course. please let me know if the modification should be different than this for my current implementation. i need to deliver to INGV and ETH and am happy to apply the fix locally to my version of the library until a new release is made available. (not the most ideal, i know....)

chad-earthscope commented 4 years ago

Thanks a lot for tracking back to that point and providing your findings. Certainly looks like an evalresp memory management problem and needs a deeper look.

chad-earthscope commented 2 years ago

It is clear that the code was performing a double free on the same pointer in free_stages(), so I remove the call to free_evalresp_blkt() and removed that function entirely as it was used nowhere else.

My guess is that this was stub code errantly left in. Thanks again for narrowing this subtle but nasty issue down.