From: Alexandre F. <ale...@gm...> - 2009-09-13 18:18:16
|
Hi, In a 2009-08-02 commit, Donal added an interesting debugging tool: ::tcl::unsupported::representation with the comment: Result string is deliberately a bit obstructive so that people are not encouraged to make code that depends on it; it's a debugging tool only! Of course I'm delighted to get a sharp knife when I can... however I'm a bit surprised by this, in the light of an earlier discussion on this list more than one year ago (2008-06-03, subject: "debugobj"), regarding a similar patch I had proposed (::tcl::unsupported::debugobj) at https://sourceforge.net/tracker/index.php?func=detail&aid=1980917&group_id=10894&atid=310894 To summarize the differences: - 'representation' just gives the type name, as a string result in a trivially parseable English sentence. - 'debugobj' also gives refcount, along with object and intrep pointers, on stdout so as to be a bit harder to depend on. Knowing the refcount can be very helpful to play with the K combinator and various in-place optimizations, and knowing the pointers helps tracking duplication at the Tcl_Obj and intrep levels. At the time of the discussion, the consensus was that (1) all this was done by Tweezer, why reinvent the wheel, and (2) too sharp a knife. Why, then, end up with an even sharper knife with less introspective power ? -Alex |
From: Alexandre F. <ale...@gm...> - 2009-09-15 22:47:37
|
Since the question is apparently too stupid to deserve an answer, and since the salient drawback of my proposal seems to be the stdout part, let's put it another way: Imagine one day we also want the refcount. What would be best: (a) yet another primitive [refcount] alongside [representation] (b) an evolution of the 'obfuscated' sentence so that it also gives the refcount -Alex |
From: Jeff H. <je...@ac...> - 2009-09-15 22:53:41
|
On 15/09/2009 3:47 PM, Alexandre Ferrieux wrote: > Since the question is apparently too stupid to deserve an answer, and > since the salient drawback of my proposal seems to be the stdout part, > let's put it another way: > > Imagine one day we also want the refcount. What would be best: > > (a) yet another primitive [refcount] alongside [representation] > (b) an evolution of the 'obfuscated' sentence so that it also > gives the refcount I have no issue with extending [representation] to output refcount and other info as well. It should stick to one command. |
From: Alexandre F. <ale...@gm...> - 2009-09-15 23:15:20
|
On 9/16/09, Jeff Hobbs <je...@ac...> wrote: > On 15/09/2009 3:47 PM, Alexandre Ferrieux wrote: > > > Since the question is apparently too stupid to deserve an answer, and > > since the salient drawback of my proposal seems to be the stdout part, > > let's put it another way: > > > > Imagine one day we also want the refcount. What would be best: > > > > (a) yet another primitive [refcount] alongside [representation] > > (b) an evolution of the 'obfuscated' sentence so that it also > > gives the refcount > > > > I have no issue with extending [representation] to output refcount and > other info as well. It should stick to one command. > OK, thanks Jeff. So, would you basically accept a patch returning (not outputting): value is a bignum with a refcount of 14, object pointer at 0x12345678 and intrep at 0x45671234 ? -Alex |
From: Donal K. F. <don...@ma...> - 2009-09-16 09:33:54
|
Alexandre Ferrieux wrote: > So, would you basically accept a patch returning (not outputting): > > value is a bignum with a refcount of 14, object pointer at > 0x12345678 and intrep at 0x45671234 I can live with that, except don't include the intrep location because not all intreps are locations (and understanding the intrep is probably a few dozen steps too far). The main things though are that it should be human-readable (to discourage non-debugging use) and yet should be in the interpreter result (to allow for remote debugging; having to fiddle around with capturing stdout would suck, and I exposed the bytecode disassembler to avoid that sort of thing). Hope that makes sense. Donal. |
From: Alexandre F. <ale...@gm...> - 2009-09-16 16:32:28
|
On 9/16/09, Donal K. Fellows <don...@ma...> wrote: > Alexandre Ferrieux wrote: > > > So, would you basically accept a patch returning (not outputting): > > > > value is a bignum with a refcount of 14, object pointer at > > 0x12345678 and intrep at 0x45671234 > > > > I can live with that, except don't include the intrep location because not > all intreps are locations (and understanding the intrep is probably a few > dozen steps too far). The main things though are that it should be > human-readable (to discourage non-debugging use) and yet should be in the > interpreter result (to allow for remote debugging; having to fiddle around > with capturing stdout would suck, and I exposed the bytecode disassembler to > avoid that sort of thing). > > Hope that makes sense. Patch updated in the SF entry, please review. Remarks: (1) I kept (in hex) both ptr1 and ptr2 of the intrep and removed the "at" (since they are not necessarily pointers as you rightfully point out). (2) I'm not sure of the portability of the %p sprintf specifier (3) I welcome education as to the proper macros for string buffer sizes large enough to hold an integer, a pointer, etc. -Alex |
From: Jeff H. <je...@ac...> - 2009-09-15 23:30:49
|
On 15/09/2009 4:15 PM, Alexandre Ferrieux wrote: > On 9/16/09, Jeff Hobbs<je...@ac...> wrote: >> On 15/09/2009 3:47 PM, Alexandre Ferrieux wrote: >> >>> Since the question is apparently too stupid to deserve an answer, and >>> since the salient drawback of my proposal seems to be the stdout part, >>> let's put it another way: >>> >>> Imagine one day we also want the refcount. What would be best: >>> >>> (a) yet another primitive [refcount] alongside [representation] >>> (b) an evolution of the 'obfuscated' sentence so that it also >>> gives the refcount >> >> I have no issue with extending [representation] to output refcount and >> other info as well. It should stick to one command. > > OK, thanks Jeff. > So, would you basically accept a patch returning (not outputting): > > value is a bignum with a refcount of 14, object pointer at > 0x12345678 and intrep at 0x45671234 Indeed, and actually I wouldn't mind seeing a dict similar to the output from 'info frame', but if Donal wants it to be slightly more painful to parse, I won't grumble. ;) Jeff |
From: Alexandre F. <ale...@gm...> - 2009-09-15 23:38:46
|
> Indeed, and actually I wouldn't mind seeing a dict similar to the output > from 'info frame', but if Donal wants it to be slightly more painful to > parse, I won't grumble. ;) Yes, but beware not to use a real Tcl container like dicts, it will +1 the refcount and complicate refcount analysis. Also, the conversion to string rep would be dangerous, since the tool is most useful on very large objects that you absolutely never want to see duplicated nor printed. So it would seem safer to generate a pure string being a short sentence, starting as shown above and ending with .. and no string rep or .. and string rep: AEZAREZAREZREAZA... (the three dots at the end to show truncation at a few chars) OK? -Alex |
From: Alexandre F. <ale...@gm...> - 2009-09-15 23:41:51
|
On 9/16/09, Alexandre Ferrieux <ale...@gm...> wrote: > > Yes, but beware not to use a real Tcl container like dicts, it will +1 > the refcount and complicate refcount analysis. Also, the conversion to > string rep would be dangerous, since the tool is most useful on very > large objects that you absolutely never want to see duplicated nor > printed. Oops, just realized you were not suggesting to have the object itself mentioned in the dict. Ignore my remarks about this. Only remains the idea that a dict is awfully too easy to extract data from ;-) -Alex |
From: Magentus <mag...@gm...> - 2009-09-16 03:13:27
Attachments:
signature.asc
|
On Wed, 16 Sep 2009 01:38:34 +0200, Alexandre Ferrieux <ale...@gm...> wrote: >> Indeed, and actually I wouldn't mind seeing a dict similar to the >> output from 'info frame', but if Donal wants it to be slightly more >> painful to parse, I won't grumble. ;) > Yes, but beware not to use a real Tcl container like dicts, it will +1 > the refcount and complicate refcount analysis. Also, the conversion to > string rep would be dangerous, since the tool is most useful on very > large objects that you absolutely never want to see duplicated nor > printed. I actually did that, by snagging the refcount before including the object, and only if the object actually HAS a string rep. (I was using a list, because dict's only existed as a script prototype at the time.) > So it would seem safer to generate a pure string being a short > sentence, starting as shown above and ending with > .. and no string rep > or > .. and string rep: AEZAREZAREZREAZA... I actually prefer that, and was going to do that myself, but couldn't be bothered. I didn't care often, beyond whether or not the string rep actually existed, and [dict exists] with the object itself included (AFTER reading the refcount) did that without having to mess around with truncation and what-not. As long as I remembered to destroy the list before I looked at that same variable again, it was invisible. The important bits for me, were the refcount, the question of whether the string rep exists, and what the internal type is. The pointer to the internal data is, well, problematic. You can have a stab at getting most of the internal data, but I found the best way to achieve the intent of that item, is to actually dump the entire TclObj in hex form (alternatively, just the intrep portion). Anyone who cares, knows where in the string to look for what they expect to find. The debate on dict vs. string, is kinda silly. The string is trivially parsable as you suggested, and some idiot is going to rely on it no matter what you do. So make it a usefully inclusive dict and move on. As an aside... Why yours DIDN'T work for me, Alexandre, is that I was often working remotely through what is essentially a backdoor into a web server I was building whereby a given page would "eval" the provided POST data (yeah, major dangerosa, but it wasn't "live", and there was a long random string that had to be passed in the request to enable it, etc.). The up-shot of that, is that std* was a three lane highway to /dev/null, so debugobj really wouldn't have helped very much. Otherwise, the idea of sending it to stdout would have been pretty cool... Although no doubt then people would jump through hoops to capture the stdout of their application and filter it to get at the data programmatically just the same, so I personally don't see that it's worth the annoyance. Why I was doing this myself, I was trying to learn how to write C packages. In particular, I was writing a kind of anti-[future] implementation (strangely, it was called future also) to solve an issue I was having with refcounted OOP. My [future] package allowed me to trigger a script on EITHER first use or destruction time, allowing me to return the ID of the newly created "object", linked to an unref when it went out of scope, causing the newly created object to self destruct if nothing cared. The main motivation, was that the object being returned was actually a middle-stage by-product of something else, which happened to be occasionally useful to the caller, and the alternative was to set up an idle event to kill the internal reference (the idea of sticking a variable in the calling proc really doesn't appeal to me - it'd be nice if there was a way to "trace add proc finished"). The idle thing was ugly, and at worst dangerous. Anyhow... As an interesting side-point, this is what, the forth recent incarnation of this tool? [debugobj], tweezer, my [future debug], and now [representation]... It's obviously a wanted feature, as frighteningly internal as it may be. Would it make sense to have the entire unsupported namespace as a core-included package, just to emphasise that these things aren't supposed to be used? -- Fredderic Debian/unstable (LC#384816) on i686 2.6.30-1-686 2009 (up 8 days, 17:40) |
From: Jeff H. <je...@ac...> - 2009-09-16 16:39:58
|
On 16/09/2009 9:32 AM, Alexandre Ferrieux wrote: > (2) I'm not sure of the portability of the %p sprintf specifier It's portable and what should be used. |
From: Alexandre F. <ale...@gm...> - 2009-09-16 21:22:28
|
On 9/16/09, Jeff Hobbs <je...@ac...> wrote: > On 16/09/2009 9:32 AM, Alexandre Ferrieux wrote: > > > (2) I'm not sure of the portability of the %p sprintf specifier > > > > It's portable and what should be used. > Thanks. Cleaned up and committed. -Alex |