2010-09-10 80 views
5

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

例子:

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) 

我也得到了玩家博克完全吐出一个traces.txt。

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

+0

来自C++ userland代码,与内核无关。请参阅git://android.git.kernel.org/platform/frameworks/base.git/media/jni/android_media_MediaPlayer.cpp和类似内容。 – 2010-09-10 14:00:21

+0

谢谢。但仍然:是否可以调试,例如与远程GDB会话? – neu242 2010-09-12 11:19:50

回答

9

你可以做很多事情。

如果您认为错误是在框架本身,然后获取源和挖掘http://source.android.com/

否则,Android的最好的调试器是DDMS,它可以与模拟器的工作,但也与真实的设备。 http://developer.android.com/guide/developing/tools/ddms.html

dumpstate through 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

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

另外,插入跟踪到内核代码可能会更容易。

+0

谢谢,但是...如何将跟踪插入到我的Java代码中来帮助调试内核代码?袒护我,我无知:p – neu242 2010-09-10 13:44:13

+0

我的意思是进入内核代码。 – doron 2010-09-10 13:52:34

0

除非您想在汇编级别进行调试,否则您可能必须在调试+调试符号启用的情况下自己构建内核。我认为大多数内核在一个小的设备中会默认避免这样做,因为它使内核更大。在这一点上,你可以启用内核调试器...

2

不是说这直接回答你的问题,但这些信息可能对你有用。

因此,根据您的-1004错误代码,您尝试流式传输时遇到I/O错误。至于-2147483648错误代码,不能帮你太多。您必须查看媒体播放器的所有日志输出,以了解为什么您要获取该代码,因为它没有定义。我从解码器扼制视频编码中看到了它。

从借来的:/frameworks/base/include/media/stagefright/MediaErrors.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

即使你不能够在内核级调试,跟踪将隐蔽的错误编号下载到正确的头文件(和描述性定义)仍然可能有用。

-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,它包括其中包含内核级错误代码/kernel/include/asm-generic/errno.h。

例如,如果连接()返回错误代码-110你就会知道那是因为超时的,因为它的定义为:

#define ETIMEDOUT  110  /* Connection timed out */ 
2

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

有关详细信息,请参阅Android构建系统的'gdbclient'shell函数, 预构建eabi gdb以及可能的DDD或其他前端。 Eclipse应该没问题。

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文章。

相关问题