devxlogo

Tricks to Improve Your Brew Handset Debugging

Tricks to Improve Your Brew Handset Debugging

lthough on-target debugging is supported on many Brew-enabled handsets, you probably (paradoxically) spend most of your time debugging on older handsets that don’t have on-target debugging at all. Of course, good instrumentation in debug builds helps you determine what’s going on in an errant program, but where do you start?

For some time, Brew has had a number of debug messages available, some that print to the log, and others that can be set to print to the display. While documented?there’s usually a session at the Brew Developer Conference every year that discusses these modes?their use still seems apocryphal. This article provides a brief summary as well as a more detailed explanation of both the various Brew debugging messages and the on-handset debug mode.

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.

On-Handset Brew Logging
On the handset, Brew has several debug modes that you can activate to provide additional insight as to what the Brew runtime is doing on your application’s behalf. How you activate this differs from handset to handset, so you should check a specific handset’s data sheet, but by default, try dialing ###273933284# (which you can remember as ###BREWDEBUG#) at the handset’s idle screen. Once this is on, you can dial one of the following codes from the idle screen:

  • Dialing ###1# turns on additional heap debugging on the device, helping you find additional memory errors.
  • Dialing ###2# shows network status on the display during network activity.
  • Dialing ###3# shows the available heap on the device during application execution.
  • Dialing ###4# forces the handset to write each log message synchronously to the Brew Logger, instead of buffering messages.
  • Dialing ###6# dumps an annotated snapshot of the heap to the logger.
  • Dialing ###8# dumps an annotated snapshot of file cache to the logger.
  • Dialing ###10# closes the resource file cache, so that you can delete open resource files.
  • Dialing #### terminates debug mode.

The annotated snapshots (###4# and ###6#) dump information to the Logger, so it’s important to be cabled to your PC. ###1# activates additional heap checking, so it will cause your application to run slower, but help you find memory errors. ###4# can be especially handy when debugging defects that crash your device, because often the handset will crash with log entries remaining in the handset’s log buffer. Without synchronous debugging you can’t see all the messages generated before the handset crashes. Turning on synchronous debugging greatly slows application execution, because the handset writes each log message to the Logger before continuing execution of the next statement.

The network monitoring mode, ###2#, shows socket and PPP status on a region of the display. The handset reports status via a single character, including:

  • ^: The PPP connection is opening.
  • =: The PPP connection is open.
  • v: The PPP connection is closing.
  • #: The PPP connection has closed.
  • ~: The PPP connection is asleep.
  • >: The PPP connection is awakened.
  • c: A socket is connecting.
  • C: A socket has connected.
  • I: A socket is idle.
  • b: A socket request is binding to a socket.
  • B: A socket request has bound to a socket.
  • R: An application is reading from a socket.
  • W: An application is writing to a socket.
  • r: An application is performing a recvfrom on a socket.
  • w: An application is performing a sendto on a socket.
  • x: A socket is closing.
  • X: A socket has closed.

The heap monitoring mode, ###3#, displays a snapshot of the available heap on the upper part of screen, so you can track how much memory is available. It updates periodically, so as your program runs you can get an idea of how much memory your application uses. Note that it reports free memory, not the largest block available. Thus, you might not be able to allocate a block as large as shown by the snapshot, because the heap may be fragmented.

Finally, you can exit this Brew Debug mode by entering ### at the idle screen.

Easier Than You Think
Debugging on the handset?especially without access to source-level debugging on the latest BREW 3.x handsets?has been likened to running hurdles in the dark while blindfolded. In truth, it’s not that bad, especially when you can interpret the various Brew debug messages and enable Brew Debug mode on the handset.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist