GDB
O Xamarin.Android 4.10 introduziu o suporte parcial para uso de gdb
usando o destino de MSBuild _Gdb
.
Observação
O suporte a gdb
requer que o NDK do Android esteja instalado.
Há três maneiras de usar o gdb
:
- Builds de depuração com o Fast Deployment habilitado.
- Builds de depuração com o Fast Deployment desabilitado.
- Builds de lançamento.
Quando as coisas derem errado, consulte a seção Solução de problemas.
Ao compilar e implantar um build de depuração com o Fast Deployment habilitado, gdb
pode ser anexado usando o destino do MSBuild _Gdb
.
Primeiro, instale o aplicativo. Isso pode ser feito por meio do IDE ou da linha de comando:
$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:Install *.csproj
Em segundo lugar, execute o destino _Gdb
. No final da execução, uma linha de comando gdb
será impressa:
$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:_Gdb *.csproj
...
Target _Gdb:
"/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
...
O destino _Gdb
iniciará uma atividade launcher declarada dentro de seu arquivo AndroidManifest.xml
. Para especificar explicitamente quais atividade seja executada, use a propriedade do MSBuild RunActivity
. No momento, iniciar serviços e outros constructos do Android não é uma ação compatível.
O destino _Gdb
criará um diretório gdb-symbols
e copiará o conteúdo dos diretórios /system/lib
e $APPDIR/lib
do seu destino para lá.
Observação
O conteúdo do diretório gdb-symbols
está vinculado ao destino do Android no qual você implantou, e não será automaticamente substituído se você mudar o destino. (Considere isso um bug.) Se você alterar dispositivos de destino Android, precisará excluir manualmente esse diretório.
Por fim, copie o comando gdb
gerado e execute-o no shell:
$ "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) bt
#0 0x40082e84 in nanosleep () from /Users/jon/Development/Projects/Scratch.HelloXamarin20/gdb-symbols/libc.so
#1 0x4008ffe6 in sleep () from /Users/jon/Development/Projects/Scratch.HelloXamarin20/gdb-symbols/libc.so
#2 0x74e46240 in ?? ()
#3 0x74e46240 in ?? ()
(gdb) c
Builds de depuração com o Fast Deployment funcionam copiando o programa gdbserver
do NDK do Android para o diretório .__override__
do Fast Deployment. Quando o Fast Deployment está desabilitado, esse diretório pode não existir.
Há duas soluções alternativas:
- Definir a propriedade do sistema
debug.mono.log
de modo que o diretório.__override__
seja criado. - Incluir
gdbserver
dentro de.apk
.
Para definir a propriedade do sistema debug.mono.log
, use o comando adb
:
$ adb shell setprop debug.mono.log gc
Uma vez que a propriedade do sistema foi definida, execute o destino _Gdb
e o comando gdb
impresso, assim como com a configuração Builds de depuração com o Fast Deployment:
$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:_Gdb *.csproj
...
Target _Gdb:
"/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
...
$ "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) c
Para incluir gdbserver
dentro de seu aplicativo:
Encontre
gdbserver
no seu Android NDK (ele deve estar em $ANDROID_NDK_PATH/prebuilt/android-arm/gdbserver/gdbserver) e copie-o para o diretório do Project.Renomeie
gdbserver
para libs/armeabi-v7a/libgdbserver.so.Adicione libs/armeabi-v7a/libgdbserver.so ao seu projeto com um ação de build de
AndroidNativeLibrary
.Recompile e reinstale seu aplicativo.
Uma vez que o aplicativo tiver sido reinstalado, execute o destino _Gdb
e o comando gdb
impresso, assim como com a configuração Builds de depuração com o Fast Deployment:
$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:_Gdb *.csproj
...
Target _Gdb:
"/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
...
$ "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) c
O suporte a gdb
requer três coisas:
- A permissão de
INTERNET
. - Depuração de Aplicativo habilitada.
- Um
gdbserver
acessível.
A permissão INTERNET
é habilitada por padrão em aplicativos de depuração. Se ela não ainda estiver presente no seu aplicativo, você poderá adicioná-la editando Properties/AndroidManifest.xml ou editando as Propriedades do Projeto.
A depuração de aplicativo pode ser habilitada configurando a propriedade de atributo personalizado ApplicationAttribute.Debugging para true
, ou editando Properties/AndroidManifest.xml e definindo o atributo //application/@android:debuggable
para true
:
<application android:label="Example.Name.Here" android:debuggable="true">
Um gdbserver
acessível pode ser fornecido seguindo a seção Builds de depuração sem o Fast Deployment.
Um probleminha: o destino _Gdb
do MSBuild finalizará quaisquer instâncias de aplicativo em execução anteriormente. Isso não funcionará em destinos com Android anterior à v4.0.
A função mono_pmip
(útil para obter registros de ativação gerenciados) é exportada do libmonosgen-2.0.so
, cujo pull não é efetuado pelo destino _Gdb
atualmente. (Isso será corrigido em uma versão futura.)
Para habilitar a chamada a funções localizadas em libmonosgen-2.0.so
, copie-o do dispositivo de destino para o diretório gdb-symbols
:
$ adb pull /data/data/Mono.Android.DebugRuntime/lib/libmonosgen-2.0.so Project/gdb-symbols
Reinicie então sua sessão de depuração.
Quando o comando gdb
encontrar um erro com "Bus error: 10"
, reinicie o dispositivo Android.
$ "/path/to/arm-linux-androideabi-gdb" -x "Project/gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
...
Bus error: 10
$
$ "/path/to/arm-linux-androideabi-gdb" -x "Project/gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
...
(gdb) bt
No stack.
Isso geralmente é um sinal de que o conteúdo do diretório gdb-symbols
não está sincronizado com o destino do Android. (Você alterou o destino do Android?)
Exclua o diretório gdb-symbols
e tente novamente.