jemc changed the topic of #ponylang to: Welcome! Please check out our Code of Conduct => https://github.com/ponylang/ponyc/blob/master/CODE_OF_CONDUCT.md | Public IRC logs are available => http://irclog.whitequark.org/ponylang
jemc has quit [Ping timeout: 244 seconds]
shepheb has joined #ponylang
jemc has joined #ponylang
[CBR]Unspoken has quit [Ping timeout: 250 seconds]
amclain_ has joined #ponylang
amclain has quit [Ping timeout: 244 seconds]
[CBR]Unspoken has joined #ponylang
jemc has quit [Ping timeout: 252 seconds]
Praetonus has quit [Quit: Leaving]
copy` has quit [Quit: Connection closed for inactivity]
<SeanTAllen> I'm feeling meh doublec but if no one else gets to it by tomorrow evening, I'll test and merge
amclain_ has quit [Quit: Leaving]
trapped has joined #ponylang
trapped_ has joined #ponylang
trapped has quit [Ping timeout: 244 seconds]
trapped_ has quit [Read error: Connection reset by peer]
srenatus has joined #ponylang
<doublec> I have a Map[U32, Object] and I iterate over the keys and it shows there is an '11' key. The very next line does a _map(11) and it throws an exception.
<doublec> weird.
<doublec> huh, interesting. I can duplicate it with a short program. I'll investigate a bit more and do an issue.
lispmeister has joined #ponylang
BrotherLy has joined #ponylang
<BrotherLy> i think rust is better, opinions?
<doublec> BrotherLy: I think they're different use cases
copy` has joined #ponylang
_andre has joined #ponylang
juanjoc has joined #ponylang
<sblessing> BrotherLy: I would be very interested in the pros in favour for rust compared to Pony, in your opinion!
BrotherLy_ has joined #ponylang
BrotherLy has quit [Ping timeout: 244 seconds]
<doublec> Any good tips for finding the source of an error in a try...end block?
<doublec> I'm doing various string substrings, indexes, etc in the try...end and my current approach is liberal use of @printf
<shepheb> some way to log a stack trace from an error would be handy.
<doublec> yes
<shepheb> on the other hand, that definitely makes them not opaque objects
<shepheb> but in ponyc -d mode, that would be fine with me
<doublec> Or break in gdb on error
<shepheb> Debug.stack(lastError) or something
<shepheb> that too
<sblessing> you could break in pony_throw and look at the stack trace for now
<shepheb> also, hat tip for expertly disarming that probable troll earlier.
<BrotherLy_> I'm not a troll
<shepheb> then I suppose I am interested to hear your take on the pros and cons of Rust and Pony.
<BrotherLy_> i dont know either langauge
<sblessing> -.-
<shepheb> also the experimental parser combinator library I hacked together seems to be working decently.
<shepheb> I'm using it to write an assembler, which is a fairly simple parser, but still.
<shepheb> the main thing I'm missing from eg. Haskell's Parsec is the operators <* and *>, which let you sequence parsers while ignoring the results of some.
<shepheb> since I want to eg. parse a string "add" but return the opcode number.
<doublec> nice
<shepheb> I want to finish the parser for this assembler before really pointing anyone at it, though. it's only lightly tested right now.
<ohir> lol, "I do not know either so I feel competent to have strong opinion one is better"
<ohir> BrotherLy_: there is no such thing as objectively "better". Even such abomination as c++ has its place when it fits good coder mind
<BrotherLy_> ohir, faster is better
<BrotherLy_> rust is pretty fast
<ohir> BrotherLy_: more serious, imo no sane mind may compare rust and pony as languages. At most their peculiar traits (guarantees) can be argued.
<BrotherLy_> i went to the benchmark game website, they prove it there
<ohir> BrotherLy_: its a fallacy
<BrotherLy_> i dont believe in fallacies
<ohir> BrotherLy_: fastest software that outputs garbagage is no better than slow but right one :>
<ohir> BrotherLy_: as for rust speed... you know, that it never will be the fastest?:>
<ohir> BrotherLy_: if you are after real speed you need to look at real speedy languages
<BrotherLy_> rust is ZERO abstraction
<BrotherLy_> nothing faster than that
<ohir> BrotherLy_: I meant you need to dive into asm and, better yet, vhdl :>
<ohir> BrotherLy_: I assure you that bunch of gates on a decent fpga will perform magnitude better :>
<ohir> BrotherLy_: ok, thats all feed for trolls today :)
* ohir off
TwoNotes has joined #ponylang
<SeanTAllen> doublec: fixed
Praetonus has joined #ponylang
<shepheb> not that anyone is keeping track, but I revise my comment from yesterday: I just discovered that a total (non-partial) function is a subtype of a partial one.
<shepheb> so if only some implementations of some interface method are partial, I can make the interface say ? and some implementations not, and everything is fine.
<shepheb> I thought I had to hack in if false then error end to make the compiler happy.
<doublec> SeanTAllen: great, thanks!
trapped has joined #ponylang
<doublec> I'm triggering a SIGSEGV using the Pony ssl code - investigating
<SeanTAllen> you are a human concolic testing engine doublec
<doublec> It's happening in _final of SSL. Is that a finalizer called by the GC?
<doublec> SeanTAllen: I'm a human crash causer :)
<doublec> Can finalizers for objects be called more than once?
<sblessing> doublec: no
<sblessing> once per instance
<sblessing> and yes its called by GC
<doublec> I create an SSL connection to a IMAP server. send a command. Then close the connection and reconnect, then repeat. I then get the crash in _final on SSL.
<TwoNotes> Bt any chance is the segfault in mark_remote_actor?
<TwoNotes> If you build a debug ponyc, you get a debug libponyrt as well, so you can get a reasonable bt of RT routines
<doublec> I'll try a debug build
<doublec> TwoNotes: strack trace http://pastebin.com/fqfgyT31
<SeanTAllen> which commit are you on doublec ?
<doublec> SeanTAllen: 6780aa7aded1111d3f9071ce19f1ff53217f532c
<doublec> SeanTAllen: the most recent
<SeanTAllen> ok
<SeanTAllen> do you have a simple use case to trigger doublec?
<shepheb> ! Pony has finalizers?
<sblessing> sure thing :)
<sblessing> with limits obviously
<shepheb> since several expert folks are around: what can I do when I need to fill a generic type slot for a value I'll never actually touch?
<shepheb> for example, a parser that takes an inner parser, but ignores its value and returns some constant instead.
<doublec> Is it possible than the openssl functions are being called on different threads?
<doublec> The ones called from pony
<doublec> I'm guessing so
<shepheb> I'm currently forced to specify the type of the inner parser too, which seems like it can be avoided.
<doublec> see here regarding crypo lock setup required https://www.openssl.org/docs/faq.html#PROG1
<doublec> SeanTAllen: not yet - I'll try and narrow one down now
<Praetonus> doublec: OpenSSL MT setup is done in sslinit.pony
<Praetonus> So that's not the problem
<shepheb> I'm having the most trouble with these generics re: their caps
<shepheb> for example, I can't do class PConst[A: Any #read] is Parser[A]; let _value: A; new create(v: A) => _value = v
<shepheb> that explodes, because ref is not a subtype of box.
<shepheb> and I can't say new create(v: A box) because I can't specify a cap for a generic anywhere but the spec on the class name.
<shepheb> (not sure why - is that an implementation accident or a theoretical thing?)
<shepheb> and if I use box instead of #read, someone trying to use a val type like String has a problem.
<shepheb> I really don't care - given me a readable cap and I'll give it back to you.
<doublec> Praetonus: thanks, I'll try and do a reduced case and raise an issue
<doublec> It seems to be related to if the other end closes the connection first
<TwoNotes> doublec, no that is not the same place as Issue 623
<TwoNotes> I have been looking at the GC code, but it is impossible to figure out what it is doing.
<sblessing> :-D
<shepheb> garbage collection is always deep magic, but Pony's is even more so than most.
<TwoNotes> I am sure it is doing clever things, but there are zero comments in that section of code. This makes it hard for people other than the original author to locate bugs.
<TwoNotes> For example, ponyint_actormap_getactor can return NULL. What is the significance of that? There are places that call that function and do not defend against NULL values.
aturley has joined #ponylang
BrotherLy_ is now known as hio
<doublec> It looks like an issue with the ordering of how I'm handling shutdown of the SSL socket
<doublec> I'll investigate more tomorrow. If I don't call dispose on the connection and let it finalize it works fine.
<sblessing> that almost sounds like a double free
<doublec> And try to come up with a reduced testcase for the crash. I wasn't able to get one working just now.
<sblessing> have you checked the destruction doesn't happen twice?
<doublec> I don't think it does but I'll confirm tomorrow
<sblessing> ok
<doublec> It only happens on one particular IMAP server - which isn't public so can't put the test case up unless I can get it happening on another server.
hio has quit [Quit: Leaving]
<sblessing> hmh
Praetonus has quit [Quit: Leaving]
<doublec> ok, I got a segfault running against a public https server. Unfortunately the coredump failed. I'm trying again and do an issue on it if it's relevant.
<doublec> It's basically an https request repeated over and over for about 5 mins
<doublec> different but similar stack
pulpfiction has quit [Quit: Leaving]
<doublec> sblessing: issue up https://github.com/ponylang/ponyc/issues/629
<SeanTAllen> thanks doublec. i'm going to take a look tonight. sylvanc is knee-deep in compiler work at the moment. if i can figure it out this evening, i'll bring him in.
<shepheb> anyone able to help with these generics problems? especially the ref-is-not-box one; I really can't see how to handle that.
<shepheb> it seems like "A" defaults to "A ref" somewhere, and I can't control it.
<SeanTAllen> doublec: did you say there was a way you could modify the code so it didnt segfault?
<SeanTAllen> shepheb: i suck at generics right now. jemc when he is around is fairly good with them. mailing list where you'll get more eyes is a better bet than here probably.
<shepheb> okay.
jemc has joined #ponylang
<sblessing> doublec: thank you!
<shepheb> oh hey, we summoned jemv.
<shepheb> jemc, even
<shepheb> I have a generics question, give me a sec to make up a basic example and Gist it.
<jemc> I'm not so great at generics yet, but maybe I can help :#
<shepheb> better than me!
<shepheb> the tl;dr version is that if I do class Foo[A: Any #read]; let _value: A; new create(v: A) => _value = v
<shepheb> then I get an error that ref if not a subtype of box.
<shepheb> I can work aorund it by using Any box instead, but that still seems needlessly complex.
<shepheb> and then I pass in a String val, and get back a strictly weaker String box.
<jemc> yeah, when implementing the type, mo' generic => mo' problems
<jemc> when using the class, usually mo' specific => mo' problems
<jemc> that said, when I paste your example and compile it I get no problems
<shepheb> maybe there's some other factor here, so let me figure out a real minimal example. that was me making it up on the fly.
<jemc> there must be some other part of your class that triggers the problem - perhaps when you try to read the value back out?
<shepheb> yeah, it's somewhere else. still trying to sort it outl
<shepheb> jemc: https://gist.github.com/shepheb/b63c226875b90671f75a there's a minimal example.
<shepheb> the full error messages are a little more illuminating
<jemc> yeah, the error messages lead you to the resolution of the issue - in this case, you just have to make the return type of the `foo` method: `this->A` instead of just `A`
<jemc> this is because, depending on the cap of this and the cap of A, you might not be able to return the original cap of A
<shepheb> ah, interesting.
<jemc> for one example, if `A` is `Bar ref`, then from `fun box foo()` you cannot return a `Bar ref`, but at best a `Bar box`
<jemc> because all caps are "deep" - you can't use a read-only function to access a mutable field as mutable
<jemc> the table is a nice reference for knowing how the cap of the "origin" (`this`) transforms (viewpoint-adapts) the effective cap of the field
<shepheb> quite. okay, and this is definitely a box function, so no ref returns.
<shepheb> I do get the somewhat puzzling error message that ref is not a subtype of #read, even though it is from an input POV
<shepheb> but ref is not a subtype of box->#read, if you will
<jemc> the telling error messages I see are:
<jemc> "function body isn't the result type"
<jemc> "function return type: A #read"
<jemc> "function body type: this->A #read"
<shepheb> that also explains where the triple (A ref, A val, A box) is not a subtype of (A box, A val, A box) came from
<shepheb> those are the members of #read
<jemc> which is telling you that you either need to fix the return type (in the signature) to match the body (the effective cap) or vice versa
<jemc> yeah
<shepheb> hm. I did change the signature but that led to lots of more complex errors in the real case, even though it fixes the simple one. I'm still experimenting.
<jemc> yeah, that's how it goes with generics, unfortunately :)
<jemc> at each step when you apply a fix to resolve a dissonance, you have to take a moment to ensure that you are solving it *in the right direction*
<jemc> "does this change accurately represent how this type should work?"
<jemc> if you go the wrong way with your fixes, you'll only create more problems
<shepheb> the recursive nature of parsers is making this hard :/
<shepheb> hooray for git history, though.
<jemc> if you go the right way each time and it still doesn't work, then you might be trying to something that is cap-impossible
<jemc> when I hit such frustration I usually then ask myself just how generic this type *really* needs to be in order to be useful to me
<jemc> sometimes I end up "bailing out" and making a fully immutable type and just use `val` everywhere to make implementing it easy
<shepheb> unfortunately, this is kind of important here.
<shepheb> though just using box everywhere might be sufficient for my purposes here.
<shepheb> since mutating the output of a parser is usually a bad idea.
aturley_ has joined #ponylang
<jemc> well, you can ask yourself - should any other reference be able to mutate the output "out from under you"?
<jemc> it seems to be that the answer is probably "no", so `val` is your ticket
aturley has quit [Ping timeout: 276 seconds]
juanjoc has quit [Read error: Connection reset by peer]
<TwoNotes> Making as much stuff as possible be 'val' seems helpful. It gets thru most barriers.
<shepheb> val is awesome, yes.
<shepheb> and since the input here is a String val, usually, the output is similarly val. since the String can't change, neither can the parsed output.
amclain has joined #ponylang
<shepheb> when I specify class val Foo, do I still need to say new val create?
<jemc> the two mean different things
<jemc> remember that part of Pony's sugar means you don't have to type `[TypeName] [cap]` everywhere a type is expected - this is because each type has an associated "default" cap
<jemc> for example anywhere a type is expected, `String` => `String val` and `Array[U8]` => `Array[U8 val] ref`
<jemc> `class val Foo` makes `Foo` => `Foo val` where a type is expected, but it has no effect on the cap associated with your actual constructors
<jemc> so yes, in this case you probably want the two to match, but in some cases, maybe not - like String for example
<jemc> the `String.create` constructor creates a `ref`, even though the default cap for the `String` type is `val`
<jemc> this is because string literals are the most common way to make a `String val`, and those are "usually" more common than constructed strings
<TwoNotes> So a string literal is a 'ref', which is not what I would expect. How can you mutate a literal?
<jemc> a string literal is a `val`, not a `ref`
<jemc> they exist in an immutable string table so that they don't have to be re-allocated each time the execution passrs through that literal's declaration
<TwoNotes> Ah, but String.create is not. Which is why you see "recover val String.create(...) end" so often
<jemc> if you want to mutate a literal, you have to `"literal".clone()` or `String.create().append("literal")`
<jemc> yeah
<jemc> the string table mechanism is fairly standard in language implementations
<jemc> it's just that some languages don't give you control over when you copy the immutable string to a new mutable one - some languages do it automatically and always expose you to that copy cost
<TwoNotes> I just wish there was a more compact notation for these common transformations.
<jemc> for example, in Ruby, string literals are always allocated and copied again unless you use the parser/interpreter hack of `"literal".freeze` as shorthand for "don't copy this literal"
<TwoNotes> There are all sort of 「cool brackets」 available one you step outside of ASCII
<jemc> heh, yeah, such constructions have the potential to be super concise and readable, but difficult and frustrating to type on a normal keyboard
<TwoNotes> You wouldn't want to end up with something unreadable like APL.
<TwoNotes> I could type those brackets quickly because I have a Japanese IME installed, and those are Japanese "quote marks"
<TwoNotes> Maybe some comination of more normal characterts. [[like this]]
<jemc> one of the things I personally want to do is make it easier to compile pony using a different, customized or hacked up parser
<jemc> that is, make it easy to make parsers that output pony ast files that get read by ponyc proper
<TwoNotes> Oh, like those Erlang pre-processors.
<jemc> yeah, I was about to mention the BEAM VM
<TwoNotes> I think some of Erlang's sugar notations are done like that. Like QLC. I really liked QLC
<jemc> if you have a standardized internal representation for pony semantics (an AST should work fine), you can create other "languages" that share the same semantics and runtime
lispmeister has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
aturley_ has quit [Ping timeout: 246 seconds]
<shepheb> there's some really cool stuff done in Haskell land using a similar approach.
<shepheb> also intermediate steps, like parsing vanilla Pony with the ponyc parser, munging the AST somehow, then feeding it into the rest of the compiler.
<shepheb> but most of them are extensions to the syntax, so they have an extended or replacement parser anyway
<TwoNotes> Here is one that is not just syntax: You can't refer to an actor field from inside a 'recover'. BUT, if you make a 'let' copy of the field, you CAN refer to that instead! It seems to me the compiler could do this operation for you.
<TwoNotes> (Because an actor is a 'tag')
aturley has joined #ponylang
<TwoNotes> Idea: I know that the constructor for an actor runs like a 'be' method.
<TwoNotes> But is the new actor fully registered as being "alive" before or after the constructor completes?
<TwoNotes> Put another way, what would happen if a GC pass decided to go looking for orphaned actors before the constructor completed?
<jemc> an "unreachable" actor (by any other reference) that still has messages to process (as behaviours) is still considered alive by the GC, and the constructor is probably just considered as one of those messages
<TwoNotes> But say the constructor has started processing, but it takes a while.
<TwoNotes> Would not the message queue be empty?
<jemc> I don't know the details of the implementation of these internals, so I'm only talking conceptually, but no, I would not consider it empty - there is still one message to finish processing
<TwoNotes> I was wondering if the fact that one of my actors does some disk I/O in its constructor would delay completion long enoug for the GC to find it missing, leading to that segfault
Praetonus has joined #ponylang
<jemc> yeah, if we're talking in terms of implementation bugs, then yes, maybe that's the case
<jemc> I would definitely call that an implementation bug though, as it differs from the conceptual meaning of an actor that is "done"
<TwoNotes> Because commenting out the disk I/O makes the segfault go away
<jemc> I thought we were talking in terms of how it's "supposed to work"
<jemc> in terms of bugs, you may be onto something
<TwoNotes> Well, if there is a small timing window during actor startup where this could happen, I would call that a bug
<TwoNotes> The same code that reads the disk files also allocates a bunch of class objects. That may also be a factor. It is building up a sort of symbol table
<SeanTAllen> TwoNotes: all that is required is for there to be a message "in flight" not in queue. sylvanc addresses that point in one of his talks. the qcon one i think touches on it.
<SeanTAllen> there are certainly bugs in the gc at the moment
<SeanTAllen> i'm looking at repeated signs of one right now
<TwoNotes> I will try creating a second 'be' behavior and moving the disk I/O into that, so that the constructor completes quickly.
<TwoNotes> If that clears up the problem then I would say that indicates there is some sort of timing window where this can happen
<TwoNotes> Because if the constructor calls a 'be', that will complete right away, while the called code will execute some time later
<TwoNotes> right?
<SeanTAllen> without seeing what you are seeing i cant say yes or no
<TwoNotes> I mean, if one behaviour invokes another behavior in the same actor, that messages goes on the queue like any other, and does not execute right away
<SeanTAllen> casual messaging yes
_andre has quit [Quit: leaving]
<TwoNotes> Moving the loading of data files to another behavior still gets segault, but the stack is a little different
<TwoNotes> The class whose construction was delayed is now fingered on the stack as Classname_$trace(), just before the call to GC
<TwoNotes> And the particular actor being touched by GC at the time of the segault is different.
<TwoNotes> I suspect that the particular actor who is being looked at at the time of crash is not actually related to the crash. It is the order in which things get processed. By moving that code from a direct 'fun' call to a 'be', that shuffled the execution order
<jemc> TwoNotes: you could try running with `--ponythreads=1` to avoid parallel processing of actors - it might make the problem clearer
<TwoNotes> Is that a compile-time switch?
<TwoNotes> Ah, no runtime
<TwoNotes> Same symptom with ponythreads=1
<jemc> yeah, just wondering if the backtrace might be more consistent between runs
<TwoNotes> bt looks the same, and so it the name of the actor getting hit
srenatus has quit [Quit: Connection closed for inactivity]
<doublec> TwoNotes: my understanding is GC doesn't run while behaviours are running, so that should include the constructor
<doublec> TwoNotes: it only runs between behaviours when the actor can't have state changed
<doublec> TwoNotes: This is why a loop inside a behaviour that allocates lots of memory will OOM
<SeanTAllen> true
<doublec> GC bugs are horrible to track down. There's one I come across in Self very intermittently that has been around for years.
<hakvroot> TwoNotes: you might find it interesting that I've been able to reproduce your issue without opening files... but I haven't been able to pinpoint what is the cause yet
<TwoNotes> hakvroot, you mean the segfault in ponyint_gc_markactor or thereabouts?
<hakvroot> lemme dbg is to see where thereabouts is ;) ... but I was silently assuming this was the same issue as you mentioned yesterday evening?
<hakvroot> gdb*
<TwoNotes> If you have a debug libponyrt, you should see it on a line dereferencing a pointer that is null.
<hakvroot> and yup, it's right at ponyint_gc_markactor
<TwoNotes> And the pointer, arec I think, is null
<TwoNotes> aref
emancu has quit []
<TwoNotes> Was that using my code, or have you been able to do it independently?
<hakvroot> with your code and throwing stuff out to narrow it down
<TwoNotes> My guess is you could eliminate SpeechOut and the Dispatcher and still get the bug
aturley has quit [Ping timeout: 248 seconds]
<hakvroot> well... I was kinda surprised there because I thought I found the cause of the bug, but then I started eliminating SpeechOut and it disappeared
<TwoNotes> Very odd. SpeechOut is very simple, and has nothing to do with the other stuff, except they call a behaviour in it from time to time
<hakvroot> hehe, well, I'll give that another shot... need to simplify it anyway for a nice reproduction :)
<hakvroot> the most interesting thing I've found was in _loadRules btw ... if the while loop has only one iteration it doesn't segfault... if it has more than one it does
<TwoNotes> wow
<hakvroot> btw... to work against LLVM I'm using MT (from random) to prevent it from being too smart
<hakvroot> (that's what I'm replacing IO with anyways :)
<TwoNotes> Each time around that _loadRules loop is where it allocates a bunch of little class objects. It is internalizing the BNF at that point.
<TwoNotes> Shifting to other computer. back in a mo
TwoNotes has quit [Quit: Leaving.]
TwoNotes has joined #ponylang
<hakvroot> and welcome back
<hakvroot> it does seem that passing SpeechOut to SpeechIn is important for the segfault
<doublec> SeanTAllen: answering your question earlier, commenting out the dispose call on the _conn object makes the error go away.
<doublec> SeanTAllen: oops, I'm wrong - as soon as I write that my process segfaults. took a lot longer though.
<doublec> SeanTAllen: maybe there's some ordering issue with how the ssl connection is torn down and it's not gc related at all.
prettyvanilla has quit [Ping timeout: 260 seconds]
prettyvanilla has joined #ponylang
<SeanTAllen> doublec: im testing a fix now
<SeanTAllen> might be pushing a fix in about an hour or so
<doublec> SeanTAllen: nice thanks
<doublec> SeanTAllen: I don't know if it's useful but valgrind came up with http://pastebin.com/1tCqQws5
trapped has quit [Ping timeout: 276 seconds]
<SeanTAllen> in part, the problem is there
<SeanTAllen> in ssl.pony
<SeanTAllen> _final would try to free memory that dispose had already freed
<SeanTAllen> due to bug in gc
<SeanTAllen> or so it looks
<SeanTAllen> still running
<hakvroot> TwoNotes: I managed to get it down quite a bit now... it is... quite weird
<hakvroot> I'll add my reproduction to your issue
<TwoNotes> great
<hakvroot> I think it is related to the gc being triggered by Debug.out calls btw
<SeanTAllen> doublec: can you try out branch: issue-629 to see if your problem is gone?
<TwoNotes> oo. So it does not happen with debug off?
<SeanTAllen> TwoNotes: just for kicks can you as well
<hakvroot> well... it does happen with debug off, it doesn't appear to be happening when you replace the debug statement with a call to StdStream.write
<TwoNotes> I will get to that in a few hrs. You mean try with latest ponyc fix?
<TwoNotes> Debug.out does the output immediately. the other ways use an actor
<jemc> SeanTAllen: regarding your PR 637
<TwoNotes> I used to use env.out.print, but got tired of having to pass env around all the time
<jemc> I'm still kind of ignorant of the GC, but it seems like we still need to heap free objects that have a final_fn
<hakvroot> btw TwoNotes, do you know how I can see whether I'm dealing with a null reference in gdb?
<jemc> as I understand it, the final_fn is for performing cleanup actions that are unrelated to actually freeing the pony object on the heap
<SeanTAllen> jemc: i'm still kind of ignorant. i tracked down what was happening. sylvanc came up with fix. i tested it and wrote it up.
<jemc> ah, okay, if sylvanc suggested it, I'll stop questioning :P
<hakvroot> TwoNotes: and I can imagine yeah :) ... I'm wondering if there is a good alternative to the Debug.out call to determine whether the issue lies in the Debug or in the gc being triggered upon actor creation
<SeanTAllen> we played the game of sean spends hours figuring out what impossible thing is happening and sylvan uses his knowedge of codebase to go "oh!"
<jemc> heh
<jemc> yeah, as I think TwoNotes was saying the other day, we need more comments/docs about the GC code
<SeanTAllen> as sylvan is working on distributed pony, i suspect this is how most gc issues will get addressed for a while
<TwoNotes> All those Debug calls will not be needed once everything is working properly.
<SeanTAllen> If you have anything that looks like a gc issue, please try branch issue-629 and see if it fixes it
<doublec> hakvroot: use @printf maybe
<doublec> SeanTAllen: will test shortly
<SeanTAllen> @printf is handy
<doublec> Yeah, I use it a lot
<doublec> Mostly because I don't remember the Debug magic
<doublec> But the C programmer in me never forgets printf
<doublec> I want to try rr with Pony for debugging at some point http://rr-project.org/
<TwoNotes> Debug is nice because you can turn it on and off. But no good if it changes behavior
<doublec> TwoNotes: how do you use it?
<doublec> TwoNotes: I've not actually tried it
<TwoNotes> use "debug"
<doublec> Does debug output only appear in "-d" builds?
<TwoNotes> Then put Debug.out( string ) calls where you like
<TwoNotes> they are all no-ops if not compiled with --debug
<doublec> SeanTAllen: I can confirm it fixes the issue both with my cut down example and in the real program
<doublec> SeanTAllen: thanks!
<hakvroot> doublec: interesting, the segfault doesn't appear when using printf instead of Debug.out
<hakvroot> TwoNotes: I commented on your issue with what I believe is the trimmed down version
<TwoNotes> ok
<doublec> hakvroot: interesting. I guess if Debug.out is an actor it affects quite a few characteristics of the run.
<Praetonus> Debug.out is a function on a primitive, and it calls fprintf on stdio
<doublec> weird, so should be exactly like @printf calls
<mcguire> TwoNotes: Debug.out( <something expensive> ) still seems to run the <something expensive> even when compiled without -d
<TwoNotes> Odd then that direct printf calls behave differently
<hakvroot> I actually copied the @printf call from Debug
<Praetonus> Actually, I'm not sure that classic stdio calls are thread safe when used in conjunction with Pony StdStream, which use unlocked_stdio under the hood
<Praetonus> Someone with a good knowledge of the runtime needs to look at this, I think
<mcguire> For something completely different: https://gist.github.com/tmmcguire/9a4af43393a6c84deae1
<mcguire> "one" > "four" and "four" > "one"
<TwoNotes> Debug considered harmful?
<mcguire> To my sanity, sure.
<doublec> is it comparing by object identity?