如何在真实设备上调试Android本机代码

时间:2010-09-10 12:53:04

标签: android c++ debugging android-source android-music-player

我在Android中的媒体后端(主要是Stagefrightplayer)遇到了一些麻烦,我想了解它为什么会抛出错误。错误通常是设备特定的,因此在仿真器上进行调试是不够的。

示例:

I/AwesomePlayer(  147): mConnectingDataSource->connect() returned -1004
V/MediaPlayerService(  147): [332] notify (0x272830, 100, 1, -1004)
E/MediaPlayer(24881): error (1, -1004)
E/MediaPlayer(24881): Error (1,-1004)
W/PlayerListener(24881): Received error: what = 1, extra = -1004

示例2:

E/MediaPlayer(  941): error (1, -2147483648)

我还让玩家完全开玩笑并吐出了痕迹。

有没有办法调试正在发生的事情,就像调试Java代码一样?感谢。

7 个答案:

答案 0 :(得分:9)

你可以做很多事情。

如果你认为错误在框架本身,那么获取源并挖掘http://source.android.com/

否则,Android的最佳调试器是DDMS,它可以与模拟器一起使用,也可以与真实设备一起使用。 http://developer.android.com/guide/developing/tools/ddms.html

dumpstate to adb(http://developer.android.com/guide/developing/tools/adb.html)也会为您提供设备上发生的事情的完整快照,但是当您发生错误时,您很难获得确切的信息。

虽然这仍然不会像GDB那样为你提供源代码级调试(或者我不确定你通常的调试Java代码的方式是什么意思)。

如果你真的把内核称为内核,那么你不再是Android了,而是更多的Linux世界,但我认为你不需要那么远。

如果您在使用某个特定的Android应用程序时遇到问题(这不是您自己的应用程序),我担心您运气不好。

对于MediaPlayer部分,Eclair的文件位于 https://android.googlesource.com/platform/frameworks/base/+/eclair-release/media/java/android/media/MediaPlayer.java,但无法找到您放在那里的具体错误消息。

答案 1 :(得分:2)

并非这直接回答了您的问题,但这些信息可能对您有用。

因此,根据您的-1004错误代码,您尝试流式传输时出现I / O错误。至于-2147483648错误代码,对你帮不了多少。您必须查看媒体播放器的所有日志输出,以了解您为何获得该代码,因为它未定义。我已经看到了解码器阻塞视频编码。

借鉴:/frameworks / base / include / media / stagefright / MediaIrors.h

MEDIA_ERROR_BASE = -1000,

ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE,
ERROR_NOT_CONNECTED     = MEDIA_ERROR_BASE - 1,
ERROR_UNKNOWN_HOST      = MEDIA_ERROR_BASE - 2,
ERROR_CANNOT_CONNECT    = MEDIA_ERROR_BASE - 3,
ERROR_IO                = MEDIA_ERROR_BASE - 4,
ERROR_CONNECTION_LOST   = MEDIA_ERROR_BASE - 5,
ERROR_MALFORMED         = MEDIA_ERROR_BASE - 7,
ERROR_OUT_OF_RANGE      = MEDIA_ERROR_BASE - 8,
ERROR_BUFFER_TOO_SMALL  = MEDIA_ERROR_BASE - 9,
ERROR_UNSUPPORTED       = MEDIA_ERROR_BASE - 10,
ERROR_END_OF_STREAM     = MEDIA_ERROR_BASE - 11,

答案 2 :(得分:2)

即使您无法在内核级别进行调试,将隐藏错误编号追踪到正确的头文件(以及描述性定义)仍然有用。

-1004表示ERROR_IO,可以在MediaErrors.h中找到:
 https://android.googlesource.com/platform/frameworks/base/+/eclair-release/include/media/stagefright/MediaErrors.h#32

-2147483648可能是UNKNOWN_ERROR,可以在Errors.h中找到:
https://android.googlesource.com/platform/frameworks/base/+/eclair-release/include/utils/Errors.h#49

正如您在Errors.h中所看到的,它包括errno.h,其中包含内核级错误代码/kernel/include/asm-generic/errno.h。

例如,如果connect()返回错误代码-110,您将知道它是因为超时,因为它被定义为:

#define ETIMEDOUT       110     /* Connection timed out */

答案 3 :(得分:2)

可以使用远程调试(目标上的gdbserver +主机上的gdb) 逐步执行在真实硬件上运行的C / C ++用户态代码。 它提供了所有“常用”选项,如断点,回溯,视图/设置变量,跟踪点。

有关详细信息,请查看Android构建系统的'gdbclient'shell函数, 预构建eabi gdb,也许是DDD或其他前端。 Eclipse应该没问题。

答案 4 :(得分:1)

虽然Android确实支持远程GDB会话,但这可能不适用于内核端代码。最好的办法是使用JTAG连接,该连接可用于执行停止模式调试。由于停止模式调试有效地停止了CPU的执行,因此您可能会发现这会导致看门狗定时器出现问题。

或者,将跟踪插入内核代码可能更容易。

答案 5 :(得分:1)

您可以通过几种不同的方式完成此操作。首先,您需要找到要调试的服务,如Java框架服务,如system_server或纯本机应用程序,如surfaceflinger。

如果是纯粹的原生服务,请查看Debugging android platform native applications文章。

如果该服务是system_server进程中托管的Java代码,请查看Debugging Android Java framework services文章。

如果您要调试的代码是由Java服务通过JNI隐式加载的本机库,请查看Debugging Android framework native libraries文章。

答案 6 :(得分:0)

除非您想在程序集级别进行调试,否则您可能必须自己构建内核并启用调试+调试符号。我认为小型设备中的大多数内核都会在默认情况下避免这样做,因为它会使内核变得更大。此时,您可以启用内核调试程序......

相关问题