cumulated update

boot editor: support dtb in linux
lazybox: more commands
master
cfig 2 weeks ago
parent f18f99a009
commit fd57f24a14
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

@ -87,20 +87,24 @@ class DeviceTreeParser : IPackable {
//pull
"adb root".check_call()
"adb push tools/bin/dtc-android /data/vendor/dtc-android".check_call()
val hw = "adb shell getprop ro.hardware".check_output()
log.info("ro.hardware=$hw")
"adb shell /data/vendor/dtc-android -I fs /proc/device-tree -o /data/vendor/file.to.pull".check_call()
var hw = "linux"
if ("adb shell which getprop".check_output().isBlank()) { //linux
"adb push tools/bin/dtc-linux /data/vendor/dtc".check_call()
} else { //android
"adb push tools/bin/dtc-android /data/vendor/dtc".check_call()
hw = "adb shell getprop ro.hardware".check_output()
log.info("ro.hardware=$hw")
}
"adb shell /data/vendor/dtc -I fs /proc/device-tree -o /data/vendor/file.to.pull".check_call()
"adb pull /data/vendor/file.to.pull $workDir$hw.dts".check_call()
"adb shell /data/vendor/dtc-android -I fs -O dtb /proc/device-tree -o /data/vendor/file.to.pull".check_call()
"adb shell /data/vendor/dtc -I fs -O dtb /proc/device-tree -o /data/vendor/file.to.pull".check_call()
"adb pull /data/vendor/file.to.pull $hw.dtb".check_call()
"adb shell rm /data/vendor/file.to.pull".check_call()
"adb shell rm /data/vendor/dtc-android".check_call()
"adb shell rm /data/vendor/dtc".check_call()
if (fileName != "$hw.dtb") {
File(fileName).delete()
log.warn("deleting intermediate dtb file: $fileName")
}
//print summary
val prints: MutableList<Pair<String, String>> = mutableListOf()
prints.add(Pair("source", "/proc/device-tree"))

@ -1,6 +1,7 @@
package cfig.lazybox
import cfig.lazybox.staging.DiffCI
import cfig.lazybox.staging.Perfetto
import cfig.lazybox.staging.RepoWorker
import cfig.lazybox.sysinfo.BootChart
import cfig.lazybox.sysinfo.CpuInfo
@ -32,6 +33,7 @@ fun main(args: Array<String>) {
println("diffci : find changelist files from CI server based on date and time ranges")
println("repo_lfs : pull LFS files from Git repositories managed by 'repo'")
println("repo_unshallow: unshallow Git repositories managed by 'repo'")
println("perfetto : generate a Perfetto configuration file")
exitProcess(0)
}
if (args[0] == "cpuinfo") {
@ -111,4 +113,7 @@ fun main(args: Array<String>) {
if (args[0] == "repo_unshallow") {
RepoWorker().unshallowRepo(args.drop(1).toTypedArray())
}
if (args[0] == "perfetto") {
Perfetto().run(args.drop(1).toTypedArray())
}
}

@ -0,0 +1,280 @@
package cfig.lazybox.staging
import java.io.File
import org.slf4j.LoggerFactory
class Perfetto {
private val log = LoggerFactory.getLogger(Perfetto::class.java.simpleName)
/**
* Main entry method to generate the configuration file.
*/
fun run(args: Array<String>) {
val options = args.toSet()
// Check for help flags
if ("-h" in options || "--help" in options) {
printUsage()
return
}
log.info("Running Perfetto configuration generation with arguments: ${args.joinToString(", ")}")
val outputFileName = "pftrace.cfg"
val finalConfig = generatePerfettoConfig(options)
try {
File(outputFileName).writeText(finalConfig)
log.info("Successfully wrote Perfetto configuration to '$outputFileName'.")
log.info("Options used: ${options.ifEmpty { setOf("default") }}")
if ("+boot" in options) {
val adbCommands = """
--------------------------------------------------------------------
Boot trace config enabled. To capture a boot trace, run these commands:
[enable tracing]
adb root
adb push pftrace.cfg /data/misc/perfetto-configs/boottrace.pbtxt
adb shell setprop persist.debug.perfetto.boottrace 1
[pull trace result after reboot]
adb pull /data/misc/perfetto-traces/boottrace.perfetto-trace
--------------------------------------------------------------------
""".trimIndent()
println(adbCommands)
}
} catch (e: Exception) {
log.error("Failed to write to file '$outputFileName'. Reason: ${e.message}")
}
}
/**
* Prints the help/usage message for the script.
*/
private fun printUsage() {
val usage = """
Usage: kotlin Perfetto.main.kts [options...]
Generates a pftrace.cfg file for Perfetto tracing based on specified options.
The output file is named 'pftrace.cfg'.
Options:
-h, --help Show this help message and exit.
+power Include ftrace power events and Android power rail data sources.
+atrace Include a wide range of atrace categories for detailed app tracing.
+lmk Include Low Memory Killer (LMK) and OOM score ftrace events.
+cpu_usage Include detailed CPU time and process fork count statistics.
+logcat Include all Android logcat buffers in the trace.
+sf Include SurfaceFlinger frame timeline data.
+boot Enable boot tracing. After generating the config, this prints the
necessary adb commands to set up the trace for the next boot.
""".trimIndent()
println(usage)
}
/**
* Builds the Perfetto configuration string based on the provided options.
*/
fun generatePerfettoConfig(options: Set<String> = emptySet()): String {
log.info("Generating Perfetto configuration with options: $options")
val configBuilder = StringBuilder()
// --- 1. Base Config: Buffers ---
log.info("Adding buffers")
configBuilder.append(
"""
# === Buffers ===
buffers: {
size_kb: 63488
fill_policy: DISCARD
}
buffers: {
size_kb: 2048
fill_policy: DISCARD
}
""".trimIndent()
)
// --- 2. Base Config: Core Data Sources (excluding sys_stats) ---
log.info("Adding core data sources")
configBuilder.append(
"""
# === Base Data Sources ===
data_sources: {
config {
name: "linux.process_stats"
process_stats_config {
scan_all_processes_on_start: true
proc_stats_poll_ms: 250
}
}
}
data_sources: {
config {
name: "android.packages_list"
target_buffer: 1
}
}
""".trimIndent()
)
// --- 3. Dynamic and Optional Config ---
// Dynamically build linux.sys_stats config
val sysStatsLines = mutableListOf(
"meminfo_period_ms: 250",
"vmstat_period_ms: 250",
"cpufreq_period_ms: 250"
)
if ("+cpu_usage" in options) {
log.info("Adding data sources for: +cpu_usage")
sysStatsLines.add("stat_period_ms: 250")
sysStatsLines.add("stat_counters: STAT_CPU_TIMES")
sysStatsLines.add("stat_counters: STAT_FORK_COUNT")
}
log.info("Appending sys_stats data source to config")
configBuilder.append("\n\n# === System-wide Stats ===")
configBuilder.append(
"""
data_sources: {
config {
name: "linux.sys_stats"
sys_stats_config {
""".trimIndent()
)
sysStatsLines.forEach { configBuilder.append("\n $it") }
configBuilder.append(
"""
}
}
}
""".trimIndent()
)
// Dynamically build ftrace config
val ftraceEvents = mutableListOf<String>()
val atraceCategories = mutableListOf<String>()
val atraceApps = mutableListOf<String>()
if ("+power" in options) {
ftraceEvents.add("power/*")
}
if ("+atrace" in options) {
ftraceEvents.add("ftrace/print")
atraceCategories.addAll(
listOf(
"adb", "aidl", "am", "audio", "binder_driver", "binder_lock",
"bionic", "camera", "dalvik", "database", "gfx", "hal",
"input", "network", "nnapi", "pm", "power", "res", "rro",
"rs", "sm", "ss", "vibrator", "video", "view", "webview", "wm"
)
)
}
if ("+lmk" in options) {
log.info("Adding data sources for: +lmk")
ftraceEvents.add("lowmemorykiller/lowmemory_kill")
ftraceEvents.add("oom/oom_score_adj_update")
atraceApps.add("lmkd")
}
if (ftraceEvents.isNotEmpty() || atraceCategories.isNotEmpty() || atraceApps.isNotEmpty()) {
log.info("Appending ftrace data source to config")
configBuilder.append("\n\n# === Optional Ftrace/Atrace Tracing ===")
configBuilder.append(
"""
data_sources: {
config {
name: "linux.ftrace"
ftrace_config {
""".trimIndent()
)
ftraceEvents.forEach { configBuilder.append("\n ftrace_events: \"$it\"") }
atraceCategories.forEach { configBuilder.append("\n atrace_categories: \"$it\"") }
atraceApps.forEach { configBuilder.append("\n atrace_apps: \"$it\"") }
configBuilder.append(
"""
}
}
}
""".trimIndent()
)
}
if ("+power" in options) {
log.info("Adding data sources for: android.power")
configBuilder.append(
"""
# === Optional Android Power Tracing ===
data_sources: {
config {
name: "android.power"
android_power_config {
battery_poll_ms: 250
battery_counters: BATTERY_COUNTER_CAPACITY_PERCENT
battery_counters: BATTERY_COUNTER_CHARGE
battery_counters: BATTERY_COUNTER_CURRENT
collect_power_rails: true
}
}
}
""".trimIndent()
)
}
if ("+logcat" in options) {
log.info("Adding data sources for: +logcat")
configBuilder.append(
"""
# === Optional Logcat Tracing ===
data_sources {
config {
name: "android.log"
android_log_config {
log_ids: LID_CRASH
log_ids: LID_DEFAULT
log_ids: LID_EVENTS
log_ids: LID_KERNEL
log_ids: LID_RADIO
log_ids: LID_SECURITY
log_ids: LID_STATS
log_ids: LID_SYSTEM
}
}
}
""".trimIndent()
)
}
// (REVISED) Add SurfaceFlinger data source if option is present
if ("+sf" in options) {
log.info("Adding data sources for: +sf")
configBuilder.append(
"""
# === Optional SurfaceFlinger Tracing ===
data_sources {
config {
name: "android.surfaceflinger.frametimeline"
}
}
""".trimIndent()
)
}
// --- 4. Trace Duration ---
log.info("Adding trace duration")
configBuilder.append(
"""
# === Trace Duration ===
# The total duration of the trace in milliseconds.
duration_ms: 15000
""".trimIndent()
)
return configBuilder.toString()
}
}

@ -51,8 +51,7 @@ class RepoWorker {
gitRepositories.forEach { repoDir ->
val relativePath = repoDir.toRelativeString(startDir).ifEmpty { "." }
if (checker(repoDir)) {
log.info("Checking [$relativePath]...")
log.info(" -> ✅ $checkerName")
log.info("Checking [$relativePath]... ✅ $checkerName")
ret.add(repoDir)
} else {
//log.info("Checking [$relativePath]...")

Binary file not shown.
Loading…
Cancel
Save