RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Tricks to Improve Your Brew Handset Debugging  : Page 2

There's more to the Brew Logger than DBGPRINTF. Learn how to interpret the various log messages and even do some debugging without the logger on handsets.

Brew Debug Log Messages
The Brew runtime provides a slew of messages to the Brew Logger that can help you debug applications, even if you're looking at a non-debug build of your application. In fact, the Brew Simulator also outputs these messages, so you've probably gotten used to seeing them even if you don't do a lot of on-handset work. Some of these messages are for debugging, while Qualcomm intended others to provide integration with the Brew Grinder. These messages fall into two broad categories:
  • Status messages, which indicate a change in system status, such as when an application starts or stops
  • BPOINT messages, which are triggered when the system hits a debugging breakpoint for an anomaly, such as an attempt to free an invalid pointer
Status messages may or may not signal an error, but you can use them to help trace application flow and determine where to place debugging messages of your own when troubleshooting. BPOINT messages nearly always signal a problem; some handset implementations restart after the system generates the message.

Status messages begin with #*, so you can easily filter them out of the log. Here's a list of the status messages you should know about:

  • #*gBI: This indicates Brew runtime initialization.
  • #*gEX: This indicates Brew runtime termination.
  • #*gST=classid: This indicates that the applet with the class id classid has received EVT_APP_START.
  • #*gSU=classid: This indicates that the applet with the class id classid has received EVT_APP_SUSPEND.
  • #*gRE=classid: This indicates that the applet with the class id classid has received EVT_APP_RESUME.
  • #*gCL=classid: This indicates that the applet with the class id classid has received EVT_APP_CLOSE.
  • #*gXX: This indicates that all applets are being stopped.
  • #*g**=error: This indicates that a Brew exception with error has occurred.
  • #*g*C=classid:error: This indicates that the creation of an instance of classid failed with the error code error.
  • #*p:ECode:event,Key:keycode: This indicates a key event with the indicated key code.
Of these, the two most useful when debugging an application are probably #*g** and #*g*C. I, personally, rely on #*g*C a lot, especially now that the creation of so many interfaces (such as ICamera) require privilege, early in development. This is especially handy if you write only generalized error handling for a set of instance creation operations, so that your application gracefully fails, but doesn't indicate which interface creation operation is at fault.

Author's Note: The definitions for the errors shown in this message are the same as those defined in the AEEError.h include file.

Another use for the status messages is to debug anomalies during application flow; you can log keystrokes during testing by filtering for the #*p:ECode messages, and then using that to write regression test cases. If you're handy with Perl or another scripting language, you can even automate sending the keystrokes to the handset using the Brew Logger scripting interfaces!

In their way, the BPOINT messages are considerably more informative than the status messages you've just seen. They always indicate a bona fide problem in your application, and should never be ignored. In fact, ignoring them in the simulator can lead to crashes on some handsets! There are four BPOINT messages:

  • BPOINT Type 1: These messages indicate a memory leak, and show in the logger on application exit as the Brew runtime frees your application heap.
  • BPOINT Type 2: These messages indicate an interface leak, and show in the logger on application exit as the Brew runtime frees your application heap.
  • BPOINT Type 3: These messages indicate heap corruption, of which I'll say more in a moment.
  • BPOINT Type 4: These messages signal a Brew runtime exception.
Memory leaks are nasty things to debug, but careful inspection of memory around the node location displayed by a BPOINT Type 1 message can often lead you to the culprit. Similarly, a good understanding of how your application allocates and uses Brew interfaces can lead you to quickly tracking down the source of BPOINT Type 2 messages.

BPOINT Type 3 messages typically occur when either the heap is corrupted, or the memory manager believes the heap is corrupted. There's a fine distinction between the two, as a double-FREE of the same pointer will attest to. When debugging a BPOINT Type 3, here are some things to look for:

  • Has the pointer already been freed?

    Tip: Always use FREEIF instead of FREE, which sets your pointer to NULL after freeing, and does not attempt to free NULL pointers.

  • Are you attempting to free static constant data?
  • Are you attempting to free data that wasn't allocated by MALLOC, such as something on the stack?
  • Is something else modifying memory around the node indicated in the message?
To test the last hypothesis, perform the following steps:
  1. Run the application in the Brew Simulator with the Visual Studio Debugger.
  2. Note the address of the node in the BPOINT message.
  3. Place a memory watchpoint at the indicated node address.
  4. Re-run the application, and examine the behavior of the code each time the memory there is being changed.
This can be time consuming, but it's the fastest way to debug heap corruption bugs.

In addition to these messages, some OEM implementations provide additional information to the logger, such as details regarding the application stack during applet launch and termination. Careful examination of these messages when debugging startup issues can often shed light as to why a cable-loaded application may not launch correctly.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date