简体   繁体   English

Android:如何在启动时使用 ADB shell 跟踪应用程序

[英]Android: How to strace an app using ADB shell am start

I need help on stracing Android apps in the SDK emulator.我需要有关在 SDK 模拟器中跟踪 Android 应用程序的帮助。

Here is my setup:这是我的设置:

I have an Android SDK emulator running the Android API 4.03 ADB shell connected to emulator.我有一个运行 Android API 4.03 ADB shell 的 Android SDK 模拟器连接到模拟器。

I am able to install an APK using the ADB install filename.apk我可以使用 ADB install filename.apk 安装 APK

I am able to run the app using the ADB shell am start -a android.intent.action.Main -n com.akproduction.notepad/com.akproduction.notepad.NoteList我能够使用 ADB shell 运行应用程序am start -a android.intent.action.Main -n com.akproduction.notepad/com.akproduction.notepad.NoteList

I try to strace using (ADB shell) strace am start -a android.intent.action.Main -n com.akproduction.notepad/com.akproduction.notepad.NoteList but I get nothing!我尝试使用(ADB shell) strace am start -a android.intent.action.Main -n com.akproduction.notepad/com.akproduction.notepad.NoteList但我什么也没得到!

How do you trace the runtime behavior of Android apps and their installation?您如何跟踪 Android 应用及其安装的运行时行为?

