Redirecting stdio to the Android Debug Log from a static/shared library

This is quite a technical post, but this issue seemed to take up most of an afternoon, so perhaps my notes will be useful to someone else…
I have a static library (in this case an audio codec) that is being integrated into an Android OMX/Stagefright audio decoder. There are some issues and it is crashing on certain input streams. This library has some debug (write to stderr) functionality already, but I can’t see it on the Android host as its going to stdio. So… how to get this into the Android debug log?
The OMX wrapper is built with the Android AOSP toolchain, but the library isn’t Android specific, and due to the use of assembler in its source and the differences between ARM assembler and GNU assembler, the library needs to be built with RVCT (RVDS/DS-5) and not the Android NDK.
Although Android is using bionic rather than libc I have managed to get away with using the ARM arm_linux stdc headers without problem., i.e:
 LDINCLUDE = /usr/local/DS-5/include/
The output static library from RVDS is placed somewhere in the AOSP/NDK build tree and the library is linked against during build with a few additions to the modules Android.mk:

LOCAL_PATH:= $(call my-dir)


include $(CLEAR_VARS)

# Tell the build system about the existing (pre-built) library.

# Note: The library name appears here and in the LOCAL_WHOLE_STATIC_LIBRARIES below.

# Also, the path is relative to the path of this makefile

LOCAL_PREBUILT_LIBS += prebuilt/my_lib.a



include $(CLEAR_VARS)

LOCAL_SRC_FILES := myDecoder.cpp


        frameworks/av/media/libstagefright/include \

        frameworks/av/include/media/stagefright \

        frameworks/native/include/media/openmax \

        $(LOCAL_PATH)/src \

        $(LOCAL_PATH)/include \



LOCAL_SHARED_LIBRARIES := libstagefright libstagefright_omx libstagefright_foundation libutils libcutils

LOCAL_MODULE := libstagefright_soft_mydec


I have only experienced one problem with doing this, which is that if building with the RVCT linux headers, calling printf(stderr, “msg”) produces a linkage error against aeabi_stderr when attemping to link the static library into the Android library:
/media/Android_Build/build/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld: out/target/product/toro/obj/STATIC_LIBRARIES/dec_lib_intermediates/my_lib.a(fmi_api.o): in function ddpi_fmi_checkframe:sub_dec/fmi_api.c(.text+0x1e8): error: undefined reference to '__aeabi_stderr'
This isn’t unexpected, as I’m building with the RVCT libc rather than bionic. To work around this, link against the NDK/AOSP c headers. In my case they’re at:
I still had one error at this point, as RVCT was looking for linux_rvct.h. Including this in the path solved the last build error, and the library now links during the AOSP build.
Lets look at the library contents with nm. The library with the problem:

00000000 t $a

000001dc t $a

00000178 t $d

         U __aeabi_stderr

00000000 T xdd_init

000001dc T xdd_seek

0000001c T xdd_unp

         U bso_init

         U bso_rewind

         U fprintf
And now:

00000000 t $a

000001d8 t $a

00000174 t $d

00000000 a          U __sF

00000000 T xdd_init

000001d8 T xdd_seek

0000001c T xdd_unp

         U bso_init

         U bso_rewind

         U fprintf

__aeabi_stderr is now __sF
Bionic defines sF:
#define stderr (&__sF[2])
All looking good!
The last job is to get dalvik to pipe stderr to the system log. This is covered at: http://developer.android.com/tools/debugging/debugging-log.html
In this case, /data/local.prop did not exist and I had to add the property to build.prop via adb:
cat "log.redirect-stdio=true" >> /system/build.prop
This persists after a reboot, so should have been picked up by dalvik when it started.
Outside the scope of this document, the decoder shared library was then pushed into the phone’s filesystem. However there still wasn’t anything in the log.
Searching around, it looks as though the stderr() output isn’t being piped into the log as redirect-stdio only refers to the dalvik VM. What is needed is to include the Android Native logging API and use the ___android_log_write() method.
Rebuild the library and here we go…. log data appears in the adb log:
01-02 01:25:30.734: E/mydec_subdec(129): FATAL ERROR:  auxdatal > frmsz

