Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String leak? #162

Closed
guregu opened this issue Apr 21, 2023 · 18 comments
Closed

String leak? #162

guregu opened this issue Apr 21, 2023 · 18 comments

Comments

@guregu
Copy link
Contributor

guregu commented Apr 21, 2023

Seems like some strings aren't getting freed. I tried bisecting it but it happens with v2.0.0 as well.

% test.pl

% these seem to leak
bad1(_).
bad2(X) :- X = "test".

% this is ok
ok("test").
$ valgrind --leak-check=full ./tpl -t -f test.pl -g 'bad2("test"),halt'                  
==13852== Memcheck, a memory error detector
==13852== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13852== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==13852== Command: ./tpl -t -f test.pl -g bad2("test"),halt
==13852== 
 [0:f0:fp:1:cp0:sp0:hp0] CALL bad2("test")
 [1:f1:fp:2:cp0:sp1:hp0] CALL "test"="test"
 [2:f1:fp:2:cp0:sp1:hp0] EXIT "test"="test"
 [3:f1:fp:2:cp0:sp1:hp0] EXIT bad2("test")
 [4:f0:fp:1:cp0:sp0:hp0] CALL halt
==13852== 
==13852== HEAP SUMMARY:
==13852==     in use at exit: 21 bytes in 1 blocks
==13852==   total heap usage: 4,724 allocs, 4,723 frees, 22,072,110 bytes allocated
==13852== 
==13852== 21 bytes in 1 blocks are definitely lost in loss record 1 of 1
==13852==    at 0x4875058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==13852==    by 0x161D6F: tokenize (parser.c:3453)
==13852==    by 0x15FF17: tokenize (parser.c:3042)
==13852==    by 0x1621EB: run (parser.c:3486)
==13852==    by 0x1B14D3: pl_eval (prolog.c:122)
==13852==    by 0x113227: main (tpl.c:266)
==13852== 
==13852== LEAK SUMMARY:
==13852==    definitely lost: 21 bytes in 1 blocks
==13852==    indirectly lost: 0 bytes in 0 blocks
==13852==      possibly lost: 0 bytes in 0 blocks
==13852==    still reachable: 0 bytes in 0 blocks
==13852==         suppressed: 0 bytes in 0 blocks
==13852== 
==13852== For lists of detected and suppressed errors, rerun with: -s
==13852== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

(Note to self, maybe this?)

foo(V) :- fail.
foo(V) :- true.
@infradig
Copy link
Contributor

infradig commented Apr 21, 2023 via email

@infradig
Copy link
Contributor

infradig commented Apr 21, 2023 via email

@guregu
Copy link
Contributor Author

guregu commented Apr 21, 2023

Hmm, that's odd. I'm on Ubuntu 22 (in a VM).

Linux ubuntu 6.1.24-orbstack-00127-g1be790b8ece0 #1 SMP Tue Apr 18 04:45:38 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

Let me see what my other setups report.

@guregu
Copy link
Contributor Author

guregu commented Apr 21, 2023

I think this is an error on my part, sorry about that. Tried it on Ubuntu 20 and fresh 22 and it's fine.
I'll double check and then close this.

@guregu
Copy link
Contributor Author

guregu commented Apr 21, 2023

How about this one? I think I got them mixed up.

% test2.pl

foo(_) :- fail.
foo(_) :- true.
$ valgrind --leak-check=full ./tpl -t -f test2.pl -g 'foo("x"),halt'
==4052== Memcheck, a memory error detector
==4052== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4052== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==4052== Command: ./tpl -t -f test2.pl -g foo("x"),halt
==4052==
[user:1:f0:fp:1:cp0:sp0:hp0:tp0] CALL foo("x")
[user:3:f1:fp:2:cp1:sp1:hp0:tp0] CALL fail
[user:5:f1:fp:2:cp1:sp1:hp0:tp0] FAIL fail
[user:7:f1:fp:2:cp0:sp1:hp0:tp0] CALL true
[user:9:f1:fp:2:cp0:sp1:hp0:tp0] EXIT true
[user:11:f1:fp:2:cp0:sp1:hp0:tp0] EXIT foo("x")
[user:13:f0:fp:2:cp0:sp1:hp0:tp0] CALL halt
==4052==
==4052== HEAP SUMMARY:
==4052==     in use at exit: 18 bytes in 1 blocks
==4052==   total heap usage: 19,701 allocs, 19,700 frees, 275,555,898 bytes allocated
==4052==
==4052== 18 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4052==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4052==    by 0x17D621: tokenize (parser.c:3493)
==4052==    by 0x17AB5F: tokenize (parser.c:3081)
==4052==    by 0x17DBE4: run (parser.c:3526)
==4052==    by 0x1D9AD9: pl_eval (prolog.c:127)
==4052==    by 0x1175D7: main (tpl.c:280)
==4052==
==4052== LEAK SUMMARY:
==4052==    definitely lost: 18 bytes in 1 blocks
==4052==    indirectly lost: 0 bytes in 0 blocks
==4052==      possibly lost: 0 bytes in 0 blocks
==4052==    still reachable: 0 bytes in 0 blocks
==4052==         suppressed: 0 bytes in 0 blocks
==4052==
==4052== For lists of detected and suppressed errors, rerun with: -s
==4052== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

$ ./tpl --version
Trealla Prolog (c) Infradig 2020-2023, v2.14.39

infradig added a commit that referenced this issue Apr 22, 2023
@guregu
Copy link
Contributor Author

guregu commented Apr 22, 2023

Thanks, I can confirm the latest changes help (no longer seeing it in the test case).
Seems like there's something still lurking about that I can trigger with my wasm json toplevel stuff, but there's a lot going on there.

Here is the full thing. I'll do some more digging and try to come up with a small test case.

% pseudojson.pl

:- module(pseudojson, [json_chars/2, json_value/2]).

json_chars(JSON, Cs) :-
	ground(JSON),
	json(JSON),
	write_term_to_chars(JSON, [json(true)], Cs),
	!.
json_chars(JSON, Cs) :-
	string(Cs),
	read_term_from_chars(Cs, JSON, [json(true)]),
	ground(JSON),
	once(json(JSON)).

json_value(JSON, Value) :-
	once(json_value_(JSON, Value)).

json_value_(true, boolean(true)).
json_value_(false, boolean(false)).
json_value_(Cs, string(Cs)) :- json_string(Cs).
json_value_(N, number(N)) :- json_number(N).
% json_value_(K:V0, string(K)-V) :-
% 	var(V0), var(V),
% 	freeze(V0, once(json_value_(V0, V))),
% 	freeze(V, once(json_value_(V0, V))).
json_value_(K:V0, string(K)-V) :-
	once(json_value_(V0, V)),
	json_field(K:V0).
json_value_([], list([])).
json_value_(L0, list(L)) :-
	once(maplist(json_value_, L0, L)).
json_value_({}, pairs([])).
json_value_({Fields}, pairs(L)) :-
	is_list(L),
	once(maplist(json_value_, L0, L)),
	list_comma(L0, Fields).
json_value_({Fields}, pairs(L)) :-
	json_object({Fields}),
	list_comma(L0, Fields),
	once(maplist(json_value_, L0, L)).
json_value_(null, null).

% json_bool(X) :- var(X), freeze(X, json_bool(X)), !.
json_bool(true).
json_bool(false).

json_string(Cs) :-
	string(Cs).

json_number(N) :- number(N).

json_field(K:V) :-
	json_string(K),
	true.
	%once(json(V)).

json_object({}).
json_object({Fields}) :-
	apply_comma(json_field, Fields).

json_list(V) :- is_list(V).

% json(X) :- ground(X).
json(V) :- var(V).
json(V) :- nonvar(V), V = null.
json(V) :- json_bool(V).
json(V) :- json_string(V).
json(V) :- json_number(V).
json(V) :- json_object(V).
json(V) :- json_list(V).

member_comma(X, (H, _)) :- member_comma(X, H).
member_comma(X, (_, T)) :- !, member_comma(X, T).
member_comma(X, X).

list_comma([H|T1], (H, T2)) :- list_comma(T1, T2).
list_comma([X], X).

apply_comma(Goal, X) :- apply_comma(Goal, _, X).
apply_comma(Goal, X, (H, _)) :- call(Goal, H), apply_comma(Goal, X, H).
apply_comma(Goal, X, (_, T)) :- !, call(Goal, T), apply_comma(Goal, X, T).
apply_comma(Goal, X, X) :- call(Goal, X).

Query:

?- findall(_, pseudojson:json({"a":"b"}), _),halt.

Report:

