原生的Android GDB远程调试得到了SIGILL

时间:2014-10-10 13:45:20

标签: android native remote-debugging

软件:官方TI安卓发布(源代码包),Jelly bean 4.2.2 for AM335x,(是的,arago / rowboat / TI开发人员添加对vanilla aosp的修改但与我的问题无关。)

硬件:am335xevm_sk(基于AM335x Cortex A8 SOC的TI开发板)

我的所作所为:

  1. 构建系统并使用SD卡引导硬件。一切正常。

  2. adb拉出init.am335xevm.rc文件,注释掉rild服务并将其推回,重启目标系统。我这样做是因为我想使用交叉调试器来远程调试rild。

  3. 设置远程调试:adb forward tcp ports。并在目标系统上启动gdbserver,如下:

    root@android:/ # gdbserver localhost:2345 system/bin/rild
    Process system/bin/rild created; pid = 829
    Listening on port 2345
    Remote debugging from host 127.0.0.1
    
  4. 远程调试rild,as:

    ma@ma-aspire:~/devkit/JB422$ PATH=$PATH:/home/ma/devkit/JB422/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin
    ma@ma-aspire:~/devkit/JB422$ arm-linux-androideabi-gdb
    GNU gdb (GDB) 7.3.1-gg2
    Copyright (C) 2011 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
    For bug reporting instructions, please see:
    <xxxx://www.gnu.org/software/gdb/bugs/>. 
    (gdb) file /home/ma/devkit/JB422/out/target/product/am335xevm_sk/symbols/system/bin/rild 
    Reading symbols from /home/ma/devkit/JB422/out/target/product/am335xevm_sk/symbols/system/bin/rild...done.
    (gdb) set sysroot /home/ma/devkit/JB422/out/target/product/am335xevm_sk/symbols
    (gdb) target remote localhost:2345
    Remote debugging using localhost:2345
    __dl__start () at bionic/linker/arch/arm/begin.S:35
    35 mov r0, sp
    (gdb) n
    36 mov r1, #0
    (gdb) n
    37 bl __linker_init
    (gdb) n
    
    Program received signal SIGILL, Illegal instruction.
    0x4013a89e in __linker_init (elfdata=0xbee7bae0) at bionic/linker/linker.cpp:2030
    2030 extern "C" unsigned __linker_init(unsigned **elfdata) {
    (gdb) c
    Continuing.
    
    Program terminated with signal SIGILL, Illegal instruction.
    The program no longer exists.
    (gdb)
    
  5. ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    我对低级工具链问题不太熟悉。我用Google搜索了问题,似乎很少有人遇到同样的问题。

    我下载了aosp源码(Android 4.2.2_r1,JDQ39)并比较了预建工具链和NDK内容,没有发现明显的差异。

    我也尝试过最新的NDK(r10b)。使用NDK中的预构建工具链重建整个目标系统并进行调试,结果是一样的。

    我还尝试使用平台设置为android-17和android-18生成独立工具链,并重复上述步骤,结果是一样的。

    我还试图重新构建NDK工具链并没有任何区别。

    我还尝试了较新版本的gdbserver(NDK r10b包中的预编译),问题仍然存在。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    但如果我使用NDK工具链调试一个简单的hello-world程序(动态链接liblog),如本页所示:

    www dot srombauts dot fr / 2011/03/06 / standalone-toolchain /

    并进行调试,我可以进入main(),但是在程序退出后,目标系统上的进程得到了类似的SIGILL终止,而不是正常退出。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    我很困惑,为什么会发生这种情况,因为许多开发人员使用gdb来调试本机代码,谷歌的平台开发人员也应该大量依赖gdb调试。这个问题似乎不太可能是由gdb或gdbserver中的错误引起的。也许它与am335x内核有关并且具体?或者我错过了使用gdb的重要内容?比方说,目标架构选项?或者应该为这种本机调试指定某些编译器选项?我已经在android上仔细阅读了很多关于原生远程调试的在线文章,没有发现任何特别指出的内容。

    我真的想使用远程GDB来调试一些本机程序,包括ril和其他一些包装HAL库的测试用例。请帮忙!

1 个答案:

答案 0 :(得分:0)

很抱歉,这不是答案,而是对我之前提问的补充。

我进一步挖掘了这个问题。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我在android源代码树中放了一个基本的helloworld程序:

#include <stdio.h>
#include <android/log.h>

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "hello-native", __VA_ARGS__))