01-02 01:25:30.734: E/mydec_subdec(129): Error occurred in:

01-02 01:25:30.734: E/mydec_subdec(129): my_dec/xdd.c (line 88)

In this case a macro was being used:
#define         ERR_PRINTERRMSG(a)               __android_log_print(ANDROID_LOG_ERROR,"ddp_subdec","\n\nFATAL ERROR:  %s\n\nError occurred in:\n%s (line %d)\n\n", (a),__FILE__,__LINE__)
In this specific case of this library some aux data is out of bounds and the assert on this was crashing. In case you were interested.
01-02 01:55:08.328: V/subdec_axdd(2841): auxdatal=4868

01-02 01:55:08.804: V/subdec_axdd(2841): auxdatal=6870

01-02 01:55:10.023: V/subdec_axdd(2841): auxdatal=6951

01-02 01:55:10.453: V/subdec_axdd(2841): auxdatal=8404

01-02 01:55:12.398: V/subdec_axdd(2841): auxdatal=2260

01-02 01:55:13.453: V/subdec_axdd(2841): auxdatal=3476

01-02 01:55:13.757: V/subdec_axdd(2841): auxdatal=6356

01-02 01:55:14.171: V/subdec_axdd(2841): auxdatal=11460

01-02 01:55:15.757: V/subdec_axdd(2841): auxdatal=6916

01-02 01:55:16.320: V/subdec_axdd(2841): auxdatal=9332

01-02 01:55:16.398: V/subdec_axdd(2841): auxdatal=10950

01-02 01:55:16.421: V/subdec_axdd(2841): auxdatal=8532

01-02 01:55:16.632: V/subdec_axdd(2841): auxdatal=11476

01-02 01:55:16.781: V/subdec_axdd(2841): auxdatal=13015

01-02 01:55:17.500: V/subdec_axdd(2841): auxdatal=6870

01-02 01:55:17.929: V/subdec_axdd(2841): auxdatal=3940
The only real downside to this method is that the source of the static library is needed. If that is true, then this is a useful tool for debugging the library on an Android host. If we don’t have the source, then this won’t work and a more generic way of intercepting stdio output would be required in the operating system itself.

NSW Topo Maps on your iOS/Android device

In this post I looked at accessing raster topographic data through LPI’s ArcGIS server, and constructing an offline atlas that could be used on a mobile device. The next logical step was to see if any of the mapping applications for Android/iOS were capable of viewing live data from the server. I looked at a couple of applications that advertise support for the necessary feature, specifically compatibility with the  TMS API, which the ArcGis MapServer handles correctly, one must assume at least semi-intentionally.

First up, the ArcGIS application itself on iOS – free. This works just fine, and the map is accessed by importing the required map of the LPI server into ArcGIS online. This can be done by passing the URL of the map in question to ArcGIS.com, then ‘saving’ the map to an ArcGIS online account. After logging into the same account in the ArcGIS app, the saved map can be accessed and viewed. Presumably the ArcGIS REST API is being used behind the scenes. The issue that rules out use of this app for remote area use was the lack of offline caching. To be fair, that’s not what this app is intended to be used for.

Second up, also in iOS, Galileo. This app supports more-or-less the same schema XML as MOBAC. I imported the customMapSource I used in MOBAC without any problem, and caching works as expected. I haven’t tested it for navigation beyond basic GPS positioning.

The next app I looked at was AlpineQuest, on Android. This also supports TMS custom online maps, but uses its own XML schema. Generating this was fairly painless. I’ve created a suitable map source that includes the old/new NSW topo maps and the ‘web’ topographic map. You can download it here. Caching works just fine. I personally found this the most usable of all the mobile apps, but YMMV.

I discussed this with a friend whilst out canyoning at the weekend and decided to paste in the same map area from various map sources. Several people have described the trails marked on local topo maps as being accurate in the same way that CityRail timetables aren’t. The ‘official’ NSW maps, Google, and Openstreetmap sources are shown here. Make your own mind up….

