BlitzMax Debugger

BlitzMax Forums/BlitzMax Programming/BlitzMax Debugger

I am working on an IDE for BlitzMax that is soon to enter the testing phase. One of the aspects of the project that I have continually put off is getting the debugger to work correctly.

As I have it now, I am capturing the output from bmk.exe and showing it in my output text area. This is fine for normal compiling and error catching, but when you get an unhandled memory exception, you need to turn to debug mode. With debug enabled, instead of a memory exception being returned, I am getting a stream of "~>" characters until I halt execution.

If anyone can shed some light on returning proper debug error messages, please help if you can. I am especially interested in the advice of those who have written Max IDEs (simon, ziggy)

Sorry, but I haven't much time yet, but will go further in detail tomorrow.
Here is a small example on how to read debugdata, I have done this for the german comunity as part of a "manual debugging" tutorial.
It is mostly a extern Debugger, which allows you to get enhanced errormessages from your developed BMax Application.


Framework BRL.RamStream
Import BRL.WAVLoader
Import BRL.PNGLoader
Import BRL.FileSystem
Import PUB.FreeProcess
Import BRL.FreeAudioAudio
Import BRL.Win32MaxGUI

Incbin "Windows XP-Fehler.wav"
'Hier die Datei incbinnen, die ausgeführtwerden soll
Incbin "testback.exe"

Global Filename:String = "testback.exe"


Type TExDebug
   Field FilePath:String
   Field Process:TProcess
      
   Function Init:TExDebug(Url:String)
      Local D:TExDebug = New TExDebug
      If FileType(Url) = 0 Then SaveIncbintoDisk()
      D.FilePath = Url
      AppTitle = StripDir(Url)
      Return D
   End Function
   
   Method Start()
      Process = CreateProcess(FilePath)
      DeleteFile(FilePath)
      While Process.Status()
         Local Info:String = Process.err.ReadLine()
         If Info <> "" Then         
            'Processing ErrorMessage"
            Info = Info[2..]
            Local Uhe:Int = Len("Unhandled Exception")
            If Info[..Uhe] = "Unhandled Exception" Then
               '
               Process.pipe.WriteLine("T")
               Local Data:String = CollectErrorData()
               
               'Notify Info[Uhe + 1..] + "~n~n"+ "Info:~n"+ Data
               Local I:TErrorInfo = TErrorInfo.Create(AppTitle ,Info[Uhe + 1..] , Data)
               I.Show()
               'DebugStop()
               Process.pipe.WriteLine("Q")

               Process.Terminate()
               Delay 200
               DeleteFile(Filename)
            EndIf
            
         EndIf
      Wend
      Print FilePath + FileType(FilePath) + " : " + Process.Status()
      'Local T:Byte = DeleteFile(FilePath)
      'If Not T Then Print "File not deleted"
   End Method
   
   Method CollectErrorData:String()
      Local Data:String = ""
      Repeat
         Local Temp:String =  Process.err.ReadLine()
         'Data:+ Temp[2..] + "~n"
         If Temp[2] = Asc("@") Then
            Local LF:Int = Temp.Find("<")
            Temp = Temp.Replace( "<" , "")
            Temp = Temp.Replace( ">" , "")
            If Data <> "" Then Data:+"~n"
            Data:+ "Error Location in : ~n" + StripDir(Temp[2..LF - 1]) + "~nin Line\Row : ~n" + temp[LF - 1..] + "~n~n" + "Debugdata : ~n~n"
         Else
            Local Temp2:String = Temp.Replace("~~>" , "")
            If Temp2.ToLower().Find("stacktrace") <> 0 Then
               If Temp2 = "}" Then
                  Data:+ "~nDatablock Ended"
               ElseIf Temp2 <> ""
               'Temp2 = Temp2.Replace("}" , "")
               Data:+ Temp2 + "~n"
               EndIf
            EndIf
         EndIf
         
      Until  Temp = ""
      Return Data
   End Method
   
End Type




Local D:TEXDebug = TExDebug.Init(Filename)
   
D.Start()

'DeleteFile Filename

