如何在真机上调试Android原生代码
我在 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 代码一样?谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
除非您想在汇编级别进行调试,否则您可能必须自己构建一个启用调试+调试符号的内核。我认为小型设备中的大多数内核都会默认避免这样做,因为它会使内核变得更大。此时您可以启用内核调试器...
Unless you want to debug at the assembly level, you'll probably have to build a kernel yourself with debugging + debug symbols enabled. I would think most kernels in a small device would avoid doing that by default, since it makes the kernel a lot bigger. At that point you could enable the kernel debugger...
您可以做很多事情。
如果您认为错误出在框架本身中,请获取源代码并挖掘 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,但找不到您放在那里的具体错误消息。
Quite a few things you can do.
If you believe the error is in the framework itself, then get the source and dig http://source.android.com/
Otherwise, the best debugger for Android is DDMS, it can work with the emulator, but also with the real device. http://developer.android.com/guide/developing/tools/ddms.html
dumpstate through adb (http://developer.android.com/guide/developing/tools/adb.html) will also give you a full snapshot of what is happening on the device, but it will difficult for you to get the exact point when the error happens.
Although that will still not give you source level debugging as GDB would (or I am not sure what you mean by your usual way of debugging Java code).
If you really mean kernel as kernel, then you are not really in Android anymore but more in Linux world but I don't think you need to go that far.
If you have trouble with a specific Android application (that's out of the open source and is not your own), I am afraid you are out of luck.
For the MediaPlayer part, the file for Eclair is located in
https://android.googlesource.com/platform/frameworks/base/+/eclair-release/media/java/android/media/MediaPlayer.java, but cannot find the specific error message you put there.
这并不是直接回答您的问题,但这些信息可能对您有用。
因此,根据您的 -1004 错误代码,您在尝试流式传输时遇到了 I/O 错误。至于-2147483648错误代码,对你没有多大帮助。您必须查看媒体播放器的所有日志输出,才能了解为什么会收到该代码,因为它尚未定义。我从解码器对视频编码的阻塞中看到了这一点。
借用:/frameworks/base/include/media/stagefright/MediaErrors.h
MEDIA_ERROR_BASE = -1000,
Not that this directly answers your question, but this information might be useful to you.
So based upon your -1004 error code, you had an I/O Error trying to stream. As far as the -2147483648 error code, can't help you much. You would have to look at all of the log output from the media player to see why you are getting that code since it isn't defined. I've seen it from having the decoder choke on the video encoding.
Borrowed from: /frameworks/base/include/media/stagefright/MediaErrors.h
MEDIA_ERROR_BASE = -1000,
可以使用远程调试(目标上的gdbserver + 主机上的gdb)
逐步执行在真实硬件上运行的 C/C++ 用户态代码。
它提供了所有“常用”选项,如断点、回溯、查看/设置变量、跟踪点。
有关详细信息,请查看 Android 构建系统的“gdbclient”shell 函数,
预构建 eabi gdb 以及 DDD 或其他前端。日食应该没问题。
Remote debugging (gdbserver on target + gdb on host) can be used
to step-through C/C++ userland code running on real hardware.
It offers all 'usual' options like breakpoints, backtrace, view/set variables, tracepoints.
For details, look at 'gdbclient' shell function of Android build system,
pre-build eabi gdb and maybe DDD or another frontend. Eclipse should be ok.
即使您无法在内核级别进行调试,跟踪神秘错误号到正确的头文件(和描述性定义)仍然很有用。
-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" rel="nofollow noreferrer"> googlesource.com/platform/frameworks/base/+/eclair-release/include/utils/Errors.h#49
正如您在
Errors.h
中看到的,它包含errno.h
其中包含内核级错误代码 /kernel/include/asm-generic/errno.h。例如,如果 connect() 返回错误代码 -110,您就会知道这是因为超时,因为它定义为:
Even if you are not able to debug on kernel level, tracking down the cryptic error number to the correct header file (and descriptive define) can still be useful.
-1004 means
ERROR_IO
and can be found inMediaErrors.h
:https://android.googlesource.com/platform/frameworks/base/+/eclair-release/include/media/stagefright/MediaErrors.h#32
-2147483648 probably is
UNKNOWN_ERROR
which can be found inErrors.h
:https://android.googlesource.com/platform/frameworks/base/+/eclair-release/include/utils/Errors.h#49
As you can see in
Errors.h
, it includeserrno.h
which includes kernel level error codes, /kernel/include/asm-generic/errno.h.For example, if connect() returns the error code -110 you will know it's because of a timeout since it's defined as:
尽管 Android 确实支持远程 GDB 会话,但这可能不适用于内核端代码。最好的选择是使用可用于执行停止模式调试的 JTAG 连接。由于停止模式调试会有效地停止 CPU 的执行,因此您可能会发现这会导致看门狗定时器出现问题。
或者,将跟踪插入内核代码可能会更容易。
Although Android does support remote GDB sessions, this probably will not work for Kernel Side Code. Your best bet is to use a JTAG connection which can be used to perform Stop Mode Debugging. Since stop mode debugging effectively halts the execution of your CPU, you might find this causes problems with Watchdog Timers.
Alternatively, inserting tracing into the kernel code may be easier.
您可以通过几种不同的方式来做到这一点。首先你需要找出你想要调试的服务是在Java框架服务(如system_server)中还是在纯本机应用程序(如surfaceflinger)中。
如果是纯原生服务,请查看调试android平台原生应用< /a> 文章。
如果服务是托管在system_server进程中的Java代码,请检查调试Android Java 框架服务一文。
如果您要调试的代码是Java服务通过JNI隐式加载的本机库,请检查调试 Android 框架原生库一文。
You can do this in couple of different ways. First you need to find out the service you want to debug is in Java framework service like system_server or in pure native application like surfaceflinger.
If it is pure native service, please check Debugging android platform native applications article.
If the service is Java code hosted in system_server process, please check Debugging Android Java framework services article.
If the code you want to debug is native library loaded by Java service through JNI implicitly, please check Debugging Android framework native libraries article.