AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

110.22 Ahk script Debugger 1.1.5b (line-by-line capable)

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Decarlo110



Joined: 15 Dec 2004
Posts: 303
Location: United States

PostPosted: Tue Jan 10, 2006 5:46 am    Post subject: 110.22 Ahk script Debugger 1.1.5b (line-by-line capable) Reply with quote

Usage:

#!d debugger settings dialog. Generates or reads from .ini file.
F12 Breaks if there is no splashtext-break; useful if no Line# Return is specified.
RCtrl continue from break; hold down for continuous advance.

Note1: At break-points, hotkeys and timers will still run.
Note2: The presence of timers other than the debug timer will prevent straightforward, line-by-line monitoring of non-timer code.

settings (in settings dialog):

use debug = allows toggling of debug mode.

debug line-by-line = if not checked, the debugger will intercept and display commands which have an execution time of at least .01 sec.

skip 400+ lines-passed alert = is displayed when each of ~400 code lines in LinesHistory execute in less than .01 sec, meaning the debugger will miss monitoring some lines.

sleep to maintain active windows (millisec) = allows adjustment in combination with A_WinDelay, for active windows seen by target code.

Line# Return of target code = used to alert on thread completed (optional).

which Lines to check = if this is used, turn off line-by-line for faster debugging. Specified lines should be Sleep 10 or higher, used as break-points.

---

To debug, place the following 2 lines at the top of the target code to be debugged, after the subroutine label:
Code:
if debug_On
   GoSub Debug_Init


If you have an OnClipboardChange routine, place the following immediately after the label:
Code:
if OnClipboardChangeDeactivated OR debugRun   ; or just: if debugRun
   RETURN


Along with the Break/Exit-debug options in the debugger, you may also Reload from the File menu of the Ahk main window.

Here is the debugger code (an example for debugging is given at the end):

Code:
SetTitleMatchMode, 2
GoSub Load_DebuggerSettings   ; place in auto-execute section
return

Load_DebuggerSettings:
if FileExist(A_ScriptDir . "\Ahk debugger settings.ini")
{
   IniRead, Debug_On, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_On
   IniRead, Debug_LineByLine, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_LineByLine
   IniRead, Debug_skip400alert, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_skip400alert
   IniRead, Debug_sleepToActive, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_sleepToActive
   IniRead, Debug_line#_Return, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_line#_Return
   IniRead, Debug_LinesToCheck, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_LinesToCheck
}
else
{
   Debug_On = 1
   Debug_LineByLine = 1
   Debug_skip400alert = 0
   Debug_sleepToActive = 100
   Debug_line#_Return = 0
   Debug_LinesToCheck = 0

   FileAppend,
   ( LTrim
   [preferences]

   Debug_On = 1
   Debug_LineByLine = 1
   Debug_skip400alert = 0
   Debug_sleepToActive = 100
   Debug_line#_Return = 0
   Debug_LinesToCheck = 0
   ), %A_ScriptDir%\Ahk debugger settings.ini
}
;msgbox,,, loaded, .5
return


#!d::

GoSub Load_DebuggerSettings
Gui 31:Destroy
Gui, 31: +AlwaysOnTop
Gui, 31: Add, Checkbox, x16 y7 h20 vDebug_On Checked%Debug_On%, use debug
Gui, 31: Add, Button, Default Hidden x153 y7, OK
Gui, 31: Add, Checkbox, x16 y29 h20 vDebug_LineByLine Checked%Debug_LineByLine%, debug line-by-line
Gui, 31: Add, Checkbox, x16 y51 h20 vDebug_skip400alert Checked%Debug_skip400alert%, skip 400+ lines-passed alert
Gui, 31: Add, Edit, x16 y76 w42 h20 vDebug_sleepToActive, %Debug_sleepToActive%  ;100
Gui, 31: Add, Text, x59 y76 w164,sleep to maintain active windows seen by target code (millisec)
Gui, 31: Add, Edit, x16 y108 w42 h20 vDebug_line#_Return, %Debug_line#_Return%  ;0
Gui, 31: Add, Text, x60 y108 w190, Line# Return of target code (optional).`nused to alert on thread completed
Gui, 31: Add, Edit, x16 y140 w210 h20 vDebug_LinesToCheck, %Debug_LinesToCheck%  ;0
Gui, 31: Add, Text, x16 y162 w210, which Lines to check (0 or blank = all)`nuse commas for 2+
, spaces optional.`nSet specified Lines as Sleep 10 or greater.
Gui, 31: Show, h210 w250, Debug settings
return


