Chapter 6. Debugging techniques

Table of Contents
Tracing
Kernel instrumentation

eCos applications and components can be debugged in traditional ways, with printing statements and debugger single-stepping, but there are situations in which these techniques cannot be used. One example of this is when a program is getting data at a high rate from a real-time source, and cannot be slowed down or interrupted.

eCos’s infrastructure module provides a tracing formalism, allowing the kernel’s tracing macros to be configured in many useful ways. eCos’s kernel provides instrumentation buffers which also collect specific (configurable) data about the system’s history and performance.

Tracing

To use eCos’s tracing facilities you must first configure your system to use tracing. You should enable the Asserts and Tracing component (CYGPKG_INFRA_DEBUG) and the Use tracing component within it (CYGDBG_USE_TRACING). These options can be enabled with the Configuration Tool or by editing the file BUILD_DIR/pkgconf/infra.h manually.

You should then examine all the tracing-related options in the Package: Infrastructure chapter of the eCos Reference Manual. One useful set of configuration options are: CYGDBG_INFRA_DEBUG_FUNCTION_REPORTS and CYGDBG_INFRA_DEBUG_TRACE_MESSAGE, which are both enabled by default when tracing is enabled.

Example 6-1 shows the output from running the hello world program (from the programming tutorial in Getting Started with eCos) that was built with tracing enabled:

Example 6-1. Hello world with tracing

$ mips-tx39-elf-run --board=jmr3904 hello
Hello, eCos world!
ASSERT FAIL: <2>cyg_trac.h          [ 623] Cyg_TraceFunction_Report_::set_exitvoid()                                                            exitvoid used in typed function
TRACE: <1>mlqueue.cxx         [ 395] Cyg_ThreadQueue_Implementation::enqueue()                                                            {{enter
TRACE: <1>mlqueue.cxx         [ 395] Cyg_ThreadQueue_Implementation::enqueue()                                                            }}RETURNING UNSET!
TRACE: <1>mlqueue.cxx         [ 126] Cyg_Scheduler_Implementation::add_thread()                                                           }}RETURNING UNSET!
TRACE: <1>thread.cxx          [ 654] Cyg_Thread::resume()                                                                                 }}return void
TRACE: <1>cstartup.cxx        [ 160] cyg_iso_c_start()                                                                                    }}return void
TRACE: <1>startup.cxx         [ 142] cyg_package_start()                                                                                  }}return void
TRACE: <1>startup.cxx         [ 150] cyg_user_start()                                                                                     {{enter
TRACE: <1>startup.cxx         [ 150] cyg_user_start()                                                                                     (((void)))
TRACE: <1>startup.cxx         [ 153] cyg_user_start()                                                                                     "This is the system default cyg_user_start()"
TRACE: <1>startup.cxx         [ 157] cyg_user_start()                                                                                     }}return void
TRACE: <1>sched.cxx           [ 212] Cyg_Scheduler::start()                                                                               {{enter
TRACE: <1>mlqueue.cxx         [ 102] Cyg_Scheduler_Implementation::schedule()                                                             {{enter
TRACE: <1>mlqueue.cxx         [ 437] Cyg_ThreadQueue_Implementation::highpri()                                                            {{enter
TRACE: <1>mlqueue.cxx         [ 437] Cyg_ThreadQueue_Implementation::highpri()                                                            }}RETURNING UNSET!
TRACE: <1>mlqueue.cxx         [ 102] Cyg_Scheduler_Implementation::schedule()                                                             }}RETURNING UNSET!
TRACE: <2>intr.cxx            [ 450] Cyg_Interrupt::enable_interrupts()                                                                   {{enter
TRACE: <2>intr.cxx            [ 450] Cyg_Interrupt::enable_interrupts()                                                                   }}RETURNING UNSET!
TRACE: <2>thread.cxx          [  69] Cyg_HardwareThread::thread_entry()                                                                   {{enter
TRACE: <2>cstartup.cxx        [ 127] invoke_main()                                                                                        {{enter
TRACE: <2>cstartup.cxx        [ 127] invoke_main()                                                                                        ((argument is ignored))
TRACE: <2>dummyxxmain.cxx     [  60] __main()                                                                                             {{enter
TRACE: <2>dummyxxmain.cxx     [  60] __main()                                                                                             (((void)))
TRACE: <2>dummyxxmain.cxx     [  63] __main()                                                                                             "This is the system default __main()"
TRACE: <2>dummyxxmain.cxx     [  67] __main()                                                                                             }}return void
TRACE: <2>memcpy.c            [ 112] _memcpy()                                                                                            {{enter
TRACE: <2>memcpy.c            [ 112] _memcpy()                                                                                            ((dst=80002804, src=BFC14E58, n=19))
TRACE: <2>memcpy.c            [ 164] _memcpy()                                                                                            }}returning 80002804
TRACE: <2>cstartup.cxx        [ 137] invoke_main()                                                                                        "main() has returned with code 0. Calling exit()"
TRACE: <2>exit.cxx            [  71] __libc_exit()                                                                                        {{enter
TRACE: <2>exit.cxx            [  71] __libc_exit()                                                                                        ((status=0 ))
TRACE: <2>atexit.cxx          [  84] cyg_libc_invoke_atexit_handlers()                                                                    {{enter
TRACE: <2>atexit.cxx          [  84] cyg_libc_invoke_atexit_handlers()                                                                      (((void)))

Scheduler:

Lock:                0
Current Thread:      <null>

Threads:

Idle Thread          pri =  31 state = R      id =   1
                     stack base = 800021F0 ptr = 80002510 size = 00000400
                     sleep reason NONE     wake reason NONE    
                     queue = 80000C54      wait info = 00000000

<null>               pri =   0 state = R      id =   2
                     stack base = 80002A48 ptr = 8000A968 size = 00008000
                     sleep reason NONE     wake reason NONE    
                     queue = 80000BD8      wait info = 00000000