Debugger

Sujets variés concernant le développement en PureBasic
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Debugger

Message par fweil »

Avant de passer ça en truc et astuces je le propose ici.

Nous sommes un certain nombre à vouloir un meilleur debug.

L'un dans l'autre, je trouve celui que nous avons tout à fait suffisant. Mais j'ai les mêmes remarques ou difficultés que tout le monde, en particulier pour ce qui est de l'affichage de chaines longues, ou simplement pour la redirection de la sortie vers d'autres modes que la fenêtre de base.

Alors pour mes besoins j'ai développé quelques fonctions que j'ai petit à petit fait évoluer pour 'encapsuler' la sortie du debugger.

Plutôt que de poster des demandes d'amélioration j'ai trouvé petit à petit que ce n'est pas plus difficle de faire certaines choses soi même.

Mais bon voila, maintenant que c'est fait, peut être y en aura t-il parmi vous qui trouveront cela utile ou qui auront des idées pour étendre ces fonctions et mieux satisfaire tout le monde.

Ici vous trouverez donc deux listings, le premier est un exemple d'utilisation, le second un include contenant les outils d'extension du debugger.

Le principe d'utilisation consiste à 'ouvrir' une sortie pour le debugger étendu, puis à utiliser celle-ci pour toute trace de debug.

Les sorties peuvent se faire sur :

- Console : la console DOS
- Debug : le debug intégré
- File : un fichier
- Window : une fenêtre

Voici les 2 listings.

Fichier : EnhancedDebugger.pb

Code : Tout sélectionner

Enumeration
  #Window_Main
  #Gadget_Editor
EndEnumeration