31ButtonOK:
31GuiClose:
31GuiEscape:
Gui, 31:Submit
Gui, 31:Destroy
IniWrite, %Debug_On%, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_On
IniWrite, %Debug_LineByLine%, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_LineByLine
IniWrite, %Debug_skip400alert%, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_skip400alert
IniWrite, %Debug_sleepToActive%, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_sleepToActive
IniWrite, %Debug_line#_Return%, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_line#_Return
IniWrite, %Debug_LinesToCheck%, %A_ScriptDir%\Ahk debugger settings.ini, preferences, Debug_LinesToCheck
return


Debug_Init:

WinShow, - AutoHotkey v ahk_class AutoHotkey   ; in case DetectHiddenWindows is off.  exclude tooltips
WinRestore, - AutoHotkey v ahk_class AutoHotkey   ; prepare for WinMove
WinMove, - AutoHotkey v ahk_class AutoHotkey,, 0, 590, 1024, 150  ; set window to debug-style shape
WinActivate, - AutoHotkey v ahk_class AutoHotkey
Thread, Interrupt, 0   ; always allow debug timer
if Debug_LineByLine
   SetBatchLines 1      ; allows line-by-line debug
SetTimer Debug, 1
sleep 300   ; SetBatchLines=1 requires sufficient sleep to properly take effect
return


Debug:

Debug_line#_Return2 := A_LineNumber + 2
Debug()
return


