How to turn UltimateDebug messages on and off

I have a lot of ud.Debug messages in my application. I would like them to display in DebugView++ when the app is compiled in Debug mode, but to remain silent when the app is compiled in Release mode.

So far the best I can manage is to set a global variable glo:dbugoff in the dictionary, and use it as the “Turn Debug Off Variable”.

But it still requires me to remember to change the default value in the dictionary when I change from Debug mode to Release mode.

There must be a better way. Ideally, I would like to have some startup code that detects whether the app has been compiled in Release mode, and then set the global variable accordingly.

Any suggestions?

Good morning Donn,

Just an idea, but couldn’t you set the variable to True / False depending on command line parameters?

Eg, set it to false by default, but set it to true if /DEBUG is present in the command line parameters.

Just an idea?

Thanks,

Andy
www.noyantis.com

%ApplicationDebug

Glo:DebugVar = %ApplicationDebug

Isn’t %ApplicationDebug a template symbol and not a runtime variable?

The template would have to be changed to accommodate settings a runtime variable to the content of %ApplicationDebug - which Donn could do of course, but then would have to remember to re-apply after each template update.

Personally, I use the setting via the command line, that way I can still leave the debug statements compiled in both debug and release modes, but only use it when needed if the command line parameter has been passed.

Personal choice I suppose :slight_smile:

Thanks,

Andy
www.noyantis.com

It is a template symbol.

So Donn changes from Debug to Release mode and the template symbol would change.
So the template could have some warning built in to highlight the mismatch between the global var and the template symbol using something like #Message or #RunDLL which calls your own popup message box when the code is generated.

There are a few ways this could be done in the templates because even though the app might be compiled as release, there might still be a need for a particular template to output debug code.

Which command line, the C11 IDE command line or the app command line?
If the C11 IDE command line, then %ApplicationDebug template should be set by the C11 IDE command line.

That’s what I meant by my personal choice - just setting the variable at runtime via some kind of user mechanism (eg existence of /DEBUG on command line parameters to the application).

We distribute our apps in Release mode, but still like to have the ability to turn on Ultimate Debug statements when required / on demand.

You could modify the template as you’ve said, but then you would have to re-apply the same changes after each release / update of Ultimate Debug.

Cheers,

Andy
www.noyantis.com

Yeah, but Donn mentioned some code to detect whether the app has been compiled in Release mode and then set the global var accordingly. Ergo Glo:DebugVar = %ApplicationDebug would do that.

I understand that you compile your apps in Release mode and use a Command() line switch/flag to set the global var, but I got the impression Donn wanted to make changes to the template to detect if the app was being compiled in debug or release mode, and then if being compiled in debug mode, to automatically switch on the debug output. But maybe I’m wrong, Donn would have to clarify on that point? :grinning:

1 Like

@RichClaCode I would prefer to leave the UltimateDebug template (and code) unmodified.

I have done a bit more experimenting and discovered that I only get once chance to set the global variable, and that is before the “DebugABCGlobalInformation” procedure is called. Once the messages start being displayed, changing the glo:dbugoff value has no impact.

In the OpenWindow event of the Main procedure I tried the following

    OF EVENT:OpenWindow
  ! Start of "Window Event Handling"
  ! [Priority 4499]
    if COMMAND('/DEBUG') then ! Debug mode
        ud.Debug(' glo:dbugoff = FALSE')
        glo:dbugoff = FALSE
    else ! Debug Mode
        ud.Debug(' glo:dbugoff = TRUE')
        glo:dbugoff = TRUE
    end ! Debug Mode  
    ud.Debug(' COMMAND: ' & COMMAND(''))

In all cases the messages keep being displayed.

I would like the flexibility of compiling in Release mode but with the option of being able to run the app (at the client’s location) with a “/DEBUG” flag to enable debug messages.

The Clarion help file mentions that you can use the “?” symbol in column 1 to indicate a line that should only be run in debug mode. But the Embeditor just moves the “?” to another column :roll_eyes:

Either way, I think the OpenWindow event is too late, and I’m not sure where to put the code so it is early enough to make a difference.

@noyantis where do you put your code to decide whether to display debug messages or not?

Assuming ABC here, in the global embeds, the Program Setup embed is where I would process the Command() flags. That embed is right after the DctInit line of code and before the MAIN procedure call, assuming MAIN is the name of the first procedure called which is typically an Appframe window.

Command() would be best for that, but you might want to obfuscate or encrypt your debug output so users cant get insights into your app to avoid giving away any secrets about how your program works.

If you look at the source code for a typical appgen window, immediately after CODE you should see
? Debughook(FilePrefix:Record) This helps the debugger load the file into the debugger.

