SWI-Prolog / swipl-devel

SWI-Prolog Main development repository
http://www.swi-prolog.org
Other
976 stars 176 forks source link

segfault in read_file_from_codes/3 when running out of stack #1311

Closed matko closed 2 months ago

matko commented 2 months ago

While trying out various ways of dcg parsing for a discourse discussion, I ran into the following curious behavior on x86_64-linux on the master branch of swipl-devel.

> dd if=/dev/urandom bs=1k count=100k of=/tmp/bigfile                        
102400+0 records in
102400+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.528878 s, 198 MB/s
> swipl -g 'read_file_to_codes("/tmp/bigfile", _, [encoding(octet)])' -t halt

ERROR: Received fatal signal 11 (segv)
Time: Wed Aug 28 12:26:50 2024
Inferences: 243623
Thread: 1 (main)
C-stack trace labeled "crash":
  [0] save_backtrace() at ??:? [0x7fa14e5d43c2]
  [1] sigCrashHandler() at ??:? [0x7fa14e5d44b9]
  [2] __restore_rt() at ??:? [0x7fa14e2d75c0]
  [3] growStacks() at ??:? [0x7fa14e4fb5cf]
  [4] growLocalSpace___LD() at ??:? [0x7fa14e4fc3e2]
  [5] PL_new_term_ref___LD() at ??:? [0x7fa14e59aeff]
  [6] unify_text___LD() at ??:? [0x7fa14e5c852d]
  [7] PL_unify_text() at ??:? [0x7fa14e5c8bea]
  [8] PL_unify_chars() at ??:? [0x7fa14e5a1278]
  [9] read_stream_to_codes3() at ??:? [0x7fa14ddaa416]
  [10] PL_next_solution___LD() at ??:? [0x7fa14e4c5ec0]
  [11] query_loop() at ??:? [0x7fa14e516a9b]
  [12] prologToplevel() at ??:? [0x7fa14e51744d]
  [13] swipl(+0x1099) [0x401099]
  [14] __libc_start_call_main() at ??:? [0x7fa14e2c114e]
  [15] __libc_start_main_alias_2() at ??:? [0x7fa14e2c1209]
  [16] swipl(+0x10e5) [0x4010e5]

PROLOG STACK:
zsh: segmentation fault (core dumped)  swipl -g 'read_file_to_codes("/tmp/bigfile", _, [encoding(octet)])' -t halt

It looks like we're simply running out of stack, but in past versions I'd get a good message for that. It looks like this was last the case for me on 9.3.3:

> nix run github:matko/swipl-nix#9_3_3 -- -g 'read_file_to_codes("/tmp/bigfile", _, [encoding(octet)])' -t halt
ERROR: -g read_file_to_codes("/tmp/bigfile", _, [encoding(octet)]): Stack limit (1.0Gb) exceeded
ERROR:   Stack sizes: local: 0.5Mb, global: 1.0Gb, trail: 0Kb
ERROR:   Stack depth: 11, last-call: 0%, Choice points: 5
ERROR:   In:
ERROR:     [11] read_util:read_stream_to_codes(<stream>(0x2d6f900), [length:44,714,684|_126], [])
ERROR:     [10] system:setup_call_cleanup(<compound (:)/2>, <compound (:)/2>, <compound (:)/2>)
ERROR:     [9] read_util:read_file_to_codes('<garbage_collected>', '<garbage_collected>', '<garbage_collected>')
ERROR:     [8] system:catch(<compound (:)/2>, _208, <compound (:)/2>)
ERROR:     [7] system:catch_with_backtrace('<garbage_collected>', '<garbage_collected>', '<garbage_collected>')
ERROR: 
ERROR: Use the --stack_limit=size[KMG] command line option or
ERROR: ?- set_prolog_flag(stack_limit, 2_147_483_648). to double the limit.
JanWielemaker commented 2 months ago

Thanks. Reproduces. Seems like a left over of the big internal data rewrite :cry:

matko commented 2 months ago

With commit bab0e6d I get the proper error. No more segfault. Thanks!