The last two images are the result of an experiment to add hill-shading to the NSW topo maps. AlpineQuest allows for multiple layers with transparency. I couldn’t get the OSM hillshade layers to render, but the Google Terrain overlay adds some depth to the image, though the artefacts from extra data in the terrain layer were, I thought, off-putting.

LPI Topo Map
NSW Topo Series 2
Hike Bike Map (OSM?) 
Google Maps
NSW Topo Series 1
Cycle/Hike Map
Google Terrain
NSW Topo + Google Terrain
NSW Topo + (30%) Google Terrain

New South Wales Topographic Maps

I’ve been trying to track down a digital source of NSW topographic maps for some time now. The paper editions, as well as often being of the 1st (1960’s production) edition, if available at all, are printed on woefully thin paper that’s lucky to survive a single outing to the bush.

I’d like to print my own. Even better, I’d like to have them as raster overlays on my GPS.  I have the Garmin vector maps, which I understand are generated from the same GIS database, but a reference raster chart from the local mapping agency themselves gives me a degree more confidence in the accuracy of the data published.

The GPS cannot download maps in real-time off an online server, and neither would there likely be any  mobile coverage in the area it was being used in anyway (so the iPhone is out too for that use-case), so I also need to be able to locally cache whatever data is available.

After a lot of trawling, it appears that the LPI do indeed (and only recently… this only seems to have popped up in the last few days) publish a cached tile service from their ArcGIS server. This can be accessed as a cached tile service compatible with MOBAC (Mobile Atlas Creator), a WMS service, or as a KML SuperOverlay service that can be displayed as an overlay in, say, google earth.

The largest scale tiles look to be rendered (according to the layer metadata) at 1:9027 at 96dpi, which by my maths comes out at about 1:28000 if printed at 300dpi. This should be plenty good enough for printing or overlay use.

I do not know whether this service is intended to be used in this way, or whether this service will still be up tomorrow.

The tiles are acquired from the same server as the server used by a ruby script that acquires vector map data from another service. As much as this is cleverly done, I found most of the tiles I attempted to acquire were supplied as cached rasters, and that getting the correct visual styling was therefore not possible. The raster tile source it uses gets scaled on the server and so the rendering quality there left something to be desired. This method appears successful for raster tiles due to its simplicity.

MOBAC Custom Map XML source:


Zoom levels 0-15 appear poorly scaled. They are not rendered for the larger scale. I recommend just working with layer 16 for navigation.

KML/KMZ for Google Earth: link

It looks like the series 1 maps are also published. I haven’t checked these to see if they have been adjusted from AGD66 to WGS84/GDA94 datum. The tiles are published using the EPSG:4326 projection, so I would expect that they have.

Google Earth Overlay
MOBAC Preview


NSW National Park Boundaries

I came across the 2009 dataset for the NPWS boundaries in KML format (good for importing into Google Earth). I’ve seen a link to this on a geocaching site but it was broken so I’ve re-uploaded it here. Hopefully a search brought you this way and this is what you were after.



Rainbow Serpent Festival Lineup Calendars

Rainbow Serpent Festival have kindly produced a PDF of the lineup for the main stages…. for the nerdy amongst us I have converted this into separate iCal calendars that you can add to your iPhone/Android/whatever mobile ‘thing’.

If previous years are anything to go by, the Market stage will be running late, and there will probably be last minute changes that you won’t know about until its too late. But isn’t seeing someone you don’t know half the fun? Gotta love the randomness! I’ve also likely made mistakes in transcription, so don’t say I didn’t warn you! I will try and correct any errors if I find them.

Click the links for the iCal files (Apple Calendar etc.) or ‘+’ button below to add it to your google calendar.

Chill Stage Calendar
Main Stage Calendar
Market Stage Calendar
Playground Stage Calendar
Sunset Stage Calendar

All together… a bit of a mess. Google Calendar has bad formatting…

Separately they look a little more readable…