I havent tried using ? for anything else, but maybe you could try something like
? Message(‘Popup Message for Debug Mode’)
making sure the embed source is set to column 1, but I think this will only happen when you load the app up using the debugger.

Perfect. I modified the code slightly:

!// Decide whether to display debug messages
if COMMAND('/DEBUG') then ! Debug mode
    glo:dbugoff = FALSE
else ! Debug Mode
    glo:dbugoff = choose(_DEBUG_ = 1, false, true)
end ! Debug Mode  

It works like a charm. I just added a “/DEBUG” command line argument in the project options.

I will bear in mind the problem of giving away program secrets, but at this stage I’m happy with the results as they are. Thanks to @SimonKemp for the assistance too.

1 Like

There’s a compiler flag "_DEBUG_" for app debug mode. So something like this perhaps:

Glo:DbugOff = choose(_DEBUG_ = 1, false, true)

debug should have underscores around it…

_ D E B U G _ (no spaces)

1 Like

See help on “Predefined Compiler Flags” which are usually used with OMIT() or COMPILE() like:

OMIT('!** Not Debug **',_Debug_)
   Glo:DbugOff = TRUE         !Not compiled Debug so skip the Output of Debug
!** Not Debug **

OutputDebugString() calls can take some time as it must access 1 or 2 kernel objects. So heavy calling can slow your program down.

You can detect if there is a Debug Viewer running, if not set your Glo:DbugOff = TRUE

http://www.unixwiz.net/techtips/outputdebugstring.html

3 Likes

I’m probably missing something here.

But isn’t the easiest way to include/exclude code depending on whether an app is compiled in DEBUG mode just to put a question mark in column 1 of the line(s) concerned?
? GLO:debugOff = false

From the help:

Question mark begins a field equate label, label, or when used as a single character in column one of source code, designates that the statement that follows only be executed in DEBUG mode.

Obviously, code compiled in this manner could be combined with a command-line switch to override what’s compiled.

BTW, I just did a quick test of a loop with 100,000 records.

After queue has been built, loop pointer = 1 to 100000, get record, concatenate 3 fields = 33 clock ticks.
Do the same, send to debug output, debugView++ NOT running = 224 clock ticks.
Do the same, debugView++ IS running = 994 clock ticks.

jf

1 Like

Yeah, that jibes with what I’ve read/seen about having a listener enabled.

I should have probably mentioned that alternative syntax, but in an APP using Embed points executable code is usually Not started in the required Column 1 … unless you check a box. So its a subtle thing I tend to not do in APPs. Also he wanted code that ran in Release builds to set = False so the “?” is opposite.

In hand code the " ? Debug " is nice and quick, you’ll see it in ABC classes a lot.

Thanks for the test confirming!

FWIW, I release my program in debug mode.
I leave my debugging in place, but control what is shown via INIs
and also by detecting at runtime if there is a listener present ( as mentioned in the other topic that Carl linked to above)

FWIW, most of my OutputDebugString (ODS) calls are written as ASSERTS, because classes can be written to make ODS calls without having to inject a Debuger class and more importantly then I can prepend the filename (module) and line number of the assert to the message. This is accomplished using AssertHook2 with a special equate of ‘<4,2,7>’ CTRL+D, CTRL+B, CTRL+G (DBG) to indicate that this assert is intended to be an ODS .

Note: if you wish to use ASSERT in a program in release mode, then you need pragma asserts=>on

1 Like

Is this reliable though, using the tick count increase?

Put another way, if I messed around with the cpu scheduling (needs a reboot admittedly) and thread priority (doesnt need rebooting, can be done on the fly), would you see it then?

It seems to be reliable
I’ve never noticed that it failed.

Look at the technique
I don’t believe is ods viewer present detection is reliant at all on performance.

We might have to watch this feature Windows Update is now carbon aware - Microsoft Support to see if it slows down thread priority or cpu time.

I’ve already noticed some windows boot msgs appear out of order in Win10 to make the machine boot more quickly, like forcing hibernation on more people for that “instant on” experience, but the boot sequence and back ground task loading is different now a days to earlier versions of windows and we can now see the green leaf next to suspended processes in the task manager.
Carbon tax on its way? :shushing_face:

1 Like

Great point Jane!

Your tests show the slow down is like 4x higher when a Debug Viewer is running. So most end users will not see the maximum slow down.

That makes sense to me because opening one Event tells if a viewer is monitoring. If it is running there is much more work to get the message to the viewer (open mutex, mmf,event,etc).

I would be curious if the new ++ is slower than the original Debug View? If you don’t have both please post your code and I’ll test both.