Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Swi-Prolog - PROLOG SYSTEM ERROR - While in 13x-th garbage collection

80 views
Skip to first unread message

oleh.lo...@gmail.com

unread,
Feb 14, 2013, 7:38:48 AM2/14/13
to
Dear Community,


an error like this one is a bit scary, especially when it happens in:

- While in 138-th garbage collection
- While in 137-th garbage collection


all the times I can catch it.


What I'm doing in my "execute_goal" wrapper is: after goal is executes - just a "garbage_collect and one with atoms.



Can you please hint on what is going there and why is there always 137th or 138th (never 140th or 65535th) ?


Thank you
Oleh


[PROLOG SYSTEM ERROR: Thread 3
Mismatch in down phase: dest = 00000000172E84C8, gBase = 00000000172E84C0

[While in 138-th garbage collection]


PROLOG STACK:
(11): system:$garbage_collect/1
(9): execute:stack_test/0
(8): ignore/1
(7): system:$c_call_prolog/0

(6): system:setup_call_catcher_cleanup/4
(2): system:catch/3
(0): system:$c_call_prolog/0
]

[pid=3400] Action?

Jan Wielemaker

unread,
Feb 14, 2013, 11:31:16 AM2/14/13
to
On 2013-02-14, oleh.lo...@gmail.com <oleh.lo...@gmail.com> wrote:
> Dear Community,
>
> an error like this one is a bit scary, especially when it happens in:
>
> - While in 138-th garbage collection
> - While in 137-th garbage collection
>
> all the times I can catch it.

Catch it?? It calls systemError(), which exits the system after
printing the information. Of course, on some systems it isn't too
hard to intercept these functions. The error however tells that there
is a consistency check mismatch in the garbage collector. That can in
theory indicate an error in the garbage collector, but in most cases
it is a user-supplied or sometimes built-in foreign predicate that
makes illegal calls on the API and causes the Prolog stacks to
contain invalid data.

> What I'm doing in my "execute_goal" wrapper is: after goal is executes - just a "garbage_collect and one with atoms.
>
> Can you please hint on what is going there and why is there always 137th or 138th (never 140th or 65535th) ?

I guess because something bad tends to happen at that point in time.

This is kind of hard to debug. First of all get the latest version if you
happen to be way back. It might be fixed. Second, recompile the core
system using -DSECURE_GC (edit the Makefile, COFLAGS variable). That adds
a lot more checks to GC, including a consistency check of the data before
and after GC. Get the crash and use a debugger to check whether it found
the consistency errors before or after GC. If it is after, it is most likely
a GC bug, but that is rare. If it is before, insert tactical calls to
checkStacks(NULL) into the C code. You can also call that from Prolog as
'$check_stacks'(Where), where Where you can use to identify the test. If
Where is not an atom, the test is executed silently.

Common errors are failure to initialise term_t handles, using term_t handles
that are out of scope, not checking return values from the PL__* functions
which may lead to ignoring errors and continuing with the invalid state.

Cheers --- Jan

oleh.lo...@gmail.com

unread,
Feb 14, 2013, 1:24:04 PM2/14/13
to J.Wiel...@invalid.invalid
Hello Jan,

thank you for answering. I'm using SwiPl 5.10.0. So, will update soon :-) btw when is the next release scheduled?


Also, I will recompile and test as you advised.

here is a wrapper predicate I was using for a goal execution:



execute_int(Module, Goal) :-
functor(Goal, Predicate, Arity),
ignore(stack_test),
call_cleanup(do_execute(Module, Goal, Predicate/Arity),
ignore(stack_test)).



stack_test :-
garbage_collect_atoms,
garbage_collect,
'$clean_history'.



Now, removing that ignore(stack_test) call makes the picture better.



Thank you & best regards,
Oleh



On Thursday, February 14, 2013 5:31:16 PM UTC+1, Jan Wielemaker wrote:

Jan Wielemaker

unread,
Feb 14, 2013, 2:18:30 PM2/14/13
to
> Hello Jan,
>
> thank you for answering. I'm using SwiPl 5.10.0. So, will update soon :-) btw when is the next release scheduled?

