Page 1 of 2

Debug

Posted: Sun Mar 08, 2009 1:32 pm
by Ugo
Dear friends,

how to debug the fivewin applications?

For now I put the msginfo/msgstop or other functions to know me the situation of some variables or only for to know if this piece of code is used.

But I am not happy, this approach takes too long to solve. :(

Are there other methods?

I remember debugging clipper that allowed me:
- to know the contents of variables;
- the step by step;
- the open areas;
- the change the value of variables;
- and more ...

Are possible also in fwh?

Many thanks for your suggestion.

Re: Debug

Posted: Fri Mar 13, 2009 4:04 pm
by Ugo
Dear friends,

How to make debugging of your applications?

Re: Debug

Posted: Mon Mar 16, 2009 8:28 am
by StefanHaupt
Ugo,

if I remember right, Andres Reyes Hernandes published a first beta of a windows debugger for xharbour some time ago. Search the forum for "WinDebug", his email is : andersreyes_mzt at yahoo.com

Re: Debug

Posted: Mon Mar 16, 2009 9:06 am
by anserkk
Ugo,

Win Debug
http://rapidshare.com/files/209798998/windebug.zip

I have not tried this. Please let us know your feedback.

Regards

Anser

Re: Debug

Posted: Tue Mar 17, 2009 2:30 am
by hua
Ugo wrote: For now I put the msginfo/msgstop or other functions to know me the situation of some variables or only for to know if this piece of code is used.
Ugo,
I'm using the same method as you do, only instead of msginfo I use outputDebugString(). I monitor stuffs using DebugView and this code below:

Code: Select all

function odb(name,val)
  local n := 1
  local cFrom := procfile(n) + " => " + trim(ProcName(n)) + "(" + str(ProcLine(n),,,.t.) +")"
  local varname

  default name := ""
  default val  := ""
  name := cValToChar(name)

  varname := cValToChar(varname)
  varname := trim(name)+": "
  outputdebugstring(cFrom+"| "+varname+cValToChar(val))
return nil
 
So if I want to monitor a var nCnt for example, I just write odb("nCnt", nCnt).
But I am not happy, this approach takes too long to solve. :(
Same here. Recently I started playing around with OLE and Excel. Wrote it using classes and dump about 2000 rows of data into Excel. I got an error message "Duplicate Key Index" that I have no idea at all where it came from because I already did a dbCloseAll() prior to that. So far, I have no idea where to start debugging it.

Re: Debug

Posted: Tue Mar 17, 2009 7:00 am
by anserkk
Ugo,

WinDebug
http://rapidshare.com/files/209798998/windebug.zip

Things to be taken care for winDebug to work properly

1. Compile your PRG's with /b (Debug parameter)
2. Instead of the xHarbour lib DEBUG.LIB, WDEBUG.LIB (Which comes along with WinDebug) should be linked to the exe
3. The CT.LIB also should be linked to the Exe. This lib is available in \xHarbour\lib
4. Run WinDebug.Exe before you run your application exe. It will be displayed in your taskbar near the clock/time
5. To close WinDebug, right click on it and choose the menu

Regards

Anser

Re: Debug

Posted: Tue Mar 17, 2009 9:57 am
by Antonio Linares
Ugo,

You can use Harbour/xHarbour debug (console mode).

Please compile FWH\samples\AltD.prg using /b:

buildh.bat altd /b

You have to link gtwin.lib instead of gtgui.lib

Re: Debug

Posted: Tue Mar 17, 2009 10:03 am
by Antonio Linares
Image

Re: Debug

Posted: Tue Mar 17, 2009 3:07 pm
by Carlos Mora
To use with outputdebugstring, but without any new function, and automágically include var's name, use the following command definition:

Code: Select all

#ifdef __RELEASE__
#xcommand DEBUG <cString1>[, <cStringN>] => 
#else
#translate ASSTRING( <x> ) => If( <x> == NIL, 'NIL', Transform( <x> , NIL ) ) + CRLF

#xcommand DEBUG <cString1>[, <cStringN>] ;
         => ;
          OutputDebugString( ProcName() +"("+LTrim(Str(ProcLine())) +") - " ) ; OutputDebugString( <"cString1">+" ("+ValType( <cString1> )+"): " ) ; OutputDebugString( ASSTRING( <cString1> ) ) ;
          [ ; OutputDebugString( ProcName() +"("+LTrim(Str(ProcLine())) +") - " ) ; OutputDebugString( <"cStringN">+" ("+ValType( <cStringN> )+"): " ) ; OutputDebugString( ASSTRING( <cStringN> ) ) ]

#endif
 
then inside your code this can be used like

DEBUG nVar, cText

then you'll get in the debug window

testfunc(2345) - nVar (N): 3
testfunc(2345) - cText (C): "this is a sample"

regards

Re: Debug

Posted: Tue Mar 17, 2009 4:16 pm
by frose
I'm working with the Visual Debugger from xHarbour.com:

Image

I don't want to miss it anymore.

Re: Debug

Posted: Wed Mar 18, 2009 1:43 am
by hua
Carlos Mora wrote:To use with outputdebugstring, but without any new function, and automágically include var's name, use the following command definition...
regards
That's neat. Thanks for sharing Carlos.

Re: Debug

Posted: Wed Mar 18, 2009 7:53 am
by angelo.c
Thanks Carlos for that neat piece of code. I use the OutputDebugString(...) command a lot in my code for debugging.

I modified yours slightly to make it more useful for me so that array values can be displayed on the output debug window.

Here is the modified code:

Code: Select all

#ifdef __RELEASE__
#xcommand DEBUG <cString1>[, <cStringN>] => 
#else
#translate ASSTRING( <x> ) => If( <x> == NIL, 'NIL', Transform( <x> , NIL ) ) + CRLF

#xcommand DEBUG <cString1>[, <cStringN>] ;
         => ;
          OutputDebugString( ProcName() +"("+LTrim(Str(ProcLine())) +") - " ) ; OutputDebugString( <"cString1">+" ("+ValType( <cString1> )+"): " ) ; OutputDebugString( FormatAsString( <cString1> ) )  ;
          [ ; OutputDebugString( ProcName() +"("+LTrim(Str(ProcLine())) +") - " ) ; OutputDebugString( <"cStringN">+" ("+ValType( <cStringN> )+"): " ) ; OutputDebugString( FormatAsString( <cStringN> ) )  ]

#endif


Then add these two routines somewhere in your code:

Code: Select all

******************************************************************
* Procedure: FormatAsString( xVal )
* Notes...: Writes information stored in xVal as a string suitable to be
*       output to any standard character output device.
*           Function returns the formatted string representing the value "xVal"
*****************************************************************
Function FormatAsString( xVal )
local cString, cValtype, cBuffer,i, j
local nFirstDimLen,nSecondDimLen,  nSecondDimType
local cTabSeparator := chr(VK_TAB)

  cValtype := VALTYPE(xVal)
  DO CASE
     CASE cValtype == "A"   //Check if an Array
         nFirstDimLen := len(xVal)  //First Dimension length
         //Init to a show array length and then output a new line
         cString := "Array Length is: " + alltrim(str(nFirstDimLen)) + "  ...  Array values follow:" + CRLF   
         if nFirstDimLen > 0
           FOR i := 1 TO nFirstDimLen       //Loop through the number of First dimension elements
             nSecondDimType := if (xVal[i] == NIL, "U", ValType(xVal[i]))  //Type of Second dimension element
             if nSecondDimType == 'A'
               nSecondDimLen := len(xVal[i])       //Number of Second dimension elements
               if nSecondDimLen != 0
                 // Must be non-zero length array
                 cBuffer :=  ""                         //Init to empty string
                 FOR j := 1 TO nSecondDimLen        //Loop through the number of Second dimension elements
                   cBuffer :=  cBuffer + ElementToString(xVal[i][j]) + cTabSeparator
                 NEXT  // j
               else  //if nSecondDimLen != 0
                 cBuffer := "Nil Array {}"
               endif  //if nSecondDimLen != 0
             else   //  if cValType == 'A'
                cBuffer :=  ElementToString(xVal[i])    //Convert element that is NOT an Array to a string value
             endif  //  if cValType == 'A'
             cString += cBuffer + CRLF          //Build resultant string
           NEXT  // i
         else
           cBuffer := "Nil Array {}"  + CRLF
         endif

     OTHERWISE
        // xVal is NOT an array at this point.
        cString := ElementToString(xVal) + CRLF
  ENDCASE

return cString


******************************************************************
* Procedure: ElementToString( xVal )
* Notes...: Function returns a string representing the value "xVal"
*****************************************************************
Function ElementToString(xVal)
local cBuffer, cValtype := VALTYPE(xVal)

 DO CASE
   CASE cValtype == "A" //Check if an Array
        cBuffer :=  "Recursive Array. Not Implemented"

   CASE cValtype == "L" //Logical value ... I prefer the displayed .T. or .F. notation
        cBuffer :=  if(xVal, ".T.", ".F.")

   CASE cValtype == "C" .OR. cValtype == "M"   //ASCII String or Memo value
        cBuffer :=  xVal

   CASE cValtype == "N" //Numeric
        cBuffer := Alltrim(str(xVal))

   CASE cValtype == "D" //Date
        cBuffer := DToC(xVal)

   OTHERWISE
     cBuffer := "Not Processed" // All other cases, then return "Not Processed"
 ENDCASE

return cBuffer




When you execute this:
local cText := "Array n := {2, 4, 6}"
local n := {2, 4, 6}
DEBUG cText, n, Date(), .T., 5, Nil

n := {1, "Test String",{3,4,5}, .t.}
DEBUG n

n := {}
DEBUG n




you get on the output debug window the following:
PACKIT(197) - cText (C): Array n := {2, 4, 6}
PACKIT(197) - n (A): Array Length is: 3 ... Array values follow:
2
4
6
PACKIT(197) - Date() (D): 18/03/2009
PACKIT(197) - .T. (L): .T.
PACKIT(197) - 5 (N): 5
PACKIT(197) - Nil (U): Not Processed
PACKIT(200) - n (A): Array Length is: 4 ... Array values follow:
1
Test String
3 4 5
.T.
PACKIT(203) - n (A): Array Length is: 0 ... Array values follow:


Ofcourse, the code can be tailored to suit yourselves; perhaps even displaying instantiated Object variables in a tabular form.

Best regards,
Angelo.c

Re: Debug

Posted: Thu Mar 19, 2009 12:32 pm
by Ugo
Dear friends,

wow!!!! :shock:
thank you for all suggestions!

I'm going to do the tests! :wink:

Re: Debug

Posted: Thu Mar 19, 2009 1:09 pm
by Ugo
anserkk wrote:WinDebug
http://rapidshare.com/files/209798998/windebug.zip

Things to be taken care for winDebug to work properly

1. Compile your PRG's with /b (Debug parameter)
2. Instead of the xHarbour lib DEBUG.LIB, WDEBUG.LIB (Which comes along with WinDebug) should be linked to the exe
3. The CT.LIB also should be linked to the Exe. This lib is available in \xHarbour\lib
4. Run WinDebug.Exe before you run your application exe. It will be displayed in your taskbar near the clock/time
5. To close WinDebug, right click on it and choose the menu
Dear Anser,

I see this with a productive solution. :wink:

I use the PCode 10 and the downloaded version is for PCode 9! :cry:

There is a new version?

Is possible to compile WinDebug?

Re: Debug

Posted: Thu Oct 20, 2011 7:22 am
by hua
I did a tiny change to Carlos's pre-processor directive. I changed the line

Code: Select all

#translate ASSTRING( <x> ) => If( <x> == NIL, 'NIL', Transform( <x> , NIL ) ) + CRLF
to

Code: Select all

#translate ASSTRING( <x> ) => valtoprg( <x> ) + CRLF
as the original statement generates a RTE when the data type is a pointer.