ใน Android 8.0 ขึ้นไป ART Tooling Interface (ART TI) จะแสดงข้อมูลภายในรันไทม์บางอย่าง และช่วยให้เครื่องมือวิเคราะห์และโปรแกรมแก้ไขข้อบกพร่องส่งผลต่อลักษณะการทํางานรันไทม์ของแอปได้ ซึ่งสามารถใช้เพื่อติดตั้งใช้งานเครื่องมือด้านประสิทธิภาพที่ทันสมัยซึ่งมีไว้สําหรับติดตั้งใช้งานตัวแทนแบบเนทีฟในแพลตฟอร์มอื่นๆ
ข้อมูลภายในรันไทม์จะแสดงต่อตัวแทนที่โหลดลงในกระบวนการรันไทม์
ซึ่งจะสื่อสารกับ ART ผ่านการโทรโดยตรงและการโทรกลับ รันไทม์รองรับหลายตัวแทนเพื่อให้แยกข้อกังวลเกี่ยวกับโปรไฟล์ที่แตกต่างกันได้ คุณอาจระบุตัวแทนเมื่อเริ่มต้นรันไทม์ (เมื่อเรียกใช้ dalvikvm
หรือ app_process
) หรือแนบกับกระบวนการที่ทำงานอยู่
เนื่องจากความสามารถในการวัดและแก้ไขลักษณะการทํางานของแอปและรันไทม์มีประสิทธิภาพสูงมาก เราจึงผสานรวมมาตรการด้านความปลอดภัย 2 ประการไว้ใน ART TI ดังนี้
- ประการแรก โค้ดที่แสดงอินเทอร์เฟซของตัวแทนอย่าง JVMTI จะใช้เป็นปลั๊กอินรันไทม์ ไม่ใช่คอมโพเนนต์หลักของรันไทม์ การโหลดปลั๊กอินอาจถูกจํากัด เพื่อบล็อกไม่ให้ตัวแทนค้นหาจุดต่อประสานใดๆ
- ประการที่ 2 ทั้งคลาส
ActivityManager
และกระบวนการรันไทม์อนุญาตให้ตัวแทนแนบกับแอปที่แก้ไขข้อบกพร่องได้เท่านั้น แอปที่แก้ไขข้อบกพร่องได้ได้รับการอนุมัติจากนักพัฒนาแอปให้วิเคราะห์และเครื่องมือวัด และจะไม่เผยแพร่แก่ผู้ใช้ Google Play Store ไม่อนุญาตให้เผยแพร่แอปที่แก้ไขข้อบกพร่องได้ วิธีนี้ช่วยให้มั่นใจได้ว่าแอปปกติ (รวมถึงคอมโพเนนต์หลัก) จะไม่สามารถดัดแปลงหรือควบคุมได้
การออกแบบ
ขั้นตอนทั่วไปและการเชื่อมโยงในแอปที่มีเครื่องมือวัดจะแสดงในรูปที่ 1

