2010-09-10 118 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文章。

相關問題