Show callstack in AHK window
#1
Posted 30 July 2012 - 05:21 PM
#2
Posted 30 July 2012 - 06:50 PM
Link: SciTE4AutoHotkey debugging
#3
Posted 30 July 2012 - 09:02 PM
In case of difficult to reproduce problems it's also important to halt the script at the current line and not at predefined breakpoints.
If a debugger could support these things reliably it would of course be the ideal solution, but I don't see AHK and the relevant editors there yet.
A simple callstack print in the AHK window would help very much for these cases. It might also be good to list the values of the local variables at the last executed line if possible.
#4
Posted 30 July 2012 - 10:12 PM
You can use the following to attach the current script to any listening debugger:
F12::
DetectHiddenWindows On
PostMessage DllCall("RegisterWindowMessage", "str", "AHK_ATTACH_DEBUGGER"),,,, ahk_id %A_ScriptHwnd%
returnTested okay on XDebugClient and Notepad++. XDebugClient didn't show the line pointer until I stepped one line, but it did work. You can detach Notepad++ by clicking the DBG button and sending detach -i whatever, but reattaching doesn't appear to work.I'm more interested in improving the DBGp-based tools than adding new tools, but I will consider your suggestion.
#5
Posted 31 July 2012 - 07:59 AM
In Notepad++ I changed its settings to break at current line which worked, but a few seconds afterwards I got an error message from AHK that an internal error occured in the debugger engine. In Notepad++ the log looks like this:
Accept: 127.0.0.1 Recv: <?xml version="1.0" encoding="UTF-8"?><init appid="AutoHotkey" ide_key="" session="" thread="7420" parent="" language="AutoHotkey" protocol_version="1.0" fileuri="file:///D%3A/Projekte/Autohotkey/7plus/7plus.ahk"/> Send: feature_set -i 1 -n max_depth -v 5 Send: feature_set -i 2 -n max_children -v 15 Send: feature_set -i 3 -n max_data -v 512 Send: breakpoint_list -i 4 Send: step_into -i 5 ---- Recv: <?xml version="1.0" encoding="UTF-8"?><response command="feature_set" feature="max_depth" success="1" transaction_id="1"/> Recv: <?xml version="1.0" encoding="UTF-8"?><response command="feature_set" feature="max_children" success="1" transaction_id="2"/> Recv: <?xml version="1.0" encoding="UTF-8"?><response command="feature_set" feature="max_data" success="1" transaction_id="3"/> Recv: <?xml version="1.0" encoding="UTF-8"?><response command="breakpoint_list" transaction_id="4"></response> Recv: <?xml version="1.0" encoding="UTF-8"?><response command="step_into" status="break" reason="ok" transaction_id="5"/> Send: stack_get -i 6 Send: breakpoint_list -i 7 Send: context_get -i 8 -c 0 Send: context_get -i 9 -c 1 ---- Recv: <?xml version="1.0" encoding="UTF-8"?><response command="stack_get" transaction_id="6"><stack level="0" type="file" filename="file:///D%3A/Projekte/Autohotkey/7plus/MessageHooks.ahk" lineno="4" where="HookProc()"/></response> Recv: <?xml version="1.0" encoding="UTF-8"?><response command="breakpoint_list" transaction_id="7"></response> Recv: <?xml version="1.0" encoding="UTF-8"?><response command="context_get" context="0" transaction_id="8"><property name="dwEventThread" fullname="dwEventThread" type="integer" facet="" children="0" encoding="base64" size="4">MTIyNA==</property><property name="dwmsEventTime" fullname="dwmsEventTime" type="integer" facet="" children="0" encoding="base64" size="8">Njg5MTY1MzE=</property><property name="event" fullname="event" type="integer" facet="" children="0" encoding="base64" size="5">MzI3Nzg=</property><property name="hWinEventHook" fullname="hWinEventHook" type="integer" facet="" children="0" encoding="base64" size="9">MjA4NDA3NTUz</property><property name="hwnd" fullname="hwnd" type="integer" facet="" children="0" encoding="base64" size="7">Mjk1MDMwNA==</property><property name="idChild" fullname="idChild" type="integer" facet="" children="0" encoding="base64" size="1">MA==</property><property name="idObject" fullname="idObject" type="integer" facet="" children="0" encoding="base64" size="1">MA==</property><property name="state" fullname="state" type="undefined" facet="" children="0" encoding="base64" size="0"></property><property name="style" fullname="style" type="undefined" facet="" children="0" encoding="base64" size="0"></property><property name="Trigger" fullname="Trigger" type="undefined" facet="" children="0" encoding="base64" size="0"></property></response> ---- Disconnect: 127.0.0.1I tried to disable the shell hook callbacks and it stopped in a timer where the same thing happened. I also tried to disable the AutoExecute section of my script to skip as much code of it as possible but with same results. It then halted during an evaluation of an #if condition and showed the error again.
Using a simple test script like the following works fine though:
x := 1
while(true)
{
x++
sleep 1000
}
#y::
DetectHiddenWindows On
PostMessage DllCall("RegisterWindowMessage", "str", "AHK_ATTACH_DEBUGGER"),,,, ahk_id %A_ScriptHwnd%
returnIf you want to use my script for testing purposes, you can get it at <!-- m -->http://chriss85.bpla... ... Source.zip<!-- m --> (run 7plus.ahk)To avoid changes to your system you should run it with the "-portable" command line argument. It should only write to %Temp%\7plus then and revert all changes on exit.
#6
Posted 01 August 2012 - 08:21 AM
That's why I said "XDebugClient didn't show the line pointer until I stepped one line". More precisely, it doesn't retrieve the call stack (including the current line pointer) until it receives a response to a continuation command, which means you need to send a continuation command (run or step).XDebugClient seems to attach, but opens only the main script file and does not appear to break.
If the script is idling (i.e. no threads are running when you attach), you'll need to step_into anyway.
I think that the DBGp plugin sends step_into if that option is enabled or run if it is not.In Notepad++ I changed its settings to break at current line which worked,
Sorry, you found a bug in the debugger engine: the property depth limit is ignored in certain cases. To work around it, open the DBGp config and set "Maximum depth of elements" to twice the limit you want, and if using the "Watches" pane, only add variables and not objects (but a few seconds afterwards I got an error message from AHK that an internal error occured in the debugger engine.
CTrigger is okay, CTrigger.Categories is not).The debugger crashes with your script (when the depth limit is ignored) because of circular references like
CTrigger.Categories.7plus.1.base -> CTrigger.I just remembered that scripts can retrieve the call stack by calling Exception() repeatedly. See [AHK_L] How to get CallStack - solution. It's unlikely that any ListLines-style built-in feature would provide any more information than this.
#7
Posted 01 August 2012 - 09:24 AM
I knew about the Exception-callstack method, but I thought it would need to be used at the place of code in question. After trying it however, I saw that the new pseudo thread from a hotkey is simply placed on top of the stack so it might work out.
#8
Posted 02 August 2012 - 10:22 PM
Maybe that gives you an idea of how much branching there is: each type of trigger leads to Categories, and each category leads back to Categories.C7plusStartTrigger.base.Categories.7plus.1.base.Categories.System.3.base.Categories.Hotkeys.3.base.Categories.Hotkeys.1.base.base.base
This setting limits the amount of nesting in a single query. Note that the debugger client may opt to expand further by re-querying a child property. XDebugClient does this, but Notepad++ does not. However, you can add something like
Var.x.y[42].z to the watch list to drill deeper. (This is a subset of expression syntax, not an expression.)With a limit of 5, the debugger engine takes maybe a second or two to return all global variables, but Notepad++ takes much longer and a lot of RAM to populate its display.
I'm having trouble with autohotkey.net, but you can get v1.1.08.01 here:
dropbox/AutoHotkey_L_Install.exe
The only change is a fix for this bug.
There are two reasons that I said to use "twice the limit":Before I had low values (Max depth: 5, Number of child elements: 15) when the issue occured.
[*:1ouf8t1v]Each nesting level was counted twice toward the depth.
[*:1ouf8t1v]If the remaining depth is 1 and you subtract 2, the depth is now -1, and the limit no longer applies. Therefore any even number will be okay. Twice any whole number is always an even number.
The exception was that if you query an object (
x.y) directly, the first level is counted once toward the depth, so the limit must be odd...
#9
Posted 03 August 2012 - 06:13 AM
#10
Posted 09 August 2012 - 08:38 AM