$ valgrind --leak-check=full ./tpl -t -f pseudojson.pl -g 'findall(_, pseudojson:json({"a":"b"}), _),halt'
==25957== Memcheck, a memory error detector
==25957== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25957== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==25957== Command: ./tpl -t -f pseudojson.pl -g findall(_,\ pseudojson:json({"a":"b"}),\ _),halt
==25957== 
[user:1:f0:fp:1:cp0:sp2:hp0:tp0] CALL findall(_0,pseudojson:json({"a":"b"}),_1)
[user:3:f0:fp:1:cp1:sp4:hp23:tp2] EXIT findall(_0,pseudojson:json({"a":"b"}),_1)
[user:5:f0:fp:1:cp1:sp4:hp23:tp2] CALL pseudojson:json({"a":"b"})
[pseudojson:7:f0:fp:1:cp1:sp4:hp30:tp2] EXIT pseudojson:json({"a":"b"})
[pseudojson:9:f1:fp:2:cp2:sp5:hp30:tp3] CALL var({"a":"b"})
[pseudojson:11:f1:fp:2:cp2:sp5:hp30:tp3] FAIL var({"a":"b"})
[pseudojson:13:f1:fp:2:cp2:sp5:hp30:tp3] CALL nonvar({"a":"b"})
[pseudojson:15:f1:fp:2:cp2:sp5:hp30:tp3] EXIT nonvar({"a":"b"})
[pseudojson:17:f1:fp:2:cp2:sp5:hp30:tp3] CALL {"a":"b"}=null
[pseudojson:19:f1:fp:2:cp2:sp5:hp30:tp3] FAIL {"a":"b"}=null
[pseudojson:21:f1:fp:2:cp2:sp5:hp30:tp3] CALL json_bool({"a":"b"})
[pseudojson:23:f1:fp:2:cp2:sp5:hp30:tp3] CALL json_string({"a":"b"})
[pseudojson:25:f2:fp:3:cp2:sp6:hp30:tp3] CALL is_list_or_partial_list({"a":"b"})
[pseudojson:27:f2:fp:3:cp2:sp6:hp30:tp3] FAIL is_list_or_partial_list({"a":"b"})
[pseudojson:29:f1:fp:2:cp2:sp5:hp30:tp3] CALL json_number({"a":"b"})
[pseudojson:31:f2:fp:3:cp2:sp6:hp30:tp3] CALL number({"a":"b"})
[pseudojson:33:f2:fp:3:cp2:sp6:hp30:tp3] FAIL number({"a":"b"})
[pseudojson:35:f1:fp:2:cp2:sp5:hp30:tp3] CALL json_object({"a":"b"})
[pseudojson:37:f2:fp:3:cp2:sp6:hp30:tp3] CALL apply_comma(json_field,"a":"b")
[pseudojson:39:f3:fp:4:cp2:sp9:hp30:tp3] CALL apply_comma(json_field,_7,"a":"b")
[pseudojson:41:f4:fp:5:cp2:sp11:hp30:tp6] CALL call(json_field,"a":"b")
[pseudojson:43:f4:fp:5:cp3:sp11:hp37:tp6] EXIT call(json_field,"a":"b")
[pseudojson:45:f5:fp:6:cp3:sp13:hp37:tp6] CALL json_string("a")
[pseudojson:47:f6:fp:7:cp3:sp14:hp37:tp6] CALL is_list_or_partial_list("a")
[pseudojson:49:f6:fp:7:cp3:sp14:hp37:tp6] EXIT is_list_or_partial_list("a")
[pseudojson:51:f6:fp:7:cp3:sp14:hp37:tp6] EXIT json_string("a")
[pseudojson:53:f5:fp:7:cp3:sp14:hp37:tp6] CALL once(json("b"))
[pseudojson:55:f5:fp:7:cp4:sp14:hp42:tp6] EXIT once(json("b"))
[pseudojson:57:f7:fp:8:cp5:sp15:hp42:tp7] CALL var("b")
[pseudojson:59:f7:fp:8:cp5:sp15:hp42:tp7] FAIL var("b")
[pseudojson:61:f7:fp:8:cp5:sp15:hp42:tp7] CALL nonvar("b")
[pseudojson:63:f7:fp:8:cp5:sp15:hp42:tp7] EXIT nonvar("b")
[pseudojson:65:f7:fp:8:cp5:sp15:hp42:tp7] CALL "b"=null
[pseudojson:67:f7:fp:8:cp5:sp15:hp42:tp7] FAIL "b"=null
[pseudojson:69:f8:fp:9:cp5:sp16:hp42:tp7] CALL is_list_or_partial_list("b")
[pseudojson:71:f8:fp:9:cp5:sp16:hp42:tp7] EXIT is_list_or_partial_list("b")
[pseudojson:73:f8:fp:9:cp5:sp16:hp42:tp7] EXIT json_string("b")
[pseudojson:75:f5:fp:9:cp5:sp16:hp42:tp7] CALL '$prune'
[pseudojson:77:f5:fp:9:cp3:sp16:hp42:tp7] EXIT '$prune'
[pseudojson:79:f5:fp:9:cp3:sp16:hp42:tp7] EXIT json_string("a")
[pseudojson:81:f4:fp:9:cp3:sp16:hp42:tp7] CALL '$drop_barrier'
[pseudojson:83:f4:fp:9:cp2:sp16:hp42:tp7] EXIT '$drop_barrier'
[pseudojson:85:f4:fp:9:cp2:sp16:hp42:tp7] EXIT json_string(json_field)
[user:87:f0:fp:9:cp2:sp16:hp42:tp7] CALL '$queue'(1,_0)
[user:89:f0:fp:9:cp2:sp16:hp42:tp7] EXIT '$queue'(1,_0)
[user:91:f0:fp:9:cp2:sp16:hp42:tp7] CALL fail
[user:93:f0:fp:9:cp2:sp16:hp42:tp7] FAIL fail
[pseudojson:95:f1:fp:2:cp1:sp5:hp30:tp2] CALL json_list({"a":"b"})
[pseudojson:97:f2:fp:3:cp1:sp6:hp30:tp2] CALL is_list({"a":"b"})
[pseudojson:99:f2:fp:3:cp1:sp6:hp30:tp2] FAIL is_list({"a":"b"})
[user:101:f0:fp:1:cp0:sp4:hp23:tp2] REDO findall(_0,pseudojson:json({"a":"b"}),_1)
[user:103:f0:fp:1:cp0:sp5:hp26:tp3] EXIT findall(_0,pseudojson:json({"a":"b"}),[_4])
[user:105:f0:fp:1:cp0:sp5:hp26:tp3] CALL halt
==25957== 
==25957== HEAP SUMMARY:
==25957==     in use at exit: 36 bytes in 2 blocks
==25957==   total heap usage: 20,218 allocs, 20,216 frees, 277,473,540 bytes allocated
==25957== 
==25957== 36 bytes in 2 blocks are definitely lost in loss record 1 of 1
==25957==    at 0x4875058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==25957==    by 0x179F43: tokenize (parser.c:3493)
==25957==    by 0x177673: tokenize (parser.c:3064)
==25957==    by 0x1777A7: tokenize (parser.c:3081)
==25957==    by 0x1777A7: tokenize (parser.c:3081)
==25957==    by 0x17A4F3: run (parser.c:3526)
==25957==    by 0x1DAA5F: pl_eval (prolog.c:127)
==25957==    by 0x11658B: main (tpl.c:280)
==25957== 
==25957== LEAK SUMMARY:
==25957==    definitely lost: 36 bytes in 2 blocks
==25957==    indirectly lost: 0 bytes in 0 blocks
==25957==      possibly lost: 0 bytes in 0 blocks
==25957==    still reachable: 0 bytes in 0 blocks
==25957==         suppressed: 0 bytes in 0 blocks
==25957== 
==25957== For lists of detected and suppressed errors, rerun with: -s
==25957== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