Type TErrorInfo
   Field Window:TGadget
   Field ErrorInfo:TGadget
   Field Title:String
   Field ErrorMessage:String
   Field ErrorData:String
   Field OKButton:TGadget
   
   Function Create:TErrorInfo(Title:String , Message:String , Data:String)
      Info:TErrorInfo = New TErrorInfo
      Info.Title = Title
      Info.ErrorMessage = Message
      Print Message
      Info.ErrorData = Data
      Return Info
   End Function
   
   Method Show()
      Local Sound:TSound = LoadSound("incbin::Windows XP-Fehler.wav")
      PlaySound(Sound)
      Local D:TGadget = Desktop()
      Local W:Int = 300
      Local H:Int = 400
      Window = CreateWindow(Title , D.Width / 2 - (W / 2) , D.Height / 2 - (H / 2) , W , H , , WINDOW_TITLEBAR)
      CreateLabel("Error : " + ErrorMessage , 20 , 20 , W - 20 , 40 , Window)
      CreateLabel("DebugData : " , 20 , 60 , W - 20 , 20 , Window)
      ErrorInfo = CreateTextArea(20 , 80 , W - 50 , H - 180 , Window , TEXTAREA_READONLY)
      SetTextAreaText(ErrorInfo , ErrorData)
      
      OKButton = CreateButton("OK",W/2-30,H-80,60,40,Window)
      
      While Window
         WaitEvent()
         If EventID() = EVENT_GADGETACTION
            'Select EventSource()
            'Case OKButton
               FreeGadget Window
               Exit
            'End Select
         EndIf
         If EventID() = EVENT_WINDOWCLOSE
            FreeGadget Window
            Exit
         EndIf
      Wend
   End Method
   


End Type

Function SaveIncbinToDisk()
   Local Bank:TBank = LoadBank("incbin::"+Filename)
   SaveBank( Bank , Filename)
   Bank = Null
End Function

Function OnEnd()
   TProcess.TerminateAll()
   
   'DeleteFile(Filename)
End Function 


Framework BRL.StandardIO

Type TTest
   Field A:Int
   
   Method Multi()
      Print A / 0
   End Method
   
End Type

Global Test:String = "Hello World"

Out(Test)

Local T:TTest = New TTest
T.A = 16
T = Null
T.Multi()


Function Out(Output:String)
   'DebugStop()
   Print Output
End Function 


The first code is the extern debugger, the 2nd is a test app, which forces an error. The 2nd code has to be build in debugmode.

Thanks for that. The IDE is written in VB, but I'm sure I'll be able to sort out the code for it. Any other code/advice is still welcome, I need all I can get.

To be honst, I can't remember right now how the debug information was called (it was sending a command throug the standard input stream of the running app). the best advice I can give is, run a BlitxMax debug application from the command prompt, to see all the 'debuging protocol' in details (how it works, how the data is presented, etc.)

Eikon,

Having taken a look myself, the best starting place is the Max IDE source - it will give you a good basis for writing one.

The biggest problem is updating the debugger tree as everything comes through the output, which you then need to process. You will also need to send through your own commands to get the detailed trace information. You need to also consider how much of the trace to output because a fairly large project may take a while to parse (talking seconds to process) - this part I'm still working with.

Good luck!

Thanks for all the help, guys. I thought I had it figured out, but have run into another brick wall. I am now able to communicate with bmk.exe and send it a 't', which I think is supposed to return the error information
(VB6 Code)            
If InStr(1, sOutput$, "Unhandled Exception") And frmMain.mnuDebug.Checked = True And DebugOn = False Then  ' Debug
     WriteFile hWritePipe2, "t", 1, tmpLen, CLng(0)
End If
After sending it the char, I now get more output:
~>Unhandled Exception:Attempt to access field or method of Null object
~>
that's the proper error msg, the only problem is that the output stops coming after this. From the examples, it appears that you should be able to get the line number and col for the error, etc. after you send the 't'. What do I need to do next to continue receiving data?

Hi, again. Check your mails, I have send you a VB 2005 snippet, about how I'm managing debug in my IDE.
But check for the following in your code:
Use WriteLine instead of Writefile or add a Chr(13) & Chr(10) after the t.

I got your mail, Klepto. Thanks for that.

Since I could never successfully send a message to bmk from StdIn in VB6, I decided to modify your BlitzMax source to create an external debugger that outputs the error information for me. It gets called behind the scenes from VB, then I capture the output and return the error information, file name, and line/col info.

I don't have full debug support yet (stop, step, etc), but hopefully this will be enough for the initial release of the IDE for testing.