;
; Sample code for using EnhancedDebugger
;
IncludeFile("EnhancedDebugger.pbi")

  EnhancedDebugger_Start("Console") ; Start EnhancedDebugger console mode
  EnhancedDebugger_Start("Window") ; Start EnhancedDebugger window mode
  EnhancedDebugger_Start("Debug") ; Start EnhancedDebugger regular debug mode (NOP)
  EnhancedDebugger_Start("File:EnhancedDebugger_Output.txt") ; Start EnhancedDebugger regular debug mode (NOP)

  a$ = "The quick brown fox jumps over the lazy dog ... "
  a$ = a$ + a$
  a$ = a$ + a$

  EnhancedDebugger_Output("Console", a$) ; Outputs a$ as a regular string
  EnhancedDebugger_HexDump("Console", @a$, Len(a$), 32) ; Dumps memory from a$ start address to last character of a$, using a width of 32 chars for display
  EnhancedDebugger_SplittedString("Console", a$, 40) ; Display a$ splitting it in 40 chars width substrings
  
  Dim Array.l(12, 12)
  
  For i = 0 To 12
    a$ = ""
    For j = 0 To 12
      Array(i, j) = 12 * i + j
      a$ + Str(Array(i, j)) + " "
    Next
    EnhancedDebugger_Output("File", a$)
  Next

  If OpenWindow(0, 0, 0, 322, 150,#PB_Window_SystemMenu |#PB_Window_ScreenCentered,"Test Window")
      EnhancedDebugger_Output("Window", Str(WindowID()))
      If CreateGadgetList(WindowID(0))
          hEditorGadget = EditorGadget (0,8,8,306,133,#PB_Container_Raised) 
          EnhancedDebugger_Output("Window", "Editor gadget handle is : " + Str(hEditorGadget)) 
      EndIf
      For a=0 To 5 
        Text.s = "Line "+Str(a)
        EnhancedDebugger_Output("Window", "Adding a line : " + Text)
        AddGadgetItem(0,a,Text) 
      Next 
      Repeat
  EnhancedDebugger_BreakPoint("Window") ; Set a Break Point
      Until WaitWindowEvent()=#PB_Event_CloseWindow 
      CloseWindow(0)
  EndIf 
  EnhancedDebugger_BreakPoint("") ; Set a Break Point
  EnhancedDebugger_Close("") ; Close EnhancedDebugger
End
Fichier : EnhancedDebugger.pbi

Code : Tout sélectionner

Global EnhancedDebugger_WindowNumber.l
EnhancedDebugger_WindowNumber = 1234
Global EnhancedDebugger_EditorGadgetNumber.l
EnhancedDebugger_EditorGadgetNumber = 1235
Global EnhancedDebugger_IsWindow.l
EnhancedDebugger_IsWindow = #FALSE
Global EnhancedDebugger_IsConsole.l
EnhancedDebugger_IsConsole = #FALSE
Global EnhancedDebugger_FileName.s

Procedure AppendFile(FileName.s, String.s)
  If OpenFile(99, FileName)
      FileSeek(Lof())
      WriteStringN(String)
      CloseFile(99)
  EndIf
EndProcedure

;
; EnhancedDebugger_Start(Output) Starts EnhancedDebugger using Output output name
;
; Available modes are right now :
;
; - Console
; - Debug
; - File[:FileName]
; - Window
;
; This procedure sets EnhancedDebugger_OutputName as a global variable reusable in all other EnhancedDebugger procedures
;
Procedure EnhancedDebugger_Start(Output.s)
  If Left(Output, 4) = "File"
      EnhancedDebugger_FileName = StringField(Output, 2, ":")
      Output = "File"
      If EnhancedDebugger_FileName = ""
          EnhancedDebugger_FileName = "Debug.txt"
      EndIf
  EndIf
  EnhancedDebugger_WindowNumber = 1234
  EnhancedDebugger_EditorGadgetNumber = 1235
  Select Output
    Case "Console"
      OpenConsole()
      Debug "Debugger console opened"
      EnhancedDebugger_IsConsole = #TRUE
    Case "Debug"
    Case "Window"
      If WindowID()
          WindowID = WindowID()
      EndIf
      WindowXSize = 480
      WindowYSize = 360
      WindowX = GetSystemMetrics_(#SM_CXSCREEN) - WindowXSize
      WindowY = 0
      If OpenWindow(EnhancedDebugger_WindowNumber, WindowX, WindowY, WindowXSize, WindowYSize, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_BorderLess, "EnhancedDebugger Window")
          AddKeyboardShortcut(EnhancedDebugger_WindowNumber, #PB_Shortcut_Escape, #PB_Shortcut_Escape)
          If CreateGadgetList(WindowID(EnhancedDebugger_WindowNumber))
              EditorGadget(EnhancedDebugger_EditorGadgetNumber, 10, 10, WindowXSize - 20, WindowYSize - 20, "")
          EndIf
      EndIf
      If WindowID
          SetForegroundWindow_(WindowID)
      EndIf
      Debug "Debugger window opened"
      EnhancedDebugger_IsWindow = #TRUE
    Default
  EndSelect
EndProcedure

;
; EnhancedDebugger_Close(Output) closes the EnhancedDebugger device named in Output
; If Output is #NULL all opened EnhancedDebugger devices are closed.
;
Procedure EnhancedDebugger_Close(Output.s)
  Select Output
    Case "Console"
      If EnhancedDebugger_IsConsole
          CloseConsole()
      EndIf
    Case "Window"
      If EnhancedDebugger_IsWindow
          CloseWindow(EnhancedDebugger_WindowNumber)
      EndIf
    Case ""
      If EnhancedDebugger_IsConsole
          CloseConsole()
      EndIf
      If EnhancedDebugger_IsWindow
          CloseWindow(EnhancedDebugger_WindowNumber)
      EndIf
  EndSelect
EndProcedure

;
; EnhancedDebugger_Output(Output, String) outputs String to the Output device declared using EnhancedDebugger_Start
;
Procedure EnhancedDebugger_Output(Output.s, String.s)
  Select Output
    Case "Console"
      PrintN(String)
    Case "Debug"
      Debug String
    Case "File"
      AppendFile(EnhancedDebugger_FileName, String)
    Case "Window"
      If WindowID()
          WindowID = WindowID()
      EndIf
      UseWindow(EnhancedDebugger_WindowNumber)
      AddGadgetItem(EnhancedDebugger_EditorGadgetNumber, -1, String)
      If WindowID
          SetForegroundWindow_(WindowID)
      EndIf
    Default
      Debug String
  EndSelect
EndProcedure

;
; EnhancedDebugger_BreakPoint(Output) halts the program in a loop using Output device
;
Procedure EnhancedDebugger_BreakPoint(Output.s)
  Select Output
    Case "Console"
      While Inkey() = ""
      Wend
    Case "Debug"
      CallDebugger
    Case "Window"
      If WindowID()
          WindowID = WindowID()
      EndIf
      UseWindow(EnhancedDebugger_WindowNumber)
      SetWindowTitle(EnhancedDebugger_WindowNumber, "EnhancedDebugger Window : Break")
      Quit = #FALSE
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_Menu
            Select EventMenuID()
              Case #PB_Shortcut_Escape
                Quit = #TRUE
            EndSelect
        EndSelect
      Until Quit
      SetWindowTitle(EnhancedDebugger_WindowNumber, "EnhancedDebugger Window")
      If WindowID
          SetForegroundWindow_(WindowID)
      EndIf
    Default
  EndSelect
EndProcedure

;
; EnhancedDebugger_SplittedString(Output, String, Length) splits a string in multilined text of Length width to the Output device
;
Procedure EnhancedDebugger_SplittedString(Output.s, String.s, Length.l)
  For i = 1 To Len(String)
    EnhancedDebugger_Output(Output, Str(i) + " : " + Mid(String, i, Length))
    i + Length - 1
  Next
EndProcedure

;
; EnhancedDebugger_SplittedString(Output, String, Length) outputs an hexadecimal dump both Hex and ASCII representation
; using Length as memory size to display and Width as line width to use for display, starting the memory scan at Address.
; Output is the device used.
;
Procedure EnhancedDebugger_HexDump(Output.s, Address.l, Length.l, Width.l)
  EnhancedDebugger_Output(Output, "***** HexDump : " + Hex(Address) + " rendering " + Hex(Length) + " bytes")
  *Buffer = AllocateMemory(Length)
  CopyMemory(Address, *Buffer, Length)
  For i = 0 To Length - 1
    If PeekB(*Buffer + i) < ' '
        PokeB(*Buffer + i, ' ')
    EndIf
  Next
  For i = 0 To Length - 1
    a$ = ""
    For j = i To i + Width - 1
      a$ = a$ + RSet(Hex(PeekB(Address + j) & $FF), 2, "0") + " "
    Next
    EnhancedDebugger_Output(Output, RSet(Hex(Address + i), 8, "0") + " | " + a$ + " - " + PeekS(*Buffer + i, Width))
    i + Width - 1
  Next
EndProcedure
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.