Announcement

Collapse
No announcement yet.

#error debug on. what does it do?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #error debug on. what does it do?

    Hello ALL!


    Here is what the help says...

    Code:
    Syntax	#DEBUG ERROR [ON|+ | OFF|-]
    
    The ERROR option specifies whether the compiler should generate
    code that checks for certain types of errors wherever they may 
    occur (with the exception of disk I/O, where errors are always 
    caught). It is best to enable error-checking when developing a 
    program; the default setting is OFF. Once all of the more 
    obvious bugs have been eradicated, you will want to turn 
    error-checking off, as this will make your code smaller and 
    faster. The final (production) version of a program should not
    contain any error-checking code. #DEBUG ERROR is always enabled 
    during compilation for debugging.

    Here is a little template program that I wrote. It seems as though
    the size of this file after it has been compiled is the same even
    if
    Code:
    #debug error on
    is set. Can anybody explain why?


    Code:
    rem Template.bas
    rem
    
    #compile exe
    #register none
    #option version5
    #debug error off
    #dim all
    
    rem windows headers
    #include "windows.inc"
    
    
    %MAXCLASSSTRING         = 64
    
    
    function WinMain(byval hInstance as long,_
                     byval hPrevInstance as long,_
                     szCmdLine as asciiz ptr,_
                     byval nCmdShow as long) as long
    
        dim szWindowClass as asciiz * %MAXCLASSSTRING
        dim wcex as WNDCLASSEX
        dim msg as TAGMSG
        dim hWnd as long
    
    
        rem setup window class
        szWindowClass       = "TemplateWindow"
    
        wcex.cbSize         = sizeof(wcex)
        wcex.style          = %CS_DBLCLKS or %CS_HREDRAW or %CS_VREDRAW
        wcex.lpfnWndProc    = codeptr(MainProc)
        wcex.cbClsExtra     = 0
        wcex.cbWndExtra     = 0
        wcex.hInstance      = hInstance
        wcex.hIcon          = LoadIcon(%NULL,byval %IDI_APPLICATION)
        wcex.hIconSm        = LoadIcon(%NULL,byval %IDI_APPLICATION)
        wcex.hCursor        = LoadCursor(%NULL,byval %IDC_ARROW)
        wcex.hbrBackground  = GetSysColorBrush(%COLOR_3DFACE)
        wcex.lpszClassName  = varptr(szWindowClass)
        wcex.lpszMenuName   = %NULL
    
    
        rem register window class
        RegisterClassEx wcex
    
        hWnd = CreateWindow(szWindowClass,_
                            szWindowClass,_
                            %WS_OVERLAPPEDWINDOW,_
                            %CW_USEDEFAULT,_
                            %CW_USEDEFAULT,_
                            %CW_USEDEFAULT,_
                            %CW_USEDEFAULT,_
                            %HWND_DESKTOP,_
                            %NULL,_
                            hInstance,_
                            byval %NULL)
    
        ShowWindow hWnd,nCmdShow
        UpdateWindow hWnd
    
    
        while GetMessage(msg,%NULL,%NULL,%NULL)
            TranslateMessage msg
            DispatchMessage msg
            wend
    
    
        function = msg.wParam
    end function
    
    
    function MainProc(byval hWnd as long,_
                      byval message as long,_
                      byval wParam as long,_
                      byval lParam as long) export as long
    
        select case (message)
            case %WM_DESTROY
                PostQuitMessage errclear
    
        end select
    
    
        function = DefWindowProc(hWnd,message,wParam,lParam)
    end function

    ------------------
    Cheers

  • #2
    #DEBUG works as the help file says, but your example gives identical results because of at least two factors:

    1. The disk image size of a compiled file grows in "chunks" due to alignment within the file structure itself. Unless the code grows enough for an alignment boundary to be crossed, small changes in the code will not always be noticable in terms of the compiled file size. If you look at the compilation statistics, you may see smaller changes in "memory image" size, etc.

    2. The code in your example does not contain any PowerBASIC statements or Functions that will benefit from error testing code imposed by #DEBUG ERROR ON - your example consists almost completely of API calls.

    I hope this explains the situation a little more clearly...


    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      I recently added '#error debug on' to my code and it has
      prevented a GPF i was getting. 'Excellent', i am thinking, my program is fixed!
      But it isn't fixed is it!?

      What exacty is going on with this line and why has my code started to work?
      Albeit i dont have the expected results, but i no longer have a GPF!

      Would be grateful if you could shed some light on this (Lance).

      Ta

      Danny

      ------------------

      Comment


      • #4
        Danny --

        If adding #DEBUG ERROR ON keeps your program from GPFing, it's a good bet that you've got an array subscript out of range somewhere. One of the things that #DEBUG ERROR ON does is subscript checking. If your program attempts to use an invalid element of an array, it is stopped from doing so. So yes, your program is almost certainly "still broken" because something is not functioning the way you intended.

        -- Eric


        ------------------
        Perfect Sync Development Tools
        Perfect Sync Web Site
        Contact Us: mailto:[email protected][email protected]</A>

        [This message has been edited by Eric Pearson (edited May 04, 2001).]
        "Not my circus, not my monkeys."

        Comment


        • #5
          Syntax #DEBUG ERROR [ON|+ | OFF|-]The ERROR option specifies whether the compiler should generatecode that checks for certain types of errors wherever they may occur (with the exception of disk I/O, where errors are always caught). It is best to enable error-checking when developing a program
          I think perhaps the question might have been better-phrased as, "WHICH errors are the types of errors #DEBUG ERROR ON will trap?"

          "Certain" is a weasel-word.

          This looks like a job for the doc writers. And while they are at it, they might explain the differences and/or interactions between #DEBUG ERROR ONand #ON ERROR GOTO

          MCM
          Michael Mattias
          Tal Systems Inc. (retired)
          Racine WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            I tried the following:
            Code:
            #DEBUG ERROR OFF
               
            FUNCTION PBMAIN AS LONG
               
              DIM a( 1:100 ) AS LONG
              
              PRINT a( 200 )
              PRINT ERR
              WAITSTAT
                
            END FUNCTION
            This case, ERR returns a 0. If I enable #DEBUG ERROR ON, the program runs to the end, and I get an ERR = 9.

            This means to trap an error you must always test the ERR value, or setup an ON ERROR GOTO... statement. Well, I don't like neither of the two. To test the ERR value after each statement slows the program; to setup the ON ERROR GOTO... is a bit complicated, since I have to do it inside each function. May be is a not good programming, but I tend to simply use the ERR value after the critical statements. (Who of you guys test for EACH possible error? ).

            Well, errors like "Subscript / Pointer out of range" are not detected with #DEBUG ERROR OFF. They are with #DEBUG ERROR ON, but they are not automatically trapped. It could be a good idea to have a new statement: #DEBUG ERROR HALT, to make the compiled code stops the program execution and show a message. This could be of great help on debugging. Consider this is a wish-list item...

            ------------------
            Rgds, Aldo

            Comment


            • #7
              That is already implemented in the compiler: ON ERROR GOTO errorhandler

              In the error handler, you can pop-up your own message box, etc, and this way you can maintain the GUI look/feel for the entire application. If you are using a something like WinLift, this may be important to you.

              To be clear, the #DEBUG ERROR ON option specifies that the compiler should generate code that checks for array boundary and null-pointer errors.

              As described in the documentation, error trapping is largely the responsibility of the programmer - this is true for most Windows compilers. I get to see a lot of code that little or no error trapping code... I think of it as "running the gauntlet". Error testing and data validation often forms a significant part of a program, and this should not be skimped upon.

              For example, how many people check the ERR value after a DIM or REDIM of an array? While it is uncommon for such a statement to fail at run-time, low-memory conditions can definitely trigger it.

              If the DIM/REDIM statement is not error tested, and you arbitarily plow into reading/writing the array, you stand a very good chance of triggering a GPF. Using #DEBUG ERROR ON can prevent the GPF and no-one will notice until the [wrong] results are generated by your program.

              YMMV, but you get the idea...

              ------------------
              Lance
              PowerBASIC Support
              mailto:[email protected][email protected]</A>
              Lance
              mailto:[email protected]

              Comment


              • #8
                Thanks for the tip Eric. It was a case of REDIM'ing a variable.

                Interestingly, i had traced the offending lines of code to another function
                in my program and was busy messing around with a variable in that function
                with no luck. As a last resort i REDIM'ed a variable higher up in my code and
                this cured the bug! This memory management 'thing' goes right
                over my head!!

                Cheers N E Way.

                Danny



                ------------------

                Comment


                • #9
                  Lance,

                  I agree with you with respect to the errors bolonging to some execution exception. What I would have is a help in debugging the CODE. Once I've tested for a correct execution of a DIM or REDIM (these instructions are almost rare, and I check them with a simple ERR test), I don't expect any more bounds error - If they are, it is not because a run-time exception; it is because my code is wrong. Once corrected it, this kind of errors will disappear at all.

                  Let us have a function with 100 references to an array. Which one generated the error? Two ways to know it:
                  1- To test ERR after each statement.
                  2- To use an ON ERROR GOTO statement, and setting a variable with an unique value before each statement. Once I trap the error, I show a message which contains that variable. Otherwise I will ignore which statemente generated the error.
                  ?- Any other system I don't know...

                  All this work could be avoided is the compiler generated the error message itself. Some time ago I had an answer like "a programmer must know what he is writing...". Well nobody (at least, me) is perfect.

                  ------------------
                  Rgds, Aldo

                  Comment


                  • #10
                    Well, there are many ways to skin the proverbial cat, as there are many ways to go about debugging your code.

                    For example, run it in the debugger and scatter #DEBUG PRINT statements through the code. Use the Animate mode to let the code run and you can stop it when you see the wrong result in the debug output window.
                    Code:
                    ON ERROR GOTO errhndlr
                    #DEBUG PRINT "about to redim"
                    DIM A$(1:100)
                    #DEBUG PRINT "about to assign an element"
                    A$(100) = "data"
                    #DEBUG PRINT "something else is about to happen"
                    etc...
                    Alternatively, write the this info to a log file.

                    Or, you could use an error trap and maintain a variable through the code (at important points). This variable can be used to indicate the position in the code when the failure occurred. Effectively this is like keeping track of your own line counter.
                    Code:
                    ON ERROR GOTO errhndlr
                    Here& = 1
                    DIM A$(1:100)
                    Here& = 2
                    A$(100) = "data"
                    Here& = 3
                    etc...
                    That said, there are a few items on the wish list in regard to improving debugging... we'll have to wait and see what R&D will come up with to help with these kind of laborious problems.

                    ------------------
                    Lance
                    PowerBASIC Support
                    mailto:[email protected][email protected]</A>
                    Lance
                    mailto:[email protected]

                    Comment


                    • #11
                      Here's a sample how you can check your arrays conditionally. You can easily turn it on or off.

                      You'll have to make your own functions for other types of arrays. I just made this to show an acceptable way of testing array bounds during development.

                      Maybe this belongs in the Source code forum?

                      Peter.


                      Code:
                      '------------------------------------------------------------------------------
                      
                      #REGISTER NONE
                      #COMPILE EXE
                      #DIM ALL
                      
                      %CheckArrays = 1
                      
                      '------------------------------------------------------------------------------
                      'Check Array bounds
                      'Forces index to a valid value.
                      #IF %CheckArrays
                      FUNCTION CheckLArray(ar() AS LONG, subscript AS LONG, index AS LONG, descr AS STRING) AS LONG
                        LOCAL i AS LONG
                      
                        i = index
                        IF index >= LBOUND(ar(subscript)) THEN
                          IF index <= UBOUND(ar(subscript)) THEN
                            FUNCTION = -1
                            EXIT FUNCTION
                          ELSE
                            index = UBOUND(ar(subscript))
                          END IF
                        ELSE
                          index = LBOUND(ar(subscript))
                        END IF
                        msgbox "Array " + descr + " out of bounds: " + STR$(LBOUND(ar(subscript))) + STR$(i) + STR$(UBOUND(ar(subscript))) + $CRLF _
                               + "Index was forced from" + STR$(i) + " to" + STR$(index)
                      END FUNCTION
                      #ENDIF
                      
                      FUNCTION PBMAIN() AS LONG
                      LOCAL lar() AS LONG
                      LOCAL i AS LONG
                      
                      DIM lar(100)
                      
                      i = 50
                      
                      #IF %CheckArrays
                        CheckLArray lar(), 1, i, "PBMAIN:lar1"
                      #ENDIF
                      lar(i) = 1
                      
                      i = 150
                      
                      #IF %CheckArrays
                        CheckLArray lar(), 1, i, "PBMAIN:lar2"
                      #ENDIF
                      lar(i) = 1
                      
                      END FUNCTION

                      ------------------
                      [email protected]
                      [email protected]

                      Comment

                      Working...
                      X