I don't know. Surely, 6.2 (stable) and 6.3 (devel) are out quite a
while, and surely a couple of things that could cause this have been
fixed. Of course, this doesn't help if your C++ code is the culprit.

Cheers --- Jan

Oleh

unread,
Feb 21, 2013, 3:12:04 AM2/21/13
to J.Wiel...@invalid.invalid
Hi Jan,


sure, will move to the 6.2.x.


I'm still wondering why is that trace enters interactive mode? offering only two options: abort and exit to top-level. either of them is "killing" my host app.

Cheers
Oleh



On Thursday, February 14, 2013 8:18:30 PM UTC+1, Jan Wielemaker wrote:

Jan Wielemaker

unread,
Feb 21, 2013, 5:31:08 AM2/21/13
to
On 2013-02-21, Oleh <oleh.lo...@gmail.com> wrote:
> Hi Jan,
>
>
> sure, will move to the 6.2.x.
>
>
> I'm still wondering why is that trace enters interactive mode? offering only two options: abort and exit to top-level. either of them is "killing" my host app.

Not entirely sure what you are talking about. Possibly sysError(),
which is called if some internal error happens. This indeed allows
for abort and exit (not to toplevel, but exit the program). Typically,
there is no safe way to proceed. In many cases, these errors are the
result of memory corruption. It was made interactive to allow you
attaching a debugger to the still living process. Maybe it is better
to simply abort by default because a growing number of applications
runs as unattended server. Others embed Prolog. I have always
seen that as a mistake :-)

Cheers --- Jan

Oleh

unread,
Feb 21, 2013, 7:07:16 AM2/21/13
to

On Thursday, February 21, 2013 11:31:08 AM UTC+1, Jan Wielemaker wrote:
>
> Not entirely sure what you are talking about. Possibly sysError(),
>
> which is called if some internal error happens. This indeed allows
>
> for abort and exit (not to toplevel, but exit the program). Typically,
>
> there is no safe way to proceed. In many cases, these errors are the
>
> result of memory corruption. It was made interactive to allow you
>
> attaching a debugger to the still living process. Maybe it is better
>
> to simply abort by default because a growing number of applications
>
> runs as unattended server. Others embed Prolog. I have always
>
> seen that as a mistake :-)
>
>
>
> Cheers --- Jan
>
>
>
Indeed, it's a sysError... I'd better check my c interface :) as terms are prepared there...


Thanks for the hint!

Cheers
Oleh

Oleh

unread,
Feb 21, 2013, 11:27:52 AM2/21/13
to
On Thursday, February 14, 2013 8:18:30 PM UTC+1, Jan Wielemaker wrote:
>
> I don't know. Surely, 6.2 (stable) and 6.3 (devel) are out quite a
>
> while, and surely a couple of things that could cause this have been
>
> fixed. Of course, this doesn't help if your C++ code is the culprit.
>
>
>
> Cheers --- Jan



OMG, Jan.... so many changes in 6.2.6 :-) and so many checks on saved-state build... already finding tons of warnings.


well, thats definitely cool! but, a simple upgrade didnt worked... as it was with 6.0.2 -- I still have a 5.10 ;)

I should check this version better with care :)



Just wondering where are .pdb filed? :) could still find them in older versione, like 6.0.2. is it due to the switch to "mingw"?


Cheers
Oleh



Jan Wielemaker

unread,
Feb 21, 2013, 1:32:44 PM2/21/13
to
On 2013-02-21, Oleh <oleh.lo...@gmail.com> wrote:
> Just wondering where are .pdb filed? :) could still find them in older versione, like 6.0.2. is it due to the switch to "mingw"?

MinGW doesn't produce .pdb files. I could change the compilation options
to include debugging info into the executables, but that makes them a
bit big. Also, MinGW and Microsoft VC don't play nice wrt to the
debugger. Basically, the MS debugger doesn't debug MinGW executables,
nor the other way around (I'm told, never tried).

This is a bit annoying. I have a fairly good development environment
hosted on Linux. SWI-Prolog is compiled with the MinGW cross-compiler
under Linux. This directory is made available as a shared folder to a
VirtualBox virtual machine running Windows 7. Then, I do debugging in
Windows using gdb. I guess you can also turn this around and use a
Windows host with a VirtualBox VM with Linux to compile SWI-Prolog.

You can also compile SWI-Prolog using MinGW on Windows, but you need
lots of patience.

The good news is that the MinGW compiled version is about 20% faster
than the VC8 version :-)