$ ./tpl --version
Trealla Prolog (c) Infradig 2020-2023, v2.14.42

Changing findall/3 to once/1 avoids the leak, so it looks like the choice points from json/1 are the crux of the issue.

@guregu
Copy link
Contributor Author

guregu commented Apr 22, 2023

Might also be worth pointing out that you can trigger it without findall by querying pseudojson:json({"a":"b"}) from the toplevel as well.

@guregu
Copy link
Contributor Author

guregu commented Apr 22, 2023

Here's a much simpler test case:

% try3.pl

leak :- bad("doesnt_unify").
no_leak :- bad("test").

bad(V) :- bad_if_choicepoint(V).
bad(V) :- true. % commenting this out prevents the leak

bad_if_choicepoint(X) :- X = "test".
$ valgrind --leak-check=full ./tpl -t -f try3.pl -g 'leak,halt'
==4361== Memcheck, a memory error detector
==4361== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4361== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==4361== Command: ./tpl -t -f try3.pl -g leak,halt
==4361==
Warning: singleton: V, near try3.pl:7
[user:1:f0:fp:1:cp0:sp0:hp0:tp0] CALL leak
[user:3:f1:fp:2:cp0:sp0:hp0:tp0] CALL bad("doesnt_unify")
[user:5:f2:fp:3:cp1:sp1:hp0:tp1] CALL bad_if_choicepoint("doesnt_unify")
[user:7:f3:fp:4:cp1:sp2:hp0:tp1] CALL "doesnt_unify"="test"
[user:9:f3:fp:4:cp1:sp2:hp0:tp1] FAIL "doesnt_unify"="test"
[user:11:f2:fp:3:cp0:sp1:hp0:tp0] CALL true
[user:13:f2:fp:3:cp0:sp1:hp0:tp0] EXIT true
[user:15:f2:fp:3:cp0:sp1:hp0:tp0] EXIT bad("doesnt_unify")
[user:17:f0:fp:3:cp0:sp1:hp0:tp0] CALL halt
==4361==
==4361== HEAP SUMMARY:
==4361==     in use at exit: 29 bytes in 1 blocks
==4361==   total heap usage: 19,794 allocs, 19,793 frees, 275,743,226 bytes allocated
==4361==
==4361== 29 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4361==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4361==    by 0x17D63F: tokenize (parser.c:3493)
==4361==    by 0x17AB7D: tokenize (parser.c:3081)
==4361==    by 0x1646F8: load_fp (module.c:1743)
==4361==    by 0x165482: load_file (module.c:1914)
==4361==    by 0x1D9D84: pl_consult (prolog.c:198)
==4361==    by 0x11750C: main (tpl.c:264)
==4361==
==4361== LEAK SUMMARY:
==4361==    definitely lost: 29 bytes in 1 blocks
==4361==    indirectly lost: 0 bytes in 0 blocks
==4361==      possibly lost: 0 bytes in 0 blocks
==4361==    still reachable: 0 bytes in 0 blocks
==4361==         suppressed: 0 bytes in 0 blocks
==4361==
==4361== For lists of detected and suppressed errors, rerun with: -s
==4361== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

