Skip to content

Commit

Permalink
WIP Add metadata #1519
Browse files Browse the repository at this point in the history
  • Loading branch information
pyricau committed Sep 11, 2019
1 parent d0b883c commit ef1dc9c
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 9 deletions.
Expand Up @@ -3,10 +3,12 @@ package leakcanary
import android.content.Intent
import leakcanary.LeakCanary.config
import leakcanary.internal.InternalLeakCanary
import shark.AndroidMetadataExtractor
import shark.AndroidObjectInspectors
import shark.AndroidReferenceMatchers
import shark.IgnoredReferenceMatcher
import shark.LibraryLeakReferenceMatcher
import shark.MetadataExtractor
import shark.ObjectInspector
import shark.ReferenceMatcher

Expand Down Expand Up @@ -91,6 +93,11 @@ object LeakCanary {
*/
val onHeapAnalyzedListener: OnHeapAnalyzedListener = DefaultOnHeapAnalyzedListener.create(),

/**
* TODO
*/
val metatadaExtractor: MetadataExtractor = AndroidMetadataExtractor,

/**
* Whether to compute the retained heap size, which is the total number of bytes in memory that
* would be reclaimed if the detected leaks didn't happen. This includes native memory
Expand Down
Expand Up @@ -59,10 +59,14 @@ internal class HeapAnalyzerService : ForegroundService(

val heapAnalysis =
heapAnalyzer.analyze(
heapDumpFile, config.referenceMatchers, config.computeRetainedHeapSize, config.objectInspectors,
heapDumpFile,
config.referenceMatchers,
config.computeRetainedHeapSize,
config.objectInspectors,
if (config.useExperimentalLeakFinders) config.objectInspectors else listOf(
ObjectInspectors.KEYED_WEAK_REFERENCE
)
),
config.metatadaExtractor
)

config.onHeapAnalyzedListener.onHeapAnalyzed(heapAnalysis)
Expand Down
Expand Up @@ -25,7 +25,6 @@ internal class LeaksDbHelper(context: Context) : SQLiteOpenHelper(
}

companion object {
// Last updated for next after 2.0-alpha-3
private const val VERSION = 16
private const val VERSION = 17
}
}
24 changes: 24 additions & 0 deletions shark-android/src/main/java/shark/AndroidMetadataExtractor.kt
@@ -0,0 +1,24 @@
package shark

object AndroidMetadataExtractor : MetadataExtractor {
override fun extractMetadata(graph: HeapGraph): Map<String, String> {
val build = AndroidBuildMirror.fromHeapGraph(graph)

val buildConfigClass = graph.findClassByName("com.squareup.leakcanary.core.BuildConfig")
val leakCanaryVersion =
buildConfigClass?.get("LIBRARY_VERSION")?.value?.readAsJavaString() ?: "Unknown"

val loadedApk = graph.findClassByName("android.app.LoadedApk")
?.instances?.firstOrNull()

val appPackageName =
loadedApk?.get("android.app.LoadedApk", "mPackageName")?.value?.readAsJavaString()
?: "Unknown"
return mapOf(
"Build.VERSION.SDK_INT" to build.sdkInt.toString(),
"Build.MANUFACTURER" to build.manufacturer,
"LeakCanary version" to leakCanaryVersion,
"App package name" to appPackageName
)
}
}
2 changes: 2 additions & 0 deletions shark/src/main/java/shark/HeapAnalysis.kt
Expand Up @@ -37,6 +37,7 @@ data class HeapAnalysisFailure(
* An exception wrapping the actual exception that was thrown.
*/
val exception: HeapAnalysisException

) : HeapAnalysis()