Cheers --- Jan
Message has been deleted

Jan Wielemaker

unread,
May 2, 2013, 4:04:32 AM5/2/13
to
On 2013-04-30, Oleh <oleh.lo...@gmail.com> wrote:
> I took me some time to catch it with some useful output.

Good to be able to generate a call stack. The bad news is that call
stacks rarely help in debugging GC issues. This is because the
damage generally happened long before the actual crash :-(

> Here is the call stack (its windows), I have used swi-prolog-6.0.2 (still need to get to 6.2.6 ... I know, but soon :)
>
> Can you please advise or hint why is it that prolog is not throwing any Exception? The PL_call_predicate has "PL_Q_NODEBUG | PL_Q_CATCH_EXCEPTION" flags, as of my understanding I should be able to catch it after the call?

That only catches nice Prolog exceptions. Here, you are in unforeseen land.

The first step would be to try the current development releases. Quite a
few bugs have been fixed (e.g. 6.3.14). The second step is to package the
whole stuff, such that it can be reproduced and contact bu...@swi-prolog.org
(include the code if it is small and no secret, otherwise we'll find some
way to transfer it and/or keep it secret).

If you want to go the whole way yourself, the first step is to recompile
after adding -DSECURE_GC to the COFLAGS in Makefile. Quite likely, that
will tell us that that there is a memory inconsistency when GC starts.
Next, the typical process is to insert additional calls to checkStacks(NULL)
at meaningful places in the source until you know what is corrupting the
stacks. This is a somewhat tricky process because checkStacks() is
rather expensive, so you have to be careful where to add it not to make
you wait for hours for the next crash. Then, there are built-in
predicates that deliberately do things that cause the stacks to
temporary contain invalid Prolog data, so you should not call
checkStacks there. Anyway, most often it is a built in predicate
doing this and if you can checks the stacks to be ok at entry and
broken at exit, you are getting close.

But, again, try 6.3.14 first ...

Success --- Jan

>
> Thank you!
>
> Cheers
> Oleh
>
> -------------
>
>> ntdll.dll!0000000076ef15da()
> [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
> ntdll.dll!0000000076ec418b()
> msvcr90.dll!00000000741e1b8b()
> swipl.dll!PL_halt(int status=0x20200080) Line 3772 + 0x8 bytes C
> swipl.dll!vsysError(const char * fm=0x0000000000000000, char * args=0x000000001f5c9dc0) Line 1471 C
> swipl.dll!sysError(const char * fm=0x0000000019074328, ...) Line 1385 C
> swipl.dll!sweep_stacks(vm_state * state=0x00000000204d04b0) Line 2606 C
> swipl.dll!collect_phase(vm_state * state=0x0000000020200080, unsigned __int64 * * saved_bar_at=0x0000000000000000) Line 2894 C
> swipl.dll!garbageCollect() Line 3759 C
> swipl.dll!ensureGlobalSpace(unsigned __int64 cells=0x000000001f5ca3a0, int flags=0x000000dd) Line 3942 C
> swipl.dll!prolog_list_to_sort_list(unsigned __int64 t=0x000000001f5c2db0, int remove_dups=0x000000de, int key=0x00000001, List_Record * * lp=0x000000001f5ca3d0, unsigned __int64 * * end=0x00000000211eeba8) Line 349 + 0xe bytes C
> swipl.dll!pl_nat_sort(unsigned __int64 in=0x00000000000000dd, unsigned __int64 out=0x0000000000000021, int remove_dups=0x18f70000, int compare_keys=0x20200080, PL_local_data * __PL_ld=0x0000000020200080) Line 425 + 0x28 bytes C
> swipl.dll!pl_sort2_va(unsigned __int64 PL__t0=0x0000000018f70000, int PL__ac=0x20200080, foreign_context * PL__ctx=0x0000000018e58910) Line 442 + 0x15 bytes C
> swipl.dll!PL_next_solution(unsigned __int64 qid=0x0000000000000021) Line 3379 C
> swipl.dll!PL_call_predicate(module * ctx=0x00000000e03471a7, int flags=0x211ef0c0, procedure * pred=0x00000000e03471a7, unsigned __int64 h0=0x00000000211ef188) Line 3468 C
> libmypl.dll!000007fefab852eb()
>
> -------------
>
>

Oleh

unread,
May 2, 2013, 8:50:48 AM5/2/13
to
On Thursday, May 2, 2013 10:04:32 AM UTC+2, Jan Wielemaker wrote:
Hello Jan

thank you for your reply, actually weird things happend with my posting in this group (went in timeout and thus didnot posted one more msg... sorry about the mess) here it is---


I have followed your suggestion.


after compiling and running in DEBUG/SECURE_GC I have following assertion warnings: assert(s == fr->size);

in the file: pl-fli.c

* line: 175 (in PL_new_term_refs__LD)
* line: 198 (in new_term_ref)

so that the 's' value is always more then the one in 'fr->size'. Ex (s:23 fr->size:22), (s:22 fr->size:21), (s:21 fr->size:20), (s:16 fr->size:15)...


How can I interpret this? Or what it means?


My call stack is as follows:

- PL_open_foreign_frame
- termToPass = PL_new_term_refs(2)
- termGoal = termToPass+1;
- if (!PL_chars_to_term(mod, termToPass)) {...
- if ( PL_call_predicate(NULL, plg_call_pred_flags, global_PredToCall, termToPass) ) {...
- PL_discard_foreign_frame

is seems (again can be that printf is not right in the place), but it seems that "assertion error" happens in or during PL_call_predicate (and not in the explicit call of PL_new_term_refs(2)



---

Sure, I will try with the new branch. Interesting is that the assertion happens with 6.0 but it didnt occurred in 5.10. but, again it may be only my setup/test data.



Cheers
Oleh

Jan Wielemaker

unread,
May 2, 2013, 2:32:04 PM5/2/13
to
On 2013-05-02, Oleh <oleh.lo...@gmail.com> wrote:
> Hello Jan
>
> thank you for your reply, actually weird things happend with my posting in this group (went in timeout and thus didnot posted one more msg... sorry about the mess) here it is---
>
>
> I have followed your suggestion.
>
>
> after compiling and running in DEBUG/SECURE_GC I have following assertion warnings: assert(s == fr->size);
>
> in the file: pl-fli.c
>
> * line: 175 (in PL_new_term_refs__LD)
> * line: 198 (in new_term_ref)
>
> so that the 's' value is always more then the one in 'fr->size'. Ex (s:23 fr->size:22), (s:22 fr->size:21), (s:21 fr->size:20), (s:16 fr->size:15)...
>
>
> How can I interpret this? Or what it means?

At least as something that may well explain GC errors. Is this with the old
version or the 6.3.x version?

Otherwise, I have little clue. Not sure you can mess this up easily through
the external interface.

> My call stack is as follows:
>
> - PL_open_foreign_frame
> - termToPass = PL_new_term_refs(2)
> - termGoal = termToPass+1;
> - if (!PL_chars_to_term(mod, termToPass)) {...
> - if ( PL_call_predicate(NULL, plg_call_pred_flags, global_PredToCall, termToPass) ) {...
> - PL_discard_foreign_frame

That is more a sequence than a stack :-) Looks ok to me. Where in this
sequence does the inconsistency appear?

> is seems (again can be that printf is not right in the place), but it seems that "assertion error" happens in or during PL_call_predicate (and not in the explicit call of PL_new_term_refs(2)

Not sure how to interpret that. Normally, gdb should tell you.

> Sure, I will try with the new branch. Interesting is that the assertion happens with 6.0 but it didnt occurred in 5.10. but, again it may be only my setup/test data.

Hard to make sense out of this. It is possible that inconsistency is
only temporary and if no GC happens at that time, there is no problem.
Many things changed in that period. Bugs were removed and new ones
appeared :-(

Cheers --- Jan

Oleh

unread,
May 16, 2013, 3:46:21 AM5/16/13
to
On Thursday, May 2, 2013 8:32:04 PM UTC+2, Jan Wielemaker wrote:
> On 2013-05-02, Oleh wrote:
>
> > Hello Jan
>
> >
>
> > thank you for your reply, actually weird things happend with my posting in this group (went in timeout and thus didnot posted one more msg... sorry about the mess) here it is---
>
> >
>
> >
>
> > I have followed your suggestion.
>
> >
>
> >
>
> > after compiling and running in DEBUG/SECURE_GC I have following assertion warnings: assert(s == fr->size);
>
> >
>
> > in the file: pl-fli.c
>
> >
>
> > * line: 175 (in PL_new_term_refs__LD)
>
> > * line: 198 (in new_term_ref)
>
> >
>
> > so that the 's' value is always more then the one in 'fr->size'. Ex (s:23 fr->size:22), (s:22 fr->size:21), (s:21 fr->size:20), (s:16 fr->size:15)...
>
> >
>
> >
>
> > How can I interpret this? Or what it means?
>
>
>
> At least as something that may well explain GC errors. Is this with the old
>
> version or the 6.3.x version?
>

on the older 6.0.2 version

>
> Otherwise, I have little clue. Not sure you can mess this up easily through
>
> the external interface.
>
>
>
> > My call stack is as follows:
>
> >
>
> > - PL_open_foreign_frame
>
> > - termToPass = PL_new_term_refs(2)
>
> > - termGoal = termToPass+1;
>
> > - if (!PL_chars_to_term(mod, termToPass)) {...
>
> > - if ( PL_call_predicate(NULL, plg_call_pred_flags, global_PredToCall, termToPass) ) {...
>
> > - PL_discard_foreign_frame
>
>
>
> That is more a sequence than a stack :-) Looks ok to me. Where in this
>
> sequence does the inconsistency appear?
>
>

yes :) it is the sequence :) and inconsistency appearing int the "PL_call_predicate" iff "garbageCollect" take place.


>
> > is seems (again can be that printf is not right in the place), but it seems that "assertion error" happens in or during PL_call_predicate (and not in the explicit call of PL_new_term_refs(2)
>
>
>
> Not sure how to interpret that. Normally, gdb should tell you.
>
>
>
> > Sure, I will try with the new branch. Interesting is that the assertion happens with 6.0 but it didnt occurred in 5.10. but, again it may be only my setup/test data.
>
>
>
> Hard to make sense out of this. It is possible that inconsistency is
>
> only temporary and if no GC happens at that time, there is no problem.
>
> Many things changed in that period. Bugs were removed and new ones
>
> appeared :-(
>
>
>
> Cheers --- Jan

Thanks & Cheers
Oleh

Jan Wielemaker

unread,
May 16, 2013, 6:05:08 AM5/16/13
to
On 2013-05-16, Oleh <oleh.lo...@gmail.com> wrote:
> On Thursday, May 2, 2013 8:32:04 PM UTC+2, Jan Wielemaker wrote:
>> version or the 6.3.x version?
>
> on the older 6.0.2 version

First upgrade?

>> Otherwise, I have little clue. Not sure you can mess this up easily through
>>
>> the external interface.
>>
>>
>>
>> > My call stack is as follows:
>>
>> >
>>
>> > - PL_open_foreign_frame
>>
>> > - termToPass = PL_new_term_refs(2)
>>
>> > - termGoal = termToPass+1;
>>
>> > - if (!PL_chars_to_term(mod, termToPass)) {...
>>
>> > - if ( PL_call_predicate(NULL, plg_call_pred_flags, global_PredToCall, termToPass) ) {...
>>
>> > - PL_discard_foreign_frame
>>
>>
>>
>> That is more a sequence than a stack :-) Looks ok to me. Where in this
>>
>> sequence does the inconsistency appear?
>>
>>
>
> yes :) it is the sequence :) and inconsistency appearing int the "PL_call_predicate" iff "garbageCollect" take place.

Call checkStacks(NULL) before the PL_call_predicate() to verify the state (requires -DSECURE_GC)

Cheers --- Jan

0 new messages