Extensions for Debugging

I’ve been working on some debugging extensions, which are now at the point where they could use a round of in-the-field testing. If you’d like to help, you can download them from SourceForge.

Floyd Mode, Verbose Runtime Problem Messages, and Interactive Debugger are the three that most authors would be interested in; the others are just support code. Here’s a screenshot of the last:

Thanks!

(Edited to add screenshot.)

Thank goodness Aaron Reed mentioned this on planet i-f. I’m not sure how I missed this thread the first time around.

Thanks Brady, this looks like it’s going to be a how-did-I-ever-live-without-it kind of tool. I’ll let you know if I find anything dysfunctional.

Wow, thanks for the post, Aaron. I think the download count just quadrupled.

And thanks, Ron. It’d be great to get suggestions or bug reports. I probably won’t resume development for a week or so though; right now I’m enjoying my first read of the parser in I7.

For this:Include call stack tracking by Brady Garvin. Include verbose runtime problem messages by Brady Garvin. Include debug file parsing by Brady Garvin.I get this:

Worked fine without “debug file parsing”. And, that one has no documentation.

Oh, I’m also using Jesse’s Dynamic Objects extension, just to make things explode bigger, if that matters. And Editable Stored Actions, though I doubt it interferes much.

Right now I’m lost as to which extensions are the “top level” ones I need worry about, and which ones are just helpers for the others.