$ ./tpl --version
Trealla Prolog (c) Infradig 2020-2023, v2.14.42

infradig added a commit that referenced this issue Apr 22, 2023
@infradig
Copy link
Contributor

infradig commented Apr 22, 2023 via email

@guregu
Copy link
Contributor Author

guregu commented Apr 22, 2023

devel branch helps a bunch, thanks! The latest test case looks good now, and the memory usage after spamming a bunch of queries is much improved.
I think there's still something remaining, but not sure if it's related to this or my stuff. I will see if I can isolate it.

@guregu
Copy link
Contributor Author

guregu commented Apr 22, 2023

Here's another one, with two cases.

Ran it against the version just released.

% try4.pl

leak2 :-
    findall(_, inner, _).

leak3 :-
    findall(_, inner2, _).

% calling inner/0 from the toplevel is fine
inner :-
    do_something("abcdefg")
    ; do_something("fooobarbaz").

% calling inner2/0 from the toplevel seems to leak "qux" (but not the other strings)?
inner2 :-
    do_something_else("abcdefg")
    ; do_something_else("fooobarbaz").

do_something(_).

do_something_else(X) :- X \= "qux".
$ valgrind --leak-check=full ./tpl -t -f try4.pl -g 'leak2,halt'                        
==29677== Memcheck, a memory error detector
==29677== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29677== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==29677== Command: ./tpl -t -f try4.pl -g leak2,halt
==29677== 
[user:1:f0:fp:1:cp0:sp0:hp0:tp0] CALL leak2
[user:3:f1:fp:2:cp1:sp4:hp11:tp2] CALL inner
[user:5:f2:fp:3:cp2:sp4:hp15:tp2] CALL do_something("abcdefg")
[user:7:f3:fp:4:cp2:sp5:hp15:tp3] EXIT do_something("abcdefg")
[user:9:f2:fp:4:cp2:sp5:hp15:tp3] EXIT do_something(_0)
[user:11:f2:fp:3:cp1:sp4:hp15:tp2] CALL do_something("fooobarbaz")
[user:13:f3:fp:4:cp1:sp5:hp15:tp3] EXIT do_something("fooobarbaz")
[user:15:f1:fp:2:cp0:sp6:hp16:tp3] EXIT leak2
==29677== 
==29677== HEAP SUMMARY:
==29677==     in use at exit: 24 bytes in 1 blocks
==29677==   total heap usage: 19,645 allocs, 19,644 frees, 276,304,527 bytes allocated
==29677== 
==29677== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1
==29677==    at 0x4875058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==29677==    by 0x178F2B: tokenize (parser.c:3493)
==29677==    by 0x17678F: tokenize (parser.c:3081)
==29677==    by 0x1617BB: load_fp (module.c:1743)
==29677==    by 0x1622CF: load_file (module.c:1914)
==29677==    by 0x1D8D3B: pl_consult (prolog.c:198)
==29677==    by 0x1164C3: main (tpl.c:264)
==29677== 
==29677== LEAK SUMMARY:
==29677==    definitely lost: 24 bytes in 1 blocks
==29677==    indirectly lost: 0 bytes in 0 blocks
==29677==      possibly lost: 0 bytes in 0 blocks
==29677==    still reachable: 0 bytes in 0 blocks
==29677==         suppressed: 0 bytes in 0 blocks
==29677== 
==29677== For lists of detected and suppressed errors, rerun with: -s
==29677== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

$ ./tpl --version                                                                       
Trealla Prolog (c) Infradig 2020-2023, v2.14.44

@infradig
Copy link
Contributor

infradig commented Apr 22, 2023 via email

@guregu
Copy link
Contributor Author

guregu commented Apr 22, 2023

That is exciting :-)

infradig added a commit that referenced this issue Apr 23, 2023
@guregu
Copy link
Contributor Author

guregu commented Apr 23, 2023

Latest changes are looking great. Ran a stress test against the wasm stuff (Go lib) and no wasm memory growth after 350,000+ queries on the same *prolog. I will declare it leak free now :)

BTW I'd be happy to test the findall changes you mentioned if you want to put it in an experimental branch sometime.

Many thanks!

@guregu guregu closed this as completed Apr 23, 2023
@guregu
Copy link
Contributor Author

guregu commented May 11, 2023

Looks like this is back. I ran a git bisect and it lead to commit 2a95bd0.
Reverting it seems to fix.

You can check it against the test case here: #162 (comment) (leak2/0 and leak3/0 both trigger it)

$ valgrind --leak-check=full ./tpl -f try4 -g 'leak2,halt'                                                      
==8679== Memcheck, a memory error detector
==8679== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8679== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==8679== Command: ./tpl -f try4 -g leak2,halt
==8679== 
==8679== 
==8679== HEAP SUMMARY:
==8679==     in use at exit: 24 bytes in 1 blocks
==8679==   total heap usage: 25,490 allocs, 25,489 frees, 106,792,046 bytes allocated
==8679== 
==8679== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8679==    at 0x4875058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==8679==    by 0x17B24B: tokenize (parser.c:3479)
==8679==    by 0x178AAF: tokenize (parser.c:3067)
==8679==    by 0x163A0B: load_fp (module.c:1725)
==8679==    by 0x16451F: load_file (module.c:1896)
==8679==    by 0x1DDD7B: pl_consult (prolog.c:202)
==8679==    by 0x116583: main (tpl.c:264)
==8679== 
==8679== LEAK SUMMARY:
==8679==    definitely lost: 24 bytes in 1 blocks
==8679==    indirectly lost: 0 bytes in 0 blocks
==8679==      possibly lost: 0 bytes in 0 blocks
==8679==    still reachable: 0 bytes in 0 blocks
==8679==         suppressed: 0 bytes in 0 blocks
==8679== 
==8679== For lists of detected and suppressed errors, rerun with: -s
==8679== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

$ ./tpl --version                                                                                               
Trealla Prolog (c) Infradig 2020-2023, v2.15.13

@guregu guregu reopened this May 11, 2023
infradig added a commit that referenced this issue May 11, 2023
@guregu
Copy link
Contributor Author

guregu commented May 11, 2023

Looks good now, thanks!

@guregu
Copy link
Contributor Author

guregu commented May 31, 2023

The leak I mentioned here is still happening: #170 (comment)

Reverting 4f47e93 makes the leak go away, but probably not a proper fix.

@guregu
Copy link
Contributor Author

guregu commented Jun 14, 2023

Many thanks, confirmed everything looks good

@guregu guregu closed this as completed Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants