# Asterisk Debug This document describes how to debug and trouble shoot Asterisk and its modules, especially for crashes with segmentation fault. ## Build Asterisk with Debug Information GDB can be used to analyze stacks when a crash occurs. In order to let gdb provide sufficient stack trace, asterisk and its modules must have debug information not being stripped. Here comes procedures to build asterisk with as much debug information as possible. ### Enable package gdb Run ```make menuconfig``` and enable ```Development → gdb``` ``` ~/git/iopsyswrt$ grep gdb .config CONFIG_PACKAGE_gdb=y ``` gdb will be installed and running on the target directly. ### Append libbfd as the dependency This package is requred when enabling more debug options for Asterisk. ``` diff --git a/net/asterisk/Makefile b/net/asterisk/Makefile index 824b9e7..ab85f07 100644 --- a/net/asterisk/Makefile +++ b/net/asterisk/Makefile @@ -463,7 +463,7 @@ $(call Package/$(PKG_NAME)/Default) TITLE:=Complete open source PBX, v$(PKG_VERSION) MENU:=1 DEPENDS:=+libstdcpp +jansson +libcap +libedit +libopenssl +libsqlite3 +libuuid +libxml2 +zlib \ - +libncurses +libpopt +libxslt +ubus +libpicoevent + +libncurses +libpopt +libxslt +ubus +libpicoevent +libbfd endef define Package/$(PKG_NAME)/description ``` ### Build An Entire Firmware as Usual First Note that this step is absolutely mandatory. Otherwise the size of the firmware might be too big to fit the target when strip option is disabled in the later steps. ### Disable Strip Option The debug information of all executable and shared object files on the target are stripped. That causes gdb not able to show useful stack information in most scenarios. So asterisk and its modules must have debug information not being stripped. Run ```make menuconfig``` and check ```Global build settings → Binary stripping method → none``` ``` ~/git/iopsyswrt$ grep -i strip .config # CONFIG_KERNEL_PROC_STRIPPED is not set # Stripping options CONFIG_NO_STRIP=y # CONFIG_USE_STRIP is not set # CONFIG_USE_SSTRIP is not set # CONFIG_STRIP_KERNEL_EXPORTS is not set ``` ### Enable Debug Options in Asterisk Enter the directory of package asterisk in iopsyswrt/build_dir and run ```make menuselect```. Go to ```Compiler Flags```. Enable the followings and press S to save the settings. ``` [*] DONT_OPTIMIZE [*] COMPILE_DOUBLE [*] DEBUG_THREADS [ ] DEBUG_FD_LEAKS [*] BETTER_BACKTRACES [ ] LOTS_OF_SPANS [*] MALLOC_DEBUG [*] DEBUG_CHAOS XXX BUILD_NATIVE --- Extended --- [*] REF_DEBUG [*] AO2_DEBUG [ ] REBUILD_PARSERS [ ] LOW_MEMORY [*] DISABLE_INLINE [*] OPTIONAL_API XXX USE_HOARD_ALLOCATOR [ ] RADIO_RELAX [ ] G711_NEW_ALGORITHM < > G711_REDUCED_BRANCHING < > TEST_CODING_TABLES < > TEST_TANDEM_TRANSCODING (*) ADDRESS_SANITIZER (*) THREAD_SANITIZER (*) LEAK_SANITIZER ``` Note that you can even enable more flags. ### Rebuild asterisk and asterisk-chan-voicemngr ``` make package/asterisk/compile V=s ``` You shall see the entire package is rebuilt since the compiler flags have been changed. Use utility ```file``` to check asterisk and .so files in ```build_dir/target-<target-name>/asterisk-18.11.2/ipkg-<target-name>/asterisk/``` are not stripped. Rebuild asterisk-chan-voicemngr. But {clean,compile} is needed. Otherwise the package won’t be rebuilt. ``` make package/asterisk-chan-voicemngr/{clean,compile} V=s ``` ### Rebuild toolchain ``` make package/toolchain/{clean,compile} ``` The purpose is to generate a libc.so which has debug information not being stripped. This is very useful to get a full stack trace in GDB. ### Build An Entire Firmware as Usual Again Asterisk has many .ipk files in bin/packages/ folder and this makes difficult to manually install them on the target. So the most convenient way is to rebuild the entire firmware image which contains Asterisk with debug information. Note that all other packages do have debug information stripped. ### Upgrade the Firmware to the DUT Upgrade the firmware to the DUT as usual. ### Modify the Init Startup Script and Restart Asterisk * Add command line argument “-vvvvvg” to enable debug mode * Enable core dump Restart asterisk after modification of ```/etc/init.d/asterisk```. ``` openwrt-telephony$ git diff diff --git a/net/asterisk/files/asterisk.init b/net/asterisk/files/asterisk.init index a169304..125fd9c 100755 --- a/net/asterisk/files/asterisk.init +++ b/net/asterisk/files/asterisk.init @@ -71,10 +71,10 @@ start_service() { config_get_bool log_stdout general log_stdout 1 procd_open_instance - procd_set_param command $PROG -f -C /var/etc/asterisk/asterisk.conf + procd_set_param command $PROG -f -vvvvvg -C /var/etc/asterisk/asterisk.conf procd_set_param respawn 6 5 3 # add extra time for reload config procd_set_param term_timeout 20 - #procd_set_param limits core="unlimited" # uncomment this for debug + procd_set_param limits core="unlimited" # uncomment this for debug # Forward stderr and stdout to logd procd_set_param stderr $log_stderr procd_set_param stdout $log_stdout ``` ### Analysis when a Crash Occurs When asterisk crashes, run the following commands to analyze. ``` root@eagle-44d437883010:~# service asterisk stop root@eagle-44d437883010:~# gdb -se asterisk -c /tmp/asterisk*.core (gdb) bt full #0 __cp_begin () at src/thread/arm/syscall_cp.s:23 No locals. #1 0xb6ee81dc in __syscall_cp_c (nr=168, u=<optimized out>, v=<optimized out>, w=<optimized out>, x=0, y=2122088, z=-1233931155) at src/thread/pthread_cancel.c:33 self = 0x1cf9ab r = <optimized out> st = <optimized out> #2 0x00227e20 in ?? () (gdb) (gdb) thread apply all Please specify a command at the end of 'thread apply all' (gdb) thread apply all bt Thread 45 (LWP 14354): #0 __cp_begin () at src/thread/arm/syscall_cp.s:23 #1 0xb6ee81dc in __syscall_cp_c (nr=162, u=<optimized out>, v=<optimized out>, w=<optimized out>, x=0, y=0, z=0) at src/thread/pthread_cancel.c:33 #2 0x00000000 in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) Thread 44 (LWP 14341): #0 __cp_begin () at src/thread/arm/syscall_cp.s:23 #1 0xb6ee81dc in __syscall_cp_c (nr=142, u=<optimized out>, v=<optimized out>, w=<optimized out>, x=0, y=1024, z=-1252840276) at src/thread/pthread_cancel.c:33 #2 0xb5532c00 in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) ... ``` **Note that using gdbserver attaching to a running asterisk may interfere the behavior of the process, e.g. some ubus call could be hanging. So gdbserver is NOT recommended. The effective way is to run asterisk normally and run gdb from the target directly when a crash occurs.** ### External Links [Get a Backtrace of Asterisk](https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=5243139) [Asterisk Debugging](https://wiki.asterisk.org/wiki/display/AST/Debugging)