Also, can the “(call frame #3)” just be a concise “3:” against the left margin? And maybe squeeze " (at address 173924)" down to “@173924” or even omit it entirely unless I’m actually looking at assembly. Until then, the memory location isn’t useful to me. (Or is it? I still have an un-named rule or phrase right where my program goes off the rails.)

I did read (some of the) documentation… last week-ish… but not all of it… yet…

Further developments as things fail harder.

Okay, I’ll have a chance to look at it this evening. I might need to draft some inclusion instructions like Erik did for Glimmr. Regarding the missing documentation, I am still working on it. My free time sank to about zero mid-February, which is why I pushed the release out when I did, but documentation was one of the casualties.

Yes, I had this comment before and failed to address it properly. Let me write something up, and I’ll run it by you to see if it helps.

This is very doable. But I want to err on the side of verbosity in the default settings, so I’ll probably tie the formatting to a preference or two. I will also document how to change preferences from the source text, so you don’t have to switch settings every time the story is run.

(The addresses are printed by default mostly to distinguish like-named rules. Possibly that’s less of an issue that I thought? If so, I’ll drop them in the defaults.)

Okay. Thanks, Ron! :slight_smile:

Oh, and while I’m thinking of it, if you’re including Debug File Parsing and still seeing unnamed rules and phrases, you’ve probably found a bug. Let me know if there’s something I can take a look at there.

Oh, I see. Call Stack Tracking was giving call frame numbers even outside the debugger, where they aren’t at all useful. That’s now fixed. Likewise for the unnamed rule/phrase problem. You can download the patched Call Stack Tracking, Verbose Runtime Problem Messages, and Interactive Debugger here.

As for the compilation failure, I tried this:[code]Include Call Stack Tracking by Brady Garvin.
Include Verbose Runtime Problem Messages by Brady Garvin.
Include Debug File Parsing by Brady Garvin.
Include Version 6 of Dynamic Objects by Jesse McGrew.
Include Version 9 of Editable Stored Actions by Ron Newcomb.

The name of the symbolic link to the debug information file is “…”.
The name of the symbolic link to the intermediate I6 file is “…”.
The name of the symbolic link to the debugging log file is “…”.

There is a room.[/code]but it compiled quite merrily. Could you check whether there’s some other factor involved?

Re: compilation failure, I had stuck the includes mid-file, rather than at the top where they usually go. Placed at the top they worked fine.

I downloaded these extensions tonight and had a look at the installation instructions. I’m in a whiny, kvetchy mood, so please feel free to conclude that I’m expecting too much. But the instructions for setting up the debugger in Windows 7 – opening a Command Prompt as administrator, making symbolic links, and all --are pretty esoteric.

Might there be a way to write an installer that would handle these steps in an automated manner? The reason I’m asking is not just because I’m a lazy snot (although I am) but because I can’t quite see the average newcomer to Inform 7 wanting to jump through such finicky little hoops. The process of installing the debugger seems (to my way of thinking) to run directly counter to the whole Inform 7 ethos of “make it look like it’s not really computer programming at all.”

Plus, it appears the whole process of creating symbolic links will have to be redone for each game. Am I right in assuming that?

I’m only fussing about this because I really like the idea of giving Inform 7 a set of debugging tools. This package looks great! But…

It would be nice if the IDEs had a sort of plugin system, so that extensions like these could install post-build scripts.

Okay. I will still write something up, especially because Floyd Mode and Interactive Debugger contrive to set off Inform bug 666.

Also, further thanks for the feedback—a handful of bugs have been found and fixed as a consequence.

I can try my hand at one. Authors will have to trust that I’m not doing anything malicious to their machine.

Yes, unfortunately.

True, though someone would have to think pretty carefully about security.

After fiddling around with several installer-building packages, I decided that none of them really fit what I was trying to do and rolled my own. There’s now a cross-platform debugger-including utility in the latest (re-)release. As usual, see https://sourceforge.net/projects/i7grip/. The documentation has also been updated, as have several of the extensions—be sure to reinstall them.

(And if anyone knows a better way to work with Windows UAC from Java, I’d appreciate pointers; my feeble attempt is here.)

(The install no workie on WinXP, but you knew that.)

Naming things:
I can never remember if its “verbose runtime error messages” or “verbose runtime problem messages” or “verbose runtime problem errors” or “verbose run-time problem messages” or “verbose run-time error messages” or…

I realize it’s mostly Inform’s fault for the synonyms and is-there-a-hyphen-or-not, but usually its this extension i reach for first when I have unexpected behavior. (From my program, I mean. When I have unexpected behavior I reach for a pillow and blanket.)

Also, the “kernel of” thing… can you swap the naming convention on the two? Mainly, the kernel should have the author-given name, cause it’s where the author-given code sits. The shell around it is just for memory allocation purposes, so it should get the “allocate memory for…” bit prepended to the name.

Is it too much to ask for the parameters passed to the author-created functions? I’m trying to figure out how on earth a hat got into my concept-processing machinery.

EDIT: or is that an option? I notice that the documentation for VRPM actually does have a bit of actual documentation at the end:To say the call stack for a verbose runtime problem message: say "[the call stack with original arguments and temporary named values and catch tokens]".
what are the arguments here, and why aren’t they in the extension’s documentation? Also, the “Usage” section should go 2nd, after Synopsis but before the credits roll. That’s the section the author is usually looking for when first going to the extension’s documentation. “Requirements and Limitations” should likely be combined with “Regarding Bugs” since both sections are small. It reduces conceptual noise.

also, this bit: Book "Detailed Call Stacks for Verbose Runtime Problem Messages" (in place of Book "The Call Stack Format" in Verbose Runtime Problem Messages by Brady Garvin) is unnecessary. The version I put in my project occurs later in the source, so it overrides the extension’s provided default say-phrase.

this seems broken:within the kernel of "circumventing" (at address 294452) (the original arguments were <temporary named value 0> = <unknown kind>: 0, <temporary named value 1> = <unknown kind>: 540302, and <temporary named value 2> = <unknown kind>: 492718), within circumventing (at address 293870) (the original arguments were <temporary named value 0> = <unknown kind>: 540302 and <temporary named value 1> = <unknown kind>: 492718),

for To (actor - a person) could try (suggestion - a stored action) (this is circumventing):

It doesn’t know what a Person is? full test:[code]“test4” by Ron Newcomb

Include verbose runtime problem messages by brady garvin.

To say the call stack for a verbose runtime problem message:
say “[the call stack with original arguments]”.

To (actor - a person) could try (suggestion - a stored action) (this is circumventing): say the matching key of the actor.

when play begins, the hat could try the action of waiting.
a hat is a thing.

there is room.
[/code]

Yeah, sorry. I’d be happy to make it work, except that I don’t see any way to avoid a post-build script when the OS doesn’t grok symlinks.

Okay. What would be a better name?

Hmm. My main concern here is that ``the foo rule’’ refers to the shell—not the kernel—when rules are treated as values, and I don’t the want authors to have to remember that an unadorned rule name means one thing in some situations and something else in others.

They are documented in Call Stack Tracking, but I will repeat the explanation in Verbose Runtime Problem Messages since it also makes sense there. On that note, I am seriously considering a redesign where the format is controlled by global flags, not phrase wording, on the grounds that one would want to change format globally far more often than locally.

Can do.

Sure. I just wanted it to work if someone put it in before the inclusion.

The problem you show is actually a consequence of me not making the extensions’ roles clear enough. Verbose Runtime Problem Messages is responsible only for adding call stacks to the problem messages, so that you can use it without setting up symbolic links or running a batch file. If you add Debug File Parsing to the mix, the arguments acquire names and kinds, and if you further add Printing according to Kind Names, it will know how to print things like people.

That said, when I run the test case, I get this:within the I6 routine ArgumentTypeFailed (at address 184384) (the original arguments were file = <unknown kind>: 464625 / 0x716F1 and line = <unknown kind>: 20 / 0x14), within the I6 routine Resolver_0 (at address 383290) (the original arguments were t_0 = <no kind>: 618554 / 0x9703A, t_1 = <no kind>: 570874 / 0x8B5FA, filename = <no kind>: 464625 / 0x716F1, and line = <no kind>: 20 / 0x14), within the kernel of "when play begins" (at address 94836) (the original argument was i7baspl = <no kind>: 0 / 0x0) ...
meaning that the hat only shows up in an I6 routine where Debug File Parsing isn’t able to look up its kind. With Interactive Debugger one could use ``examine as’’ to cast it, but that’s not really an option here. I can probably add kind inference for resolver routines to bandage this particular case. I will have to think about what’s the right thing to do more generally.

Finally have time and a good excuse to try out these extensions. Initial impressions: incredible + wow!

A couple of things to note:

  • When working with any Glulx I/O functionality, it is often not desirable to test using Zoom, because CocoaGlk does so many things outside of the Glk spec. However, the symlinks have .glkdata extensions, which means that they need to be manually removed to work with Gargoyle, and vice-versa. There’s nothing that can be done about this: Zoom must have .glkdata extensions, and Gargoyle can’t have them. But it might be worth mentioning in the manual. EDITED TO ADD: or, since these are just symlinked, the java automaker could create both versions with no extensions and versions with .glkdata extensions.
  • I7 rule names referred to in I6 code using the (+ +) notation are resolved to a number in the debugger output. E.g., this line “if ( FollowRulebook( (+command-counting rules +) ) && RulebookSucceeded())” is printed in the debugger as “if ( FollowRulebook( 399 ) && RulebookSucceeded())”. There probably isn’t any way around this, but it would be nice to see the rule names, particularly since all of the HandleGlkEvent rules in Glulx Entry Points–probably included in most folks’ Glulx projects–are written this way. EDITED TO ADD: I’ve now posted for feedback a new version of GEP that does event handling at the I7 level, which in addition to other benefits also bypasses this little inconvenience.

And a question–is there any way to use the debugger in Quixe? I am sure that it would incredibly slow, but I can live with that. I’m just wondering if there’s a way to get the symlinked files into a game’s LocalStorage. I’m sure there are situations where auto.inf might not fit in LocalStorage, but assuming it does fit, would there be a way to set that up?

Thanks a bunch for making these. I shudder to think of all the time they would have saved me on past projects…

That’s a good idea. Will do.

No, I’m afraid not really, apart from asking the author to use commands like ``print 399 as a rulebook.’’

Hmm, probably. I’ll have to think about the right way to do that, and it also depends on what happens with Zarf’s idea for in-ulx debug data.

Also on that topic, I’m thinking that it would be nice to have (1) automatic breakpoints on illegal Glk behavior, like those on runtime problems, and (2) commands like break on output'' orbreak when `foo’ is printed.’’ They should both be possible.

As you can maybe tell, I haven’t had much time to work on the extensions—I still haven’t gotten to some of Ron’s feedback. But I appreciate the comments, and I’ll try to get the changes in as soon as I have a chance.

Here’s a proof-of-concept: eblong.com/zarf/tmp/quixedebug/play-remote.html

If you type “jump”, the interpreter will cause a fatal error, and the error console will display:

VM stack dump: 0x3c “Main__”, 0xb2f1 “Main”, 0x1c625 “FollowRulebook”, 0x1c78d “ProcessRulebook”, 0x1c78d “ProcessRulebook”, 0xb50e “GENERATE_ACTION_R”, 0x16e7e “BeginAction”, 0x16edc “ActionPrimitive”, 0x1c78d “ProcessRulebook”, 0x1c78d “ProcessRulebook”, 0xe06d “R_22”, 0x1c78d “ProcessRulebook”, 0x1c78d “ProcessRulebook”, 0xe507 “R_740”, 0x255e7 “Glk__Wrap”

To set this up, I used my blorb script to add the gameinfo.dbg file to the compiled blorb:

blorbtool.py test.gblorb import Data 9999 BINA gameinfo.dbg

Quixe is configured to look for Data chunk 9999, and parse it as Inform debugging information. This implementation saves only enough information to display a stack trace.

An Inform extension could use the glk_stream_open_resource() call to read that data chunk and parse it the same way. (However, the I7 IDE interpreters don’t support that call yet.)

Hmm, when you added glk_stream_open_resource et al., were there any plans made for Inform to support declarations of TEXT and BINA chunks? I am rather eager to get rid of the debugger’s symlink nonsense, and this seems like a good way to do that for the next Inform release.

I haven’t talked to Graham about supporting that feature at the I7 level. I agree that if it does, the author will have to be able to discriminate between text and binary inclusions.