ปลั๊กอิน ART libopenjdkjvmti
จะแสดง ART TI ซึ่งออกแบบมาเพื่อรองรับความต้องการและข้อจำกัดของแพลตฟอร์ม ดังนี้
- การกําหนดคลาสใหม่จะอิงตามไฟล์
Dex
ซึ่งมีคําจํากัดความคลาสเดียวเท่านั้น แทนที่จะเป็นไฟล์คลาส - ระบบจะไม่แสดง API ภาษา Java สําหรับเครื่องมือวัดผลและการกําหนดใหม่
นอกจากนี้ ART TI ยังรองรับเครื่องมือวิเคราะห์โปรไฟล์ของ Android Studio ด้วย
โหลดหรือแนบตัวแทน
หากต้องการแนบตัวแทนเมื่อเริ่มต้นรันไทม์ ให้ใช้คำสั่งนี้เพื่อโหลดทั้งปลั๊กอิน JVMTI และตัวแทนที่ระบุ
dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …
ไม่มีมาตรการด้านความปลอดภัยเมื่อโหลดตัวแทนที่รันไทม์ขณะเริ่มต้น ดังนั้นโปรดทราบว่ารันไทม์ที่เริ่มต้นด้วยตนเองจะอนุญาตให้แก้ไขได้อย่างเต็มที่โดยไม่มีมาตรการด้านความปลอดภัย (การดำเนินการนี้ช่วยให้สามารถทดสอบ ART ได้)
หมายเหตุ: การดำเนินการนี้ใช้ไม่ได้กับแอปทั่วไป (รวมถึงเซิร์ฟเวอร์ระบบ) ในอุปกรณ์ แอปจะแยกออกมาจาก zygote ที่ทำงานอยู่ และกระบวนการ zygote ไม่ได้รับอนุญาตให้โหลดตัวแทน
หากต้องการแนบตัวแทนกับแอปที่ทำงานอยู่ ให้ใช้คำสั่งนี้
adb shell cmd activity attach-agent [process] /path/to/agent/libagent.so[=agent-options]
หากยังไม่ได้โหลดปลั๊กอิน JVMTI การแนบตัวแทนจะโหลดทั้งปลั๊กอินและคลังตัวแทน
ตัวแทนจะแนบอยู่กับแอปที่ทำงานอยู่ซึ่งทําเครื่องหมายเป็นแก้ไขข้อบกพร่องได้เท่านั้น (เป็นส่วนหนึ่งของไฟล์ Manifest ของแอป โดยตั้งค่าแอตทริบิวต์ android:debuggable
เป็น true
ในโหนดแอป) ทั้งคลาส ActivityManager
และ ART จะดำเนินการตรวจสอบก่อนที่จะอนุญาตให้แนบตัวแทน คลาส ActivityManager จะตรวจสอบข้อมูลแอปปัจจุบัน (ซึ่งมาจากข้อมูลคลาส PackageManager) เพื่อหาสถานะที่แก้ไขข้อบกพร่องได้ และรันไทม์จะตรวจสอบสถานะปัจจุบันซึ่งตั้งค่าไว้เมื่อเริ่มแอป
สถานที่ตั้งของตัวแทน
รันไทม์ต้องโหลดตัวแทนลงในกระบวนการปัจจุบันเพื่อให้ตัวแทนสามารถเชื่อมโยงและสื่อสารกับกระบวนการดังกล่าวได้โดยตรง ART เองไม่สนใจว่าตัวแทนจะมาจากตำแหน่งใด สตริงนี้ใช้สำหรับdlopen
call สิทธิ์ของระบบไฟล์และนโยบาย SELinux จะจำกัดการโหลดจริง
หากต้องการส่งตัวแทนที่แอปแก้ไขข้อบกพร่องได้ ให้ทําดังนี้
- ฝังตัวแทนในไดเรกทอรีไลบรารีของ APK ของแอป
- ใช้
run-as
เพื่อคัดลอกตัวแทนไปยังไดเรกทอรีข้อมูลของแอป
API
เพิ่มวิธีการต่อไปนี้ลงใน android.os.Debug
แล้ว
/** * Attach a library as a jvmti agent to the current runtime, with the given classloader * determining the library search path. * Note: agents may only be attached to debuggable apps. Otherwise, this function will * throw a SecurityException. * * @param library the library containing the agent. * @param options the options passed to the agent. * @param classLoader the classloader determining the library search path. * * @throws IOException if the agent could not be attached. * @throws a SecurityException if the app is not debuggable. */ public static void attachJvmtiAgent(@NonNull String library, @Nullable String options, @Nullable ClassLoader classLoader) throws IOException {
API อื่นๆ ของ Android
คำสั่ง attach-agent จะปรากฏต่อสาธารณะ คำสั่งนี้จะแนบตัวแทน JVMTI กับกระบวนการที่ทำงานอยู่
adb shell 'am attach-agent com.example.android.displayingbitmaps \'/data/data/com.example.android.displayingbitmaps/code_cache/libfieldnulls.so=Ljava/lang/Class;.name:Ljava/lang/String;\''
คําสั่ง am start -P
และ am
start-profiler/stop-profiler
คล้ายกับคําสั่ง attach-agent
JVMTI
ฟีเจอร์นี้จะแสดง JVMTI API ต่อตัวแทน (โค้ดเนทีฟ) ความสามารถที่สําคัญมีดังนี้
- การกําหนดชั้นเรียนใหม่
- การติดตามการจัดสรรออบเจ็กต์และการรวบรวมขยะ
- การดำเนินการซ้ำกับออบเจ็กต์ทั้งหมดในกอง โดยทำตามต้นไม้อ้างอิงของออบเจ็กต์
- การตรวจสอบสแต็กการเรียกใช้ Java
- ระงับ (และกลับมาดำเนินการต่อ) ชุดข้อความทั้งหมด
ความสามารถต่างๆ อาจพร้อมใช้งานใน Android เวอร์ชันต่างๆ
ความเข้ากันได้
ฟีเจอร์นี้ต้องใช้การรองรับรันไทม์หลักที่พร้อมใช้งานใน Android 8.0 ขึ้นไปเท่านั้น ผู้ผลิตอุปกรณ์ไม่จําเป็นต้องทําการเปลี่ยนแปลงใดๆ เพื่อติดตั้งใช้งานฟีเจอร์นี้ ซึ่งเป็นส่วนหนึ่งของ AOSP
การตรวจสอบความถูกต้อง
CTS จะทดสอบสิ่งต่อไปนี้ใน Android 8 ขึ้นไป
- ทดสอบว่าตัวแทนแนบกับแอปที่แก้ไขข้อบกพร่องได้ และแนบกับแอปที่แก้ไขข้อบกพร่องไม่ได้
- ทดสอบ API ของ JVMTI ทั้งหมดที่ติดตั้งใช้งาน
- ทดสอบว่าอินเทอร์เฟซไบนารีสําหรับตัวแทนมีความเสถียร
เราได้เพิ่มการทดสอบเพิ่มเติมลงใน Android 9 ขึ้นไป และรวมไว้ในการทดสอบ CTS สำหรับรุ่นเหล่านั้น