beneroth changed the topic of #picolisp to: PicoLisp language | The scalpel of software development | Channel Log: https://libera.irclog.whitequark.org/picolisp | Check www.picolisp.com for more information
brandelune has joined #picolisp
brandelune has quit [Quit: This computer has gone to sleep]
brandelune has joined #picolisp
brandelune has quit [Quit: This computer has gone to sleep]
theruran has joined #picolisp
brandelune has joined #picolisp
aw- has joined #picolisp
brandelune has quit [Quit: This computer has gone to sleep]
brandelune has joined #picolisp
cranium has joined #picolisp
<aw-> oh look, someone else located in Japan
<Regenaxer> Hi aw-!
<beneroth> Hi aw-, Regenaxer :)
<beneroth> Regenaxer, is it illegal to call 'isa with NIL as second argument? e.g. (isa '+Someclass NIL)
<Regenaxer> Hi beneroth! I think it is no problem with NIL
<beneroth> I've got a very weird bug involving for, recur and a cond with an isa
<Regenaxer> 'isa' always returns NIL if the VAL of the second arg is atomic
<beneroth> smells like corrupted stack
<Regenaxer> Can you post a minimal example?
<beneroth> (for Arg Args (recur (Arg) ...)) could be a problem, using the iterator variable in recur?
<beneroth> I try, it's pretty involved
<Regenaxer> This is no problem
<Regenaxer> Using Arg
theruran has quit [Quit: Connection closed for inactivity]
<beneroth> Regenaxer, I've got a heisebug :((
<beneroth> (cond ((pair Arg) ...) ...) -> segfaults
<beneroth> (cond ((not (atom Arg)) ...) ....) -> works
<Regenaxer> hehe
<beneroth> (cond ((and (out NIL (prinl "AAA")) (pair Arg) (out NIL (prinl "BBB"))) ...) ...) -> works
<Regenaxer> Crashes in 'pair'?
<Regenaxer> e.g. (trace 'pair)
<beneroth> (cond ((list? Arg) ...) ...) -> works
<beneroth> good idea, I test, thank you!
<beneroth> s/list?/lst?
<Regenaxer> T
<Regenaxer> But as it is heisen, trace may work or not :)
<Regenaxer> Does behavior change if you do (gc 999) before test?
<beneroth> trace works, shows pair returning, so it's not pair crashing
<beneroth> gc 999 changes behaviour... no segfault
<Regenaxer> OK, so it is a typical gc issue
<Regenaxer> typical for such heisenbugs
<Regenaxer> The reason lies before the crash happens
<beneroth> ah with gc it still crashes, just much later
<beneroth> yeah
<beneroth> corrupt stack
<Regenaxer> makes sense
<Regenaxer> not stack but heap
<Regenaxer> hard to localize
<beneroth> problem is... with testing I find the small code change, which introduced this segfault... but I fear it's only triggered here, the corruption is somewhere else (many possibilities) :/
<Regenaxer> Is it pil64?
<beneroth> yeah
<Regenaxer> Can you try pil21? It may behave differently
<Regenaxer> or give an error
brandelune has quit [Quit: This computer has gone to sleep]
<Regenaxer> Or does your code depend on pil64 somehow?
<beneroth> pil21 runtime would be ok, but I might use some deprecated code I must clean up. this is the reason I haven't switched yet (well time needed to do that).
<Regenaxer> I think usually only one point: "'arg' without arguments is not supported"
<Regenaxer> ah, and cases of env offset args to \eval' and 'run'
<Regenaxer> Do you have such cases?
<beneroth> I believe so, yes. in DSL's
<Regenaxer> I think switching to pil21 is really advisable
<beneroth> T
<Regenaxer> Best is to clean up the DSLs using (private) for all involved symbols
<Regenaxer> The offset args may remain
<Regenaxer> they apply to '@' only now
<beneroth> T
<beneroth> afk for lunch, bbl
<Regenaxer> cu :)
brandelune has joined #picolisp
brandelune has quit [Client Quit]
<tankf33der> Next task:
<Regenaxer> nice
beneroth_ has joined #picolisp
beneroth has quit [Ping timeout: 252 seconds]
beneroth_ has quit [Quit: Leaving]
beneroth has joined #picolisp
<beneroth> Regenaxer, I put multiple (gc) calls into the code now. the segfault happens at X iterations of a function call. that implies that the corruption happens (execution-timewise) nearby and likely not much earlier, right?
<Regenaxer> yes, usually a function being executed *while* next gc runs
<Regenaxer> Can you make a core dump?
<Regenaxer> ulimit -c unlimited
<Regenaxer> Then we see with gdb and bt where it happens
<Regenaxer> $ gdb pil21/bin/picolisp core
<Regenaxer> ...
<Regenaxer> (gdb) bt
<Regenaxer> ...
<Regenaxer> There are 2 possibilities
<Regenaxer> 1 it crashes *in* gc, then the heap was corrupted
<Regenaxer> 2 it crashes in some function whose data were wrongly collected
<Regenaxer> (2) is more helpful usually
<beneroth> thx, working on it
<Regenaxer> Let's hope we find it
<beneroth> I've enabled core dumping, but I cannot find the dump. Ubuntu 18.04. Internet says they are supposed to end up in /var/crash/
<Regenaxer> On Debian it is in ./core
<beneroth> so, I managed to create a dump
<Regenaxer> is it in current directory?
<beneroth> now it is
<beneroth> had to mess with systemd variables
<Regenaxer> $ gdb path/to/picoLisp/bin/picolisp core
<Regenaxer> I see
<beneroth> Program terminated with signal SIGSEGV, Segmentation fault.
<beneroth> #0 0x0000000000412e12 in doIsa ()
<beneroth> so this is case (2) ?
<Regenaxer> ok, directly in 'isa'
<Regenaxer> yes
<beneroth> yeah we circle back to my initial question...
<Regenaxer> means that the lists of lists in the class hierary is corrupted probably
<Regenaxer> 'isa' traverses the lists
<beneroth> the code iterating over a nested list, calling (isa) on atoms
<beneroth> atoms can be 'any
<beneroth> not necessarily class symbols
<Regenaxer> that's ok
<beneroth> maybe it's wrongly processed if the value of an atom looks like an class list?
<Regenaxer> Can it be numbers?
<beneroth> but happens to be a cons pair?
<beneroth> yes
<Regenaxer> Maybe numbers are not expected
<Regenaxer> isa looks at the values
<beneroth> (isa '+Foo Arg) -> (and (sym? Arg) (isa +Foo Arg)) and good?
<beneroth> yeah I see, would use it as a pointer
<Regenaxer> But I think numbers are ok too
<Regenaxer> should be checked
<Regenaxer> I think the heap is corrupted
<Regenaxer> the lists in the values
<beneroth> I fear so too
<Regenaxer> pil21 checks (ifn (symb? Z)
<Regenaxer> I think pil64 does the same
<Regenaxer> And if number were the problem it would crash reproducibly
<beneroth> when I e.g. put an boolean check on Arg (e.g. (unless Arg ...) or (cond ((not Arg) ...) ((isa '+Foo Arg) ...)) the segfault didn't occur
<Regenaxer> *numbers
<beneroth> I think so too. I quickly check the pil64 source
<Regenaxer> I do so too
<beneroth> num E # Symbol?
<beneroth> Line 971
<Regenaxer> exactly
<Regenaxer> yes, second arg
<Regenaxer> after Eval 'any'
<tankf33der> Beneroth: show me a code crashing
<beneroth> Regenaxer, when I do (sym?) before (isa) it crashes no more :(
<beneroth> tankf33der, thanks, a moment
<Regenaxer> Not sure, it is a heisenbug after all
<beneroth> T
<Regenaxer> You could (trace 'isa) to see the last call
<beneroth> I think it's only pseudo-random that the segfault happens here, the corruption happens somewhere else
<Regenaxer> yes
<beneroth> problem is, it's a quite embedded piece of code which much context data, not feasible to mock up nor share
<Regenaxer> the above pastebin does not crash here
<Regenaxer> in pil21
<beneroth> it probably entirely depends on the detailed structure of the Args list
<Regenaxer> also not in pil64 (Termux)
<Regenaxer> yeah
<Regenaxer> and memory situation
<beneroth> so you agree that the #works part should not have semantically any difference to the crashing variant (because 'isa implementation kinda does the same) and it must be a heisebug with a corrupted memory layout ?
<beneroth> so even more memory situation, not Args
<beneroth> ah btw. I do (gc) just before that code.
<Regenaxer> both versions look ok
<Regenaxer> Could use 'fish' probably
<beneroth> I think (gc) has nothing to do with the issue. maybe (gc) moves the corruption around, but not causing it, I would think
<tankf33der> How to run this code?
<tankf33der> Your pastebin code does not contain Args list inside
<beneroth> T. it is repeatedly called with another Args. deep nested lists.
<Regenaxer> right, so my test here was meaningless
<tankf33der> beneroth: add Args, it can not be repeated
<Regenaxer> btw, the code seems not right
<beneroth> T, that too xD
<Regenaxer> in this examwle
<Regenaxer> (isa as condition is alwyys true
<Regenaxer> paren missing?
<Regenaxer> ((isa ...
<beneroth> paren missing
<beneroth> T
<Regenaxer> ok
<Regenaxer> anyway not the reason
<beneroth> T
<beneroth> it works correct now, but I fear still that the memory is corrupted.
<Regenaxer> most probably
<beneroth> which is potentially caused by any destructive function called long before this code comes, right?
<Regenaxer> If it were pil21, we could compile some 'dbg' easily into the source of 'isa'
<Regenaxer> right
<beneroth> good advertisement :)
<Regenaxer> can still be a gc issue
<Regenaxer> pil21 also has a dbg
<tankf33der> i did not receive a code with a crash
<Regenaxer> I meant pil64 also has 'dbg'
<Regenaxer> but harder to call
<tankf33der> why you gonna add a dbg to isa call if you do not have a code crashes
<Regenaxer> args must be pushed or so
<Regenaxer> Not me
<Regenaxer> beneroth could add
<tankf33der> beneroth did not provide crashing code
<Regenaxer> yes, cause it is complicated
<tankf33der> picolisp code and data can be easily transferred from pc to pc
<tankf33der> to run
<Regenaxer> T
brandelune has joined #picolisp
<beneroth> I've got the troubling Args. Here now with correct parens and Args: https://pastebin.com/12BgDZ5t
<beneroth> tankf33der, please check again
<Regenaxer> Ha!!!
<Regenaxer> It gives stack overflow
<beneroth> aah
<Regenaxer> So it is simply an infinite recursion
<tankf33der> Eat 8gb of ram on laptop
<beneroth> hahaha
<Regenaxer> Pil21 does stack checks
* beneroth is laughing
<beneroth> damn I didn't recognize
<beneroth> good case for pil21 :D :D
<Regenaxer> :)
<beneroth> I suspect the (fin Arg), that probably loops
<Regenaxer> : (load "x")
<Regenaxer> -----------------------------------
<Regenaxer> [x:22] Stack overflow
<Regenaxer> ?
<beneroth> oh nice
<beneroth> do you have a good bakery nearby? I ought to send you a cake... :)
<Regenaxer> haha, no, thanks! :)
<beneroth> lets talk about that another time ;-)
<beneroth> but I still don't see.. what is the semantic difference between the working and crashing variant?
<Regenaxer> Good. We go on travel tomorrow, so unfortunately no time for a cake ;)
<beneroth> ok
<Regenaxer> Perhaps the stack suffices sometimes
<Regenaxer> what if ulimit -s unlimited?
<beneroth> I strongly suspect the (when (fin Args)) is logically wrong (I think it checks same endings multiple times?), but that is the same between both variants
<Regenaxer> yes, still strange
<Regenaxer> perhaps the stack overflow is also just a symptom?
<beneroth> then I get "Killed" instead of segfaulting.. I guess killed by Linux out of memory manager
<Regenaxer> corruption created some circularity
<Regenaxer> yes
<Regenaxer> stack unlimited gets killed eventually
<Regenaxer> if you have swap, it gets slower and slower and then gets killed
<beneroth> I think it must be the use of recurse.. though it's used extensively in both variants
<Regenaxer> Let me try more
<beneroth> the intention is, that all +Foo and +Bar gets found, wherever they are in this AST, even when the AST contains cons pairs.
<beneroth> Args is factually an AST
<Regenaxer> As I said, I would recommend 'fish'
<beneroth> (well, prog)
<beneroth> T
<beneroth> Regenaxer, though what really is desired a 'fish which also checks atomar cdr values
<Regenaxer> I think I knew what it is
<Regenaxer> (uppc @)
<Regenaxer> '@' is bound all the time to other values
<Regenaxer> So you get infinite recursion
<Regenaxer> (member @ ...) too
<beneroth> yeah
<beneroth> but the @ here should be quoted in Arg, not evaluated
<Regenaxer> but it crashes on the first '@'
<beneroth> T
<Regenaxer> quote does not help
<Regenaxer> it is not evaluated
<Regenaxer> the value is taken
<Regenaxer> but '@' is set in 'cond\
<Regenaxer> 'cond'
<Regenaxer> always to new values
<beneroth> right, the one which is used in (recur @)
<beneroth> well no, before, in the condition
<beneroth> you are right
<Regenaxer> You should use 'fish\
<beneroth> but the (uppc @) should not be evaluated or bound
<Regenaxer> it is taken as data
<Regenaxer> so it recurses on '@'
<Regenaxer> (fish '((X) (or (isa '+Foo X) ...)) Args)
<beneroth> I don't grok the recursing on @
<Regenaxer> or you exclude '@' from recursion
<beneroth> ah
<beneroth> yeah I see
<beneroth> ah yes
<beneroth> I see
<beneroth> @ is a symbol, so it passes the symbol check within 'isa
<beneroth> and then isa continues with getting its value, which might be whatever
<Regenaxer> right
<Regenaxer> So (unless (== '@ Arg) ... or so
<beneroth> scratching on the "code is data" can even in picolisp cause splinters ;-)
<beneroth> T
<Regenaxer> yeah :)
<beneroth> (recur (Arg)
<beneroth> (unless (= Arg '@)
<beneroth> (cond
<beneroth> and all is good
<Regenaxer> :)
<Regenaxer> I traced it
<beneroth> good one. thank you Regenaxer! I'm really glad we found the cause!
<Regenaxer> in fact '@' has '@' as its value
<Regenaxer> so it recurses infinitely
<beneroth> yeah I saw the @ being the last Arg before it crashes, but I didn't made the connection with the (val @) that results from that
<Regenaxer> (for Arg Args
<Regenaxer> (recur (Arg)
<Regenaxer> (msg (cons Arg (val Arg)))
<Regenaxer> (cond
<beneroth> aaah
<beneroth> it makes sense
<beneroth> bwahahaha
<beneroth> I manage to produce the weirdest situations...
<beneroth> (that is not positive)
<beneroth> (actually it's not my code, but doesn't matter)
<beneroth> really a good one. thanks Regenaxer, I grok now.
<Regenaxer> Well, a powerful tool lets you cut off your leg
<Regenaxer> This could happen to me too
<Regenaxer> Good to know that we don't have a serious memory bug in pil :)
<beneroth> T
<beneroth> either I should do less meta-programming, or you should do more :P
<beneroth> then again, meta-programming is seldom really KISS...
<Regenaxer> or we both do more
<Regenaxer> yes, many border conditions
tankf33der has quit [Quit: the lounge - https://webirc.envs.net]
<beneroth> yeah it quickly results in too big a context and therefore in spaghetti dependencies
<Regenaxer> 'Arg' and 'Args' also need to be excluded
<Regenaxer> or made (private)
<Regenaxer> and FooLst and BarLst too to be pedandic ;)
<beneroth> or transient?
<beneroth> yeah you are right
<Regenaxer> yes, transient is good
<Regenaxer> in pil64 transient is better
<beneroth> they're very unlikely to show up in Args, but if they do, it's the same situation as now with @ and very hard to find
<Regenaxer> yep
<beneroth> yeah, transients now, (private) in pil21
* beneroth hugs Regenaxer
<beneroth> thank you
<Regenaxer> IIRC pil64 had private too
<Regenaxer> Welcome :)
<beneroth> afaik not, not bound here in my version.. but it could be constructed of course
<beneroth> 'intern you added to pil64
<beneroth> ah no
<beneroth> what am I talking
<beneroth> nevermind
<Regenaxer> It is there, in lib.l
<Regenaxer> np
<Regenaxer> It behaves a little better in pil21
<Regenaxer> i.e. it is out of the way
<beneroth> ah
<beneroth> found it, thx
brandelune has quit [Read error: Connection reset by peer]
brandelune has joined #picolisp
brandelune has quit [Quit: This computer has gone to sleep]
aw- has quit [Ping timeout: 252 seconds]
cranium has quit [Quit: Leaving]
theruran has joined #picolisp
aw- has joined #picolisp
brandelune has joined #picolisp