void main(void)
{
    printf("Hello Native Printf\n");
    LOGI("Hello Native LOGI");
}

使用Android.mk文件:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello-native
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := hello-native.c

LOCAL_SHARED_LIBRARIES := liblog

include $(BUILD_EXECUTABLE)

然后调试失败了SIGILL,如上一篇文章所述。

但是,如果我使用标准的Makefile(正如Karim Yaghmour在其出色的书“嵌入式Android”中所提出的那样,第140页):

#Paths and settings

TARGET_PRODUCT = am335xevm_sk
ANDROID_ROOT = /home/ma/devkit/JB422
BIONIC_LIBC = $(ANDROID_ROOT)/bionic/libc
PRODUCT_OUT = $(ANDROID_ROOT)/out/target/product/$(TARGET_PRODUCT)
CROSS_COMPILE = $(ANDROID_ROOT)/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-

# Tool names
AS = $(CROSS_COMPILE)as
AR = $(CROSS_COMPILE)ar
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
LD = $(CROSS_COMPILE)ld
NM = $(CROSS_COMPILE)nm
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)ranlib
READELF = $(CROSS_COMPILE)readelf
SIZE = $(CROSS_COMPILE)size
STRINGS = $(CROSS_COMPILE)strings
STRIP = $(CROSS_COMPILE)strip

export AS AR CC CPP LD NM OBJCOPY OBJDUMP RANLIB READELF \
SIZE STRINGS STRIP

# Build settings

CFLAGS = -O0 -Wall -fno-short-enums -ggdb

HEADER_OPS = -I$(BIONIC_LIBC)/include \
-I$(BIONIC_LIBC)/arch-arm/include \
-I$(BIONIC_LIBC)/kernel/common \
-I$(BIONIC_LIBC)/kernel/arch-arm \
-I$(ANDROID_ROOT)/system/core/include

LDFLAGS = -nostdlib -Wl,-dynamic-linker,/system/bin/linker \
$(PRODUCT_OUT)/obj/lib/crtbegin_dynamic.o \
$(PRODUCT_OUT)/obj/lib/crtend_android.o \
-L$(PRODUCT_OUT)/obj/lib -lc -ldl -llog

# Installation variables
EXEC_NAME = hello-native
INSTALL = install
INSTALL_DIR = $(PRODUCT_OUT)/system/bin

# Files needed for the build
OBJS = hello-native.o

# Make rules
all: hello-native

.c.o:
$(CC) $(CFLAGS) $(HEADER_OPS) -c $<

hello-native: ${OBJS}
$(CC) -o $(EXEC_NAME) ${OBJS} $(LDFLAGS)

install: hello-native
test -d $(INSTALL_DIR) || $(INSTALL) -d -m 755 $(INSTALL_DIR)
$(INSTALL) -m 755 $(EXEC_NAME) $(INSTALL_DIR)

clean:
rm -f *.o $(EXEC_NAME) core
distclean:
rm -f *~
rm -f *.o $(EXEC_NAME) core

然后程序正确编译和调试。唯一的例外是当程序退出时,如果我将sysroot设置为/ out / target / product / am335xevm_sk / symbols,我得到了SIGILL,但如果我没有设置调试器sysroot,程序将正常退出。

它们使用不同的工具链和调试器,从原始TI版本,原始版本或新版本NDK,或从NDK中的源代码重建,以相同的方式工作。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

然后我尝试在ARM代码中编译rild,将LOCAL_ARM_MODE设置为arm,如下:

ifeq ($(TARGET_ARCH),arm)

LOCAL_SHARED_LIBRARIES += libdl
endif # arm

LOCAL_CFLAGS := -DRIL_SHLIB -O0
LOCAL_ARM_MODE := arm

LOCAL_MODULE:= rild
LOCAL_MODULE_TAGS := optional

include $(BUILD_EXECUTABLE)

然后程序正确编译和调试,如果我没有将sysroot设置为out / target / product / am335xevm_sk / symbols,否则,调试器可以进入链接器并使用SIGILL崩溃,如前所述。

这至少为我的需要提供了一种解决方案,但我不相信Android(ndk)gdb无法处理拇指代码? gcc / gdb设置有什么我错过的吗?或者在Rowboat发行版中修改了一些gcc选项,以防止官方gdb工具正常工作?

HELP!