5

我在 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)

我还让玩家彻底崩溃并吐出一个 traces.txt。

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

4

7 回答 7

9

你可以做的事情相当多。

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

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

通过 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,但找不到您放在那里的特定错误消息。

于 2010-11-01T18:06:37.073 回答
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,
于 2011-03-04T19:40:23.413 回答
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 */
于 2011-07-04T14:20:57.690 回答
2

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

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

于 2011-07-07T18:46:21.390 回答
1

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

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

于 2010-09-10T13:37:49.240 回答
1

您可以通过几种不同的方式做到这一点。首先,您需要找出您要调试的服务是在 Java 框架服务(如 system_server)中,还是在纯原生应用程序(如 surfaceflinger)中。

如果是纯原生服务,请查看调试android平台原生应用一文。

如果服务是托管在 system_server 进程中的 Java 代码,请查看调试 Android Java 框架服务一文。

如果要调试的代码是 Java 服务通过 JNI 隐式加载的原生库,请查看调试 Android 框架原生库一文。

于 2014-07-31T03:44:51.563 回答
0

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

于 2010-11-02T18:39:52.787 回答