1 建立AndroidStudio调试系统代码工程
1.1 建立工程时,无需编译整个系统代码。
1)只需要抽取调试的那几个java代码文件作为工程代码,引用或关联的系统jar包作为libs引用。
2)添加bootClasspath引用
3)可以删除android.sdk引用(根据需要与否)
ndk.dir=D\:\\AndroidSDK\\sdk\\ndk-bundle
sdk.dir=D\:\\AndroidSDK\\sdk
2、将1.1中编译的jar或apk或so替换到手机(debug版本)中,进行在线调试
2.1 选择正确的进程attach debug,一定要注意区分调试代码所在的系统进程,否则进入不了该断点。
Breakpoint at:
android.os.Process#killProcess
android.os.Process#killProcessQuiet
一运行就crash?Debug方式启动,然后AS attach debug
$ am start -D -W -n com.xxx/.yyy
$ am set-debug-app -w --persistent com.xxx
有native crash,产生tombstone日志,设置属性让debuggerd保留现场,然后 gdbclient.py -p PID
# setprop debug.debuggerd.wait_for_gdb true (7.0 8.0 9.0)
# setprop debug.db.uid 999999 (<= 6.0)
完整示例工程如下:
//================build.grade=============
apply plugin: 'java'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
def defaultEncoding = 'UTF-8'
sourceSets {
main {
java {
srcDirs "$ANDROID_SRC_ROOT/frameworks/base/core/java",
"$ANDROID_SRC_ROOT/frameworks/base/media/java"
}
}
}
def CORE_JAR = "/system/framework/core-all.jar" // for Android N+; subst '/system/framework/core-oj.jar:/system/framework/core-libart.jar'
// QCOM
def BOOTCLASSPATH="/system/framework/com.qualcomm.qti.camera.jar:/system/framework/QPerformance.jar:/system/framework/core-oj.jar" //...
def SYSTEMSERVERCLASSPATH="/system/framework/services.jar:/system/framework/ethernet-service.jar" //...
// MTK
def EXTRA_CLASSPATH="/system/framework/android.hardware.light-V2.0-java.jar" //...
def full_clspath = CORE_JAR + ":" + BOOTCLASSPATH + ":" + SYSTEMSERVERCLASSPATH + ":" + EXTRA_CLASSPATH
sysLibs = files(full_clspath.split(":").collect {
it.toString().replace("/system/framework", "qcomdev/sysLibs")
}).filter { it.exists() }
task fixModuleIml {
ext.imlFile = projectDir.absolutePath + '/' + project.name + '.iml'
inputs.file imlFile
outputs.file imlFile
try {
if (!file(imlFile).exists())
return
// Parse the existing iml file
def parse = new XmlParser().parse(imlFile)
def moduleComponent = parse.component.find { it.@name == 'NewModuleRootManager' }
// Check if it has already been fixed
def orderEntries = moduleComponent.orderEntry
// Determine the index of the jdk entry
def jdkOrderEntry = orderEntries.find { it.@type == 'jdk' || it.@type == 'inheritedJdk' }
if (jdkOrderEntry == null)
return
moduleComponent.children().remove(jdkOrderEntry)
moduleComponent.children().add(jdkOrderEntry)
// Write the fixed iml file
def printer = new XmlNodePrinter(new PrintWriter(new FileWriter(imlFile)))
printer.preserveWhitespace = true
printer.print(parse)
} catch (Exception e) {
e.printStackTrace()
}
}
compileJava {
options.encoding = defaultEncoding
def clspath = rootProject.ext.sysLibs.join(File.pathSeparator)
println "bootClasspath before => " + options.bootClasspath
options.bootClasspath = clspath
println "bootClasspath after => " + options.bootClasspath
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
implementation rootProject.ext.sysLibs
}