FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Debug
Posts: 283
Joined: Sat Oct 15, 2005 06:40 AM
Debug
Posted: Sun Mar 08, 2009 01:32 PM

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
Posts: 283
Joined: Sat Oct 15, 2005 06:40 AM
Re: Debug
Posted: Fri Mar 13, 2009 04:04 PM

Dear friends,

How to make debugging of your applications?

Ciao, best regards,

Ugo
Posts: 824
Joined: Thu Oct 13, 2005 07:39 AM
Re: Debug
Posted: Mon Mar 16, 2009 08:28 AM

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
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: Debug
Posted: Mon Mar 16, 2009 09:06 AM

Ugo,

Win Debug

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

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

Regards

Anser

Posts: 1096
Joined: Fri Oct 28, 2005 02:27 AM
Re: Debug
Posted: Tue Mar 17, 2009 02:30 AM
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 (fw): Select all Collapse
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.12

BCC5.82/BCC7.3

xHarbour/Harbour
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: Debug
Posted: Tue Mar 17, 2009 07:00 AM
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
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Debug
Posted: Tue Mar 17, 2009 09:57 AM

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
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Debug
Posted: Tue Mar 17, 2009 10:03 AM
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Debug
Posted: Tue Mar 17, 2009 03:07 PM
To use with outputdebugstring, but without any new function, and automágically include var's name, use the following command definition:


Code (fw): Select all Collapse
#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"
Posts: 392
Joined: Tue Mar 10, 2009 11:54 AM
Re: Debug
Posted: Tue Mar 17, 2009 04:16 PM
I'm working with the Visual Debugger from xHarbour.com:



I don't want to miss it anymore.
Windows 11 Pro 22H2 22621.1848

Microsoft (R) Windows (R) Resource Compiler Version 10.0.10011.16384

Harbour 3.2.0dev (r2008190002)

FWH 23.10 x86
Posts: 1096
Joined: Fri Oct 28, 2005 02:27 AM
Re: Debug
Posted: Wed Mar 18, 2009 01:43 AM
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.12

BCC5.82/BCC7.3

xHarbour/Harbour
Posts: 36
Joined: Thu Mar 30, 2006 11:19 AM
Re: Debug
Posted: Wed Mar 18, 2009 07:53 AM
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 (fw): Select all Collapse
#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 (fw): Select all Collapse
******************************************************************
* 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
Posts: 283
Joined: Sat Oct 15, 2005 06:40 AM
Re: Debug
Posted: Thu Mar 19, 2009 12:32 PM

Dear friends,

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

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

Ciao, best regards,

Ugo
Posts: 283
Joined: Sat Oct 15, 2005 06:40 AM
Re: Debug
Posted: Thu Mar 19, 2009 01:09 PM
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. :-)

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

There is a new version?

Is possible to compile WinDebug?
Ciao, best regards,

Ugo
Posts: 1096
Joined: Fri Oct 28, 2005 02:27 AM
Re: Debug
Posted: Thu Oct 20, 2011 07:22 AM
I did a tiny change to Carlos's pre-processor directive. I changed the line
Code (fw): Select all Collapse
#translate ASSTRING( <x> ) => If( <x> == NIL, 'NIL', Transform( <x> , NIL ) ) + CRLF
to
Code (fw): Select all Collapse
#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.12

BCC5.82/BCC7.3

xHarbour/Harbour