; adding/deleting lines in this code block requires adjusting Debug_line#_Close
Debug()
{
   Debug_line#_Close := A_LineNumber + 110   ; Line of closing brace *******

   global Debug_line#_Return   ; return of target code being debugged
   global Debug_line#_Return2   ; return of debug timer routine
   global Debug_LinesToCheck
   global debugRun         ; for OnClipboardChange handling
   global Debug_On, Debug_skip400alert, Debug_sleepToActive   ; settings
   static Debug_line#_Return3

   debugRun ++
   sleep Debug_sleepToActive   ; wait for window activated by target code
   winA := WinActive("A")      ; store ID of active window
   clipSaved_debug := clipboard
   clipboard =

   ListLines
   WinActivate, - AutoHotkey v ahk_class AutoHotkey   ; exclude Ahk tooltips
   ControlSend,, +^{end}^c, - AutoHotkey v ahk_class AutoHotkey   ; call main window
   codeToDebug := clipboard
   ControlSend,, ^{end}{up 11}+{end}^c, - AutoHotkey v ahk_class AutoHotkey  ; up # to last line before debug call
   Loop
   {
      code_Line := clipboard
      code_Line := StringL( code_Line, InStr(code_Line, ":")-1 )
      if code_Line is number
         BREAK
      else
         ControlSend,, {up}{home}+{end}^c, - AutoHotkey v ahk_class AutoHotkey
   }
   clipboard := clipSaved_debug
   if (code_Line = Debug_line#_Return2)   ; dont display Return of debug timer
   {
      Loop 400
         a=1
      WinActivate, ahk_id %winA%
      WinWaitActive, ahk_id %winA%   ; restore active window seen by target code
      Debug_line#_Return3 := A_LineNumber + 2
      if ! GetKeyState("F12", "p")
         RETURN
   }
   Loop 4
      SendMessage, 0x115, 0, 0, Edit1, - AutoHotkey v ahk_class AutoHotkey

   If !Debug_skip400alert & (debugRun >1)
     && !InStr(codeToDebug, "`n" . Debug_line#_Close . ": }")
     && !InStr(codeToDebug, "`n" . Debug_line#_Return3 . ": ")
   {
      msgbox, 4353, debug,
      ( LTrim
      More than 400 lines were executed in 0.00 sec.
      Some lines of code being debugged have scrolled past in the Line history buffer.`n
      1) Verify that Debug_line#_Close matches the line # of the closing } in Debug()`n
      2) Use    Thread, Interrupt, 0   before   SetTimer, Debug, 1`n
      3) A sleep of 10 or greater may be needed logically prior to Line %code_Line%`n
      [This alert can be deactivated in the debug settings dialog.]`n
      Continue debug?
      )
      IfMsgBox, Cancel
      {
         debugRun =
         SetTimer Debug, off
         WinMove, - AutoHotkey v ahk_class AutoHotkey,, 153, 153, 768, 558
         Loop 400   ; for code tracing readability
            a=1
         RETURN
      }
   }
   If (debugRun > 1) AND (InStr(codeToDebug, "`n" . Debug_line#_Return . ": " ) )
   {
      SplashText("*thread completed - press Space to exit", 0, 350)
      Keywait Space, D
      Keywait Space
      debugRun =
      SetTimer Debug, off
      SplashTextOff
      WinMove, - AutoHotkey v ahk_class AutoHotkey,, 153, 153, 768, 558
      WinMinimize - AutoHotkey v ahk_class AutoHotkey
      Loop 400
         a=1
      RETURN
   }
/*   ; display lines in preferred editor
   ControlSend,, ^g, <editor_caption>
   sleep 50   ; use higher Priority to prevent interruption
   ControlSend,, %code_Line%{Enter}, <editor_caption>
*/
   if ( ! Debug_LinesToCheck ) OR In(code_Line, Debug_LinesToCheck) OR GetKeyState("F12", "p")
   {
      SplashText("variables current to Line " . code_Line
      . "   press RCtrl to continue.  RCtrl.RShift to exit debug", 0, 500)
      WinSet, Enable,, exit debug
      Keywait RCtrl, D
      sleep 150
      if GetKeyState("RShift", "p") AND GetKeyState("RCtrl", "p")
      {
         ; needed to exit.  using before Keywait above disallows other threads
         Thread, Priority, 999

         debugRun =
         SetTimer, Debug, off
         WinRestore, - AutoHotkey v ahk_class AutoHotkey
         WinMove, - AutoHotkey v ahk_class AutoHotkey,, 153, 153, 768, 558
         WinMinimize - AutoHotkey v ahk_class AutoHotkey
      }
      SplashTextOff
   }
   Loop 400   ; for code tracing readability & to prevent false thread-complete alert
      a=1
   WinActivate, ahk_id %winA%
   WinWaitActive, ahk_id %winA%,, 1.2   ; restore active window seen by target code
}   ; this line number must match Debug_line#_Close *******


StringL(in, charsToKeep, charsToTrim="")
{
   StringLeft, out, in, %charsToKeep%
   if charsToTrim
      StringTrimLeft, out, out, %charsToTrim%
   return out
}

In( a, b )   ; If a in b list
{
   Loop, Parse, b, `,, %A_Space%%A_Tab%
      if a = %A_LoopField%
         Return 1
}

SplashText(title="", timeout="", width="", height="", text="")   ; default timeout 700
{
   SplashTextOn, %Width%, %Height%, %Title%, %Text%
   if timeout =
      sleep 700
   else if timeout = 0   ; leave on until replaced or turned off later
      RETURN
   else
      sleep %timeout%
   SplashTextOff
   return
}


!-::   ; example code for debug

if debug_On
   GoSub Debug_Init

; the lines above prepare the debug
; the lines below are the code to debug (example)

Loop 3
{
   sleep 10
   a=1
   b=2
   c=3
   d=4
}
Return


i will probably improve the code to optionally show last 10 lines executed, or last N lines specified by the user. Also, it would be good to have a display of target variables, selected by the user beforehand. Currently, ^v to display all the script's variables, will have to suffice. I will also look into removing the timer-limitation in line-by-line mode.
_________________
1) The Open Source Definition http://www.opensource.org/docs/definition_plain.php

2) Intuitive. Logical. Versatile. Adaptable. <<AutoHotkey>>


Last edited by Decarlo110 on Sun Jan 15, 2006 2:40 pm; edited 3 times in total
Back to top
View user's profile Send private message
toralf



Joined: 31 Jan 2005
Posts: 3842
Location: Bremen, Germany

PostPosted: Tue Jan 10, 2006 8:28 am    Post subject: Reply with quote

That's a great idea. When I find time I will study the code. Thanks for sharing.
_________________
Ciao
toralf
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Thalon



Joined: 12 Jul 2005
Posts: 640

PostPosted: Tue Jan 10, 2006 9:56 am    Post subject: Reply with quote

Yes, it's a great script!
Simple to read, but I will also have to try the different settings..

Nice 1!

Thalon
_________________
AHK-Icon-Changer
AHK-IRC
deutsches Forum
SacredVault
Back to top
View user's profile Send private message
toralf



Joined: 31 Jan 2005
Posts: 3842
Location: Bremen, Germany

PostPosted: Tue Jan 10, 2006 10:34 am    Post subject: Reply with quote

don't these functions
Code:
StringL(in, charsToKeep, charsToTrim="")
InString(a,b)
already exist in AHK? I thought StringMid and InStr() would do the same thing?
_________________
Ciao
toralf
Back to top
View user's profile Send private message Send e-mail Visit poster's website
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Tue Jan 10, 2006 10:02 pm    Post subject: Reply with quote

An interactive AHk debugger is an interesting idea. Could be useful to help new users get a feel for AHk.
Back to top
View user's profile Send private message
Decarlo110



Joined: 15 Dec 2004
Posts: 303
Location: United States

PostPosted: Thu Jan 12, 2006 12:50 am    Post subject: Reply with quote

toralf wrote:
don't these functions
Code:
StringL(in, charsToKeep, charsToTrim="")
InString(a,b)

already exist in AHK? I thought StringMid and InStr() would do the same thing?

You are right that StringMid can be used, but i've personally found StringL() to be a bit more useful than StringMid() would be, and so it has become my preference. On InString() vs. InStr(), my use of InString() had simply become a habit (there were 2 months after Functions had first become available that the current built-in functions were not yet built-in), plus i stripped part of my custom function that i had been experimenting with. Anyway, i've changed the code to use InStr() throughout. Thanks for mentioning it.

---

For those who have been experimenting with the debugger, you may have noticed that the line-by-line mode wasnt really line-by-line. In v1.1.2 it had been working, but when i coded the Debug_Init subroutine, i changed the sleep value to 10, which apparently affects whether SetBatchLines=1 takes effect. However, this has been fixed by raising the Sleep period to a higher value (300).

Code:
; v1.1.4

; fixed line-by-line mode
; added Return=Submit+Close in settings dialog


Thanks all for the compliments. I hope to improve the code further.
_________________
1) The Open Source Definition http://www.opensource.org/docs/definition_plain.php

2) Intuitive. Logical. Versatile. Adaptable. <<AutoHotkey>>


Last edited by Decarlo110 on Sun Jan 15, 2006 2:42 pm; edited 1 time in total
Back to top
View user's profile Send private message
Decarlo110



Joined: 15 Dec 2004
Posts: 303
Location: United States

PostPosted: Sun Jan 15, 2006 9:14 am    Post subject: Reply with quote

Code:
; v1.1.5
;
; fixed/eliminated indefinite waiting if target script uses dialog windows

_________________
1) The Open Source Definition http://www.opensource.org/docs/definition_plain.php

2) Intuitive. Logical. Versatile. Adaptable. <<AutoHotkey>>
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group