(PS The test app is locatedhere . (PS 测试应用程序位于此处

The "am start" command does not directly run your application; “am start”命令不会直接运行您的应用程序; it simply tells Android to do whatever is necessary to, in your example, start a specific activity.它只是告诉 Android 做任何必要的事情,在你的例子中,开始一个特定的活动。

The strace command is normally used as in strace commandname command args and it launches commandname -- easy, but in this Android use case, not helpful. strace命令通常在strace commandname command args ,它启动commandname —— 很简单,但在这个 Android 用例中,没有帮助。 However, strace has a -p option which is helpful to you: strace -p <process id> will let you start tracing the process with the specified id.但是,strace 有一个-p选项,它对您很有帮助: strace -p <process id>将让您开始使用指定的 id 跟踪进程。

If you type ps on your Android system you can locate the process with the name com.akproduction.notepad (probably; by default processes are named for their Android package, but it's possible to change that in the manifest).如果您在 Android 系统上键入ps ,您可以找到名为com.akproduction.notepad的进程(可能;默认情况下,进程以其 Android 包命名,但可以在清单中更改)。 Then you can start stracing it, wherever it happens to be.然后你可以开始追踪它,无论它在哪里。

If you need to catch things early in the process, you'll need to either modify the code to cause it to delay until you're ready to trace it, or you'll at least need to get the process running before you start the activity.如果您需要在流程早期发现问题,您需要修改代码以使其延迟,直到您准备好跟踪它,或者您至少需要在开始之前让流程运行活动。 The second option there is often as easy as starting the activity, then using the back button, then getting your trace ready, then starting the activity again -- but this is always code-specific to the application.第二种选择通常与启动活动一样简单,然后使用后退按钮,然后准备好跟踪,然后再次启动活动——但这始终是特定于应用程序的代码。

Android apps are actually started by forking the zygote process, so you can trace app initialization by tracing the zygote process and following child processes ('-f'): Android 应用程序实际上是通过 fork zygote 进程启动的,因此您可以通过跟踪 zygote 进程并跟踪子进程('-f')来跟踪应用程序初始化:

setenforce 0  # In Android 4.3 and later, if SELinux is enabled, strace will fail with "strace: wait: Permission denied"

set `ps | grep zygote` ; strace -p $2 -f -tt -T -s 500 -o /sdcard/strace.txt

This is an ugly one-liner hack I used today to solve this issue.这是我今天用来解决这个问题的一个丑陋的单行黑客。 Assuming the program has some known name, just try attaching to the process as soon as it appears.假设程序有一些已知的名称,只要它出现就尝试附加到进程。 In this example, I'm interested in all calls to open.在这个例子中,我对所有打开的调用感兴趣。

while true; do
  while ! ps  | grep -q -i MyProgram; do :; done;
  ps | grep -i MyProgram | while read a b c; do
   strace -e open -f -p $b;
  done;
done

Here's a one-liner that grabs the process id and pipes it to strace right after am launches the app.这是一个单行代码,它在am启动应用程序后立即获取进程 ID并将其通过管道传送到 strace。 You won't get the first few instructions executed, but it kicks in early enough for my needs.你不会得到前几条指令的执行,但它很早就开始满足我的需要。

am start -n com.packagename.here\\.ActivityName && set `ps | grep com.packagename.here` && strace -p $2

I would recommend prior to starting your app start strace on zygote process and follow forks.我建议在启动您的应用程序之前,先在 zygote 进程上启动 strace 并跟踪 fork。 Zygote process is the main process from which every new process forks in Android, including your app. Zygote 进程是 Android 中每个新进程分支的主要进程,包括您的应用程序。 Then you might want to filter the log based on PIDs you are interested in. Example:然后您可能希望根据您感兴趣的 PID 过滤日志。示例:

ps zygote ps合子

get the zygote PID, then获取合子PID,然后

strace -f -p < zygote_PID > strace -f -p <zygote_PID>

I've found a tricky way to do this and also guarantee that all the syscalls are going to be catch.我找到了一个棘手的方法来做到这一点,并保证所有的系统调用都会被捕获。 It can be done even if the app is not debuggable:即使应用程序不可调试,也可以这样做:

  • Set the Activity Manager ( am ) to put the app in debug mode with a -w option that will halt its execution until it is attached to a debugger设置活动管理器 ( am ) 以使用-w选项将应用程序置于调试模式,该选项将停止其执行,直到它附加到调试器
  • Start the application manually (you can just click on the screen on its icon or call it with am start手动启动应用程序(您只需单击屏幕上的图标或使用am start调用它
  • With the application halted, obtain its PID在应用程序停止的情况下,获取其 PID
  • With its PID obtained, call strace to trace this process得到它的PID后,调用strace来跟踪这个进程
  • Finally, attach the debugger so the execution start.最后,附加调试器以便开始执行。

Here are the steps:以下是步骤:

adb shell # shell into the device
am set-debug-app -w com.package.name # put app to debug mode
am start com.package.name/com.path.to.MainActivity # start the app
ps -A | grep com.package.name # this will show you the PID
strace -p <PID> > appoutput.txt 2> appstrace.txt 
# strace the program and record its output and strace in txt files

Now just attach the debugger and enjoy, you can do it for example in Android Studio or Eclipse.现在只需附加调试器并享受,例如,您可以在 Android Studio 或 Eclipse 中进行。 From this point on the execution will begin and you will be able to trace it since the very first line of code.从这一点开始执行将开始,您将能够从第一行代码开始跟踪它。

If you have root access or the device is running without SELinux enabled, then you can follow the way from Android site:如果您有 root 访问权限或者设备在没有启用 SELinux 的情况下运行,那么您可以按照 Android 站点的方法进行操作:

Set up the device so that you can run strace.设置设备以便您可以运行 strace。 You need to be root, disable SELinux, and restart the runtime to remove the seccomp filter that will otherwise prevent strace from running: adb root adb shell setenforce 0 adb shell stop adb shell start您需要是 root,禁用 SELinux,然后重新启动运行时以删除 seccomp 过滤器,否则会阻止 strace 运行: adb root adb shell setenforce 0 adb shell stop adb shell start

Set up a world-writable directory for strace logs, because strace will be running under the app's uid: adb shell mkdir -m 777 /data/local/tmp/strace为 strace 日志设置一个全局可写目录,因为 strace 将在应用程序的 uid 下运行: adb shell mkdir -m 777 /data/local/tmp/strace

Choose the process to trace and launch it: adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'选择要跟踪的进程并启动它: adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'

Launch the process normally.正常启动进程。

https://source.android.com/devices/tech/debug/strace#app-strace https://source.android.com/devices/tech/debug/strace#app-strace

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM