首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >本地Android远程调试获得SIGILL

本地Android远程调试获得SIGILL
EN

Stack Overflow用户
提问于 2014-10-10 13:45:20
回答 1查看 1.3K关注 0票数 1

软件:官方的TI android发布版(源代码包),用于AM335x的Jelly 4.2.2 (是的,arago/rowboat/TI开发人员添加了对普通aosp的修改,但与我的问题无关)。

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

我所做的:

  1. 建立系统,并使用sd卡启动硬件。一切正常运转。
  2. 亚行提取init.am335xevm.rc文件,注释rild服务并将其推回,重新启动目标系统。我这样做是因为我想使用交叉调试器远程调试rild。
  3. 设置远程调试: adb转发tcp端口。并在目标系统上启动gdbserver,如: root@android:/ # gdbserver localhost:2345 system/bin/rild Process system/bin/rild已创建;pid = 829侦听来自主机127.0.0.1的端口2345远程调试
  4. 远程调试rild,如: ma@ma-aspire:~/devkit/ it 422$ PATH=$PATH:/home/ma/devkit/JB422/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin ma@ma-aspire:~/devkit/it 422$ arm-linux-androideabi-gdb GNU gdb (GDB) 7.3.1-G版权G2 (C) 2011免费软件基金会GPLv3+:GNU版本3或更高版本http://gnu.org/licenses/gpl.html这是免费软件:您可以自由更改和重新分发它。在法律允许的范围内,没有任何保证。输入“显示复制”和“显示保修”以获取详细信息。这个GDB被配置为“--host=x86_64-linux target=arm-linux”。有关错误报告说明,请参见:xxxx://www.gnu.org/software/gdb/bugs/。(gdb)文件/home/ma/devkit/JB422/out/target/product/am335xevm_sk/symbols/system/bin/rild从/home/ma/devkit/JB422/out/target/product/am335xevm_sk/symbols/system/bin/rild...done.读取符号(gdb)设置sysroot /home/ma/devkit/JB422/out/target/product/am335xevm_sk/symbols (gdb)目标远程本地主机:2345 __dl__start ()使用本地主机:2345__dl__start()在仿生/链接器/arch/arm/初学者。S: 35 mov r0,sp (gdb) n 36 mov r1,#0 (gdb) n 37 bl __linker_init (gdb) n程序接收信号SIGILL,非法指令。0x4013a89e in __linker_init (elfdata=0xbee7bae0) at bionic/linker/linker.cpp:2030 extern "C“未签名的__linker_init(未签名**elfdata) { (gdb) c继续。程序终止信号SIGILL,非法指令。这个程序不再存在。(gdb)

代码语言:javascript
运行
复制

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

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

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

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

我还试图重新构建NDK工具链,但没有区别。

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

代码语言:javascript
运行
复制

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

www点srombauts点fr/2011/03/06/独立工具链/

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

代码语言:javascript
运行
复制

我非常困惑为什么会出现这种情况,因为许多开发人员使用gdb调试本机代码,而google的平台开发人员也应该严重依赖gdb调试。这个问题似乎不太可能是由gdb或gdbserver中的错误引起的。也许它是与am335x内核相关和特定的?还是我错过了一些重要的使用gdb的东西?比如说,目标架构选项?或者应该为这类本机调试指定某些编译器选项?我仔细地阅读了很多关于android上本机远程调试的在线文章,但没有发现任何特别指出的地方。

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

EN

回答 1

Stack Overflow用户

发布于 2014-10-13 06:37:27

很抱歉,这不是答覆,而是对我上一项质询的补充。

我进一步研究了这个问题。

代码语言:javascript
运行
复制

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

代码语言:javascript
运行
复制
#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文件设置为:

代码语言:javascript
运行
复制
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在其出色的著作Embedded Android (第140页)中提出的那样):

代码语言:javascript
运行
复制
#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/符号,则得到和SIGILL,但如果不设置调试器sysroot,程序将正常退出。

它们使用不同的工具链和调试器,从原始的TI版本,从最初的或新版本的NDK,或者从NDK中的源代码重新构建。

代码语言:javascript
运行
复制

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

代码语言:javascript
运行
复制
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/符号,则程序将正确编译和调试,否则调试器可能会像前面提到的那样进入链接器并与SIGILL崩溃。

这至少为我的需要提供了一个变通的解决方案,但我不能相信Android (ndk) gdb不能处理拇指代码?gcc/gdb的设置中有什么我错过的吗?还是一些gcc的选项在划艇发行版中被修改,从而阻碍了官方gdb工具的正常工作?

帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26300959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档