/**
Expand All @@ -46,6 +47,7 @@ data class HeapAnalysisSuccess(
override val heapDumpFile: File,
override val createdAtTimeMillis: Long,
override val analysisDurationMillis: Long,
val metadata: Map<String, String>,
/**
* The list of [ApplicationLeak] found in the heap dump by [HeapAnalyzer].
*/
Expand Down
7 changes: 6 additions & 1 deletion shark/src/main/java/shark/HeapAnalyzer.kt
Expand Up @@ -41,6 +41,7 @@ import shark.LeakTraceElement.Holder.THREAD
import shark.OnAnalysisProgressListener.Step.BUILDING_LEAK_TRACES
import shark.OnAnalysisProgressListener.Step.COMPUTING_NATIVE_RETAINED_SIZE
import shark.OnAnalysisProgressListener.Step.COMPUTING_RETAINED_SIZE
import shark.OnAnalysisProgressListener.Step.EXTRACTING_METADATA
import shark.OnAnalysisProgressListener.Step.FINDING_LEAKING_INSTANCES
import shark.OnAnalysisProgressListener.Step.PARSING_HEAP_DUMP
import shark.OnAnalysisProgressListener.Step.REPORTING_HEAP_ANALYSIS
Expand Down Expand Up @@ -82,6 +83,7 @@ class HeapAnalyzer constructor(
computeRetainedHeapSize: Boolean = false,
objectInspectors: List<ObjectInspector> = emptyList(),
leakFinders: List<ObjectInspector> = objectInspectors,
metadataExtractor: MetadataExtractor = MetadataExtractor.NO_OP,
proguardMapping: ProguardMapping? = null
): HeapAnalysis {
val analysisStartNanoTime = System.nanoTime()
Expand All @@ -101,13 +103,16 @@ class HeapAnalyzer constructor(
.use { hprof ->
val graph = HprofHeapGraph.indexHprof(hprof, proguardMapping)

listener.onAnalysisProgress(EXTRACTING_METADATA)
val metadata = metadataExtractor.extractMetadata(graph)

val findLeakInput = FindLeakInput(
graph, leakFinders, referenceMatchers, computeRetainedHeapSize, objectInspectors
)
val (applicationLeaks, libraryLeaks) = findLeakInput.findLeaks()
listener.onAnalysisProgress(REPORTING_HEAP_ANALYSIS)
return HeapAnalysisSuccess(
heapDumpFile, System.currentTimeMillis(), since(analysisStartNanoTime),
heapDumpFile, System.currentTimeMillis(), since(analysisStartNanoTime), metadata,
applicationLeaks, libraryLeaks
)
}
Expand Down
39 changes: 39 additions & 0 deletions shark/src/main/java/shark/MetadataExtractor.kt
@@ -0,0 +1,39 @@
package shark

import shark.MetadataExtractor.Companion.invoke
import shark.ObjectInspector.Companion.invoke

/**
* Extracts metadata from a hprof to be reported in [HeapAnalysisSuccess.metadata].
*
* You can create a [MetadataExtractor] from a lambda by calling [invoke].
*/
interface MetadataExtractor {
fun extractMetadata(graph: HeapGraph): Map<String, String>

companion object {

/**
* A no-op [MetadataExtractor]
*/
val NO_OP = MetadataExtractor { emptyMap() }

/**
* Utility function to create a [MetadataExtractor] from the passed in [block] lambda instead of
* using the anonymous `object : MetadataExtractor` syntax.
*
* Usage:
*
* ```kotlin
* val inspector = MetadataExtractor { graph ->
*
* }
* ```
*/
inline operator fun invoke(crossinline block: (HeapGraph) -> Map<String, String>): MetadataExtractor =
object : MetadataExtractor {
override fun extractMetadata(graph: HeapGraph): Map<String, String> = block(graph)
}
}

}
6 changes: 2 additions & 4 deletions shark/src/main/java/shark/OnAnalysisProgressListener.kt
Expand Up @@ -8,6 +8,7 @@ interface OnAnalysisProgressListener {
// These steps are defined in the order in which they occur.
enum class Step {
PARSING_HEAP_DUMP,
EXTRACTING_METADATA,
FINDING_LEAKING_INSTANCES,
FINDING_PATHS_TO_LEAKING_OBJECTS,
FINDING_DOMINATORS,
Expand All @@ -24,10 +25,7 @@ interface OnAnalysisProgressListener {
/**
* A no-op [OnAnalysisProgressListener]
*/
val NO_OP = object : OnAnalysisProgressListener {
override fun onAnalysisProgress(step: Step) {
}
}
val NO_OP = OnAnalysisProgressListener {}

/**
* Utility function to create a [OnAnalysisProgressListener] from the passed in [block] lambda
Expand Down

0 comments on commit ef1dc9c

Please sign in to comment.