Debug

User avatar
Ugo
Posts: 283
Joined: Sat Oct 15, 2005 6:40 am
Location: Turin, Italy

Debug

Post 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.
Ciao, best regards,
Ugo
User avatar
Ugo
Posts: 283
Joined: Sat Oct 15, 2005 6:40 am
Location: Turin, Italy

Re: Debug

Post by Ugo »

Dear friends,

How to make debugging of your applications?
Ciao, best regards,
Ugo
StefanHaupt
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: Debug

Post 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
kind regards
Stefan
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Debug

Post 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
hua
Posts: 861
Joined: Fri Oct 28, 2005 2:27 am

Re: Debug

Post 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.
FWH 11.08/FWH 19.03
xHarbour 1.2.1 (Rev 6406) + BCC
Harbour 3.1 (Rev 17062) + BCC
Harbour 3.2.0dev (r1904111533) + BCC
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: Debug

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Debug

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Debug

Post by Antonio Linares »

Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
Carlos Mora
Posts: 988
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Debug

Post 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
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
User avatar
frose
Posts: 327
Joined: Tue Mar 10, 2009 11:54 am
Location: Germany, Gütersloh
Contact:

Re: Debug

Post by frose »

I'm working with the Visual Debugger from xHarbour.com:

Image

I don't want to miss it anymore.
hua
Posts: 861
Joined: Fri Oct 28, 2005 2:27 am

Re: Debug

Post 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.
FWH 11.08/FWH 19.03
xHarbour 1.2.1 (Rev 6406) + BCC
Harbour 3.1 (Rev 17062) + BCC
Harbour 3.2.0dev (r1904111533) + BCC
angelo.c
Posts: 36
Joined: Thu Mar 30, 2006 11:19 am

Re: Debug

Post 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
User avatar
Ugo
Posts: 283
Joined: Sat Oct 15, 2005 6:40 am
Location: Turin, Italy

Re: Debug

Post by Ugo »

Dear friends,

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

I'm going to do the tests! :wink:
Ciao, best regards,
Ugo
User avatar
Ugo
Posts: 283
Joined: Sat Oct 15, 2005 6:40 am
Location: Turin, Italy

Re: Debug

Post 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?
Ciao, best regards,
Ugo
hua
Posts: 861
Joined: Fri Oct 28, 2005 2:27 am

Re: Debug

Post 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.
FWH 11.08/FWH 19.03
xHarbour 1.2.1 (Rev 6406) + BCC
Harbour 3.1 (Rev 17062) + BCC
Harbour 3.2.0dev (r1904111533) + BCC
Post Reply