Set_breakpoint crash

sb(PI,Line,Id) :- 
   % get src file
   pi_head(PI,Head), clause(Head,_,Ref),
   clause_property(Ref,file(File)),
   % set breakpoint
   set_breakpoint(File,Line,1,Id).

8 ?- sb(mod:somepred/1,1229,I).
[...]received fatal signal 11 (segv)
C-stack trace labeled "crash":
  [0] save_backtrace() at :? [0x7f03031884f1]
  [1] print_c_backtrace() at :? [0x7f03031885ad]
  [2] sigCrashHandler() at :? [0x7f03031886bd]
  [3] __restore_rt() at sigaction.c:? [0x7f0302f3cda0]
  [4] pl_clause_from_source4_va() at pl-srcfile.c:? [0x7f03031499ca]
  [5] PL_next_solution___LD() at :? [0x7f0303191c02]
  [6] query_loop() at :? [0x7f03031d3d88]
  [7] prologToplevel() at :? [0x7f03031d3c1b]
  [8] PL_toplevel() at ??:? [0x7f03031e89eb]
  [9] swipl(+0x10b1) [0x55dfe77370b1]
  [10] __libc_start_main() at ??:? [0x7f0302f27b25]
  [11] swipl(+0x10ee) [0x55dfe77370ee]
Prolog stack:
  [13] system:$clause_from_source/4 [PC=1 in supervisor]
  [12] prolog_breakpoints:set_breakpoint/5 [PC=25 in clause 1]
  [10] sb/3 [PC=30 in clause 1]
  [9] $toplevel:toplevel_call/1 [PC=3 in clause 1]
  [8] $toplevel:stop_backtrace/2 [PC=4 in clause 1]
  [7] $tabling:$wfs_call/2 [PC=17 in clause 1]
  [5] $toplevel:$execute_goal2/3 [PC=31 in clause 1]
  [3] $toplevel:$query_loop/0 [PC=39 in clause 2]
  [2] $toplevel:$runtoplevel/0 [PC=19 in clause 1]
  [1] $toplevel:$toplevel/0 [PC=3 in clause 1]
  [0] system:$c_call_prolog/0 [PC=0 in top query clause]
Running on_halt hooks with status 139
Killing 1530697 with default signal handlers

I am getting a crash when trying to set a breakpoint; this happens with the graphical debugger also; it happens with one prolog source code file, unfortunately I can’t reproduce it with a smaller file, but hopefully the above gives enough information to track down the problem. Running the latest SWI-Prolog (8.5.4-13-g9d2babb2c).

No clue. I guess the best is to recompile for debugging. The should get us line numbers. Maybe that is enough. Otherwise we’ll need a debugger …

Here is the crash with line numbers

C-stack trace labeled "crash":
  [0] save_backtrace() at /tmp/swipl-devel/src/os/pl-cstack.c:331 [0x7f1362ecc74b]
  [1] print_c_backtrace() at /tmp/swipl-devel/src/os/pl-cstack.c:868 [0x7f1362eccfe3]
  [2] sigCrashHandler() at /tmp/swipl-devel/src/os/pl-cstack.c:908 [0x7f1362ecd15d]
  [3] alt_segv_handler() at /tmp/swipl-devel/src/pl-setup.c:753 [0x7f1362dcefe8]
  [4] __restore_rt() at sigaction.c:? [0x7f1362b28da0]
  [5] pl_clause_from_source4_va() at /tmp/swipl-devel/src/pl-srcfile.c:1819 [0x7f1362e14659]
  [6] PL_next_solution___LD() at /tmp/swipl-devel/src/pl-vmi.c:4585 [0x7f1362d05c9c]
  [7] query_loop() at /tmp/swipl-devel/src/pl-pro.c:147 [0x7f1362d9918e]
  [8] prologToplevel() at /tmp/swipl-devel/src/pl-pro.c:496 [0x7f1362d99e36]
  [9] PL_toplevel() at /tmp/swipl-devel/src/pl-fli.c:4558 [0x7f1362e9295a]
  [10] swipl(+0x11b9) [0x555f0f34d1b9]
  [11] __libc_start_main() at ??:? [0x7f1362b13b25]
  [12] swipl(+0x109e) [0x555f0f34d09e]
Prolog stack:
  [14] system:$clause_from_source/4 [PC=1 in supervisor]
  [13] prolog_breakpoints:set_breakpoint/5 [PC=25 in clause 1]
  [11] sb/3 [PC=30 in clause 1]
  [10] system:<meta-call>/1 [PC=8 in clause -1]
  [9] $toplevel:toplevel_call/1 [PC=3 in clause 1]
  [8] $toplevel:stop_backtrace/2 [PC=4 in clause 1]
  [7] $tabling:$wfs_call/2 [PC=17 in clause 1]
  [5] $toplevel:$execute_goal2/3 [PC=31 in clause 1]
  [3] $toplevel:$query_loop/0 [PC=39 in clause 2]
  [2] $toplevel:$runtoplevel/0 [PC=19 in clause 1]
  [1] $toplevel:$toplevel/0 [PC=3 in clause 1]
  [0] system:$c_call_prolog/0 [PC=0 in top query clause]

Seems like the problem is in pl_clause_from_source4_va() at /tmp/swipl-devel/src/pl-srcfile.c:1819 [0x7f1362e14659]

EDIT: in gdb cl is null which is causing the segfault. No idea why it is null though.

│  1818                                                                                                             │
│  >  1819          if ( cl->source_no == source_no )                                                               │
│     1820          { if ( ln >= (int)cl->line_no )                                                                 │
│     1821            { if ( !c || c->line_no < cl->line_no )       
[...]
Thread 1 "swipl" received signal SIGSEGV, Segmentation fault.
0x00007ffff7c5a659 in pl_clause_from_source4_va (PL__t0=231, PL__ac=4, PL__ctx=0x7fffffffd2a0) at /tmp/swipl-devel/src/pl-srcfile.c:1819
(gdb) print cl
$1 = (Clause) 0x0
(gdb)   

That should not be possible :frowning: So, most likely something more fundamental is wrong. Any way to reproduce this?

I tried to make a small reproducible version but it didn’t reproduce with the smaller source. I will try to bisect the code and see if I can make it reproducible with a small sample. It will most likely be some days.

It doesn’t need to be small. The way to find this is first to try enabling addresssanitizer (see CMAKE.md) and see whether we have to do with memory corruption. If not, I typically add a little C function that checks for the error condition and insert that at some places in the source to find where the issue is introduced. Can be tedious :frowning:

I’ll report when I have found some more info. Merry Christmas, and have a good time of rest!

Found some more information about this bug. In the original prolog source I have a few predicates that are dynamic/1 and thread_local/1:

  • If I comment out the thread_local/1 declaration and leave the predicates as dynamic/1 the bug disappears.
  • I tried to reduce it to a smaller piece of prolog source (with thread_local/1 declarations) but still could not make a small reproducible sample.
  • I’ll keep trying to make a reproducible version.

That rings a bell. Note that thread_local always implies dynamic. Pushed a fix. Can’t verify it fixes the crash, but it was surely wrong code and could explain a crash.

1 Like

Certainly! The patch fixes it, thanks!

1 Like