memorydetective 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +50 -1
  2. package/README.md +75 -9
  3. package/USAGE.md +27 -4
  4. package/dist/cli.js +106 -3
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.js +42 -22
  7. package/dist/index.js.map +1 -1
  8. package/dist/parsers/referenceTree.d.ts +73 -0
  9. package/dist/parsers/referenceTree.js +145 -0
  10. package/dist/parsers/referenceTree.js.map +1 -0
  11. package/dist/runtime/axe.js +6 -1
  12. package/dist/runtime/axe.js.map +1 -1
  13. package/dist/runtime/exec.d.ts +30 -0
  14. package/dist/runtime/exec.js +30 -3
  15. package/dist/runtime/exec.js.map +1 -1
  16. package/dist/runtime/fixTemplates.js +67 -0
  17. package/dist/runtime/fixTemplates.js.map +1 -1
  18. package/dist/runtime/leakReport.d.ts +62 -0
  19. package/dist/runtime/leakReport.js +138 -0
  20. package/dist/runtime/leakReport.js.map +1 -0
  21. package/dist/runtime/platformCheck.d.ts +54 -0
  22. package/dist/runtime/platformCheck.js +94 -0
  23. package/dist/runtime/platformCheck.js.map +1 -0
  24. package/dist/runtime/redact.d.ts +66 -0
  25. package/dist/runtime/redact.js +146 -0
  26. package/dist/runtime/redact.js.map +1 -0
  27. package/dist/runtime/responseFormatter.d.ts +55 -0
  28. package/dist/runtime/responseFormatter.js +200 -0
  29. package/dist/runtime/responseFormatter.js.map +1 -0
  30. package/dist/runtime/securityFlags.d.ts +74 -0
  31. package/dist/runtime/securityFlags.js +90 -0
  32. package/dist/runtime/securityFlags.js.map +1 -0
  33. package/dist/runtime/staticAnalysisHints.js +14 -1
  34. package/dist/runtime/staticAnalysisHints.js.map +1 -1
  35. package/dist/templates/leak-report.html +39 -0
  36. package/dist/templates/templates/leak-report.html +39 -0
  37. package/dist/tools/analyzeAbandonedMemory.d.ts +140 -0
  38. package/dist/tools/analyzeAbandonedMemory.js +287 -0
  39. package/dist/tools/analyzeAbandonedMemory.js.map +1 -0
  40. package/dist/tools/analyzeAllocations.d.ts +11 -2
  41. package/dist/tools/analyzeAllocations.js +4 -0
  42. package/dist/tools/analyzeAllocations.js.map +1 -1
  43. package/dist/tools/analyzeAnimationHitches.d.ts +32 -2
  44. package/dist/tools/analyzeAnimationHitches.js +25 -4
  45. package/dist/tools/analyzeAnimationHitches.js.map +1 -1
  46. package/dist/tools/analyzeAppLaunch.d.ts +3 -0
  47. package/dist/tools/analyzeAppLaunch.js +2 -0
  48. package/dist/tools/analyzeAppLaunch.js.map +1 -1
  49. package/dist/tools/analyzeHangs.d.ts +78 -2
  50. package/dist/tools/analyzeHangs.js +117 -4
  51. package/dist/tools/analyzeHangs.js.map +1 -1
  52. package/dist/tools/analyzeMemgraph.d.ts +21 -1
  53. package/dist/tools/analyzeMemgraph.js +52 -2
  54. package/dist/tools/analyzeMemgraph.js.map +1 -1
  55. package/dist/tools/analyzeTimeProfile.d.ts +11 -1
  56. package/dist/tools/analyzeTimeProfile.js +5 -0
  57. package/dist/tools/analyzeTimeProfile.js.map +1 -1
  58. package/dist/tools/bootAndLaunchForLeakInvestigation.d.ts +18 -9
  59. package/dist/tools/bootAndLaunchForLeakInvestigation.js +27 -0
  60. package/dist/tools/bootAndLaunchForLeakInvestigation.js.map +1 -1
  61. package/dist/tools/captureMemgraph.d.ts +22 -4
  62. package/dist/tools/captureMemgraph.js +42 -9
  63. package/dist/tools/captureMemgraph.js.map +1 -1
  64. package/dist/tools/captureScenarioState.d.ts +12 -4
  65. package/dist/tools/captureScenarioState.js +4 -0
  66. package/dist/tools/captureScenarioState.js.map +1 -1
  67. package/dist/tools/classifyCycle.js +77 -0
  68. package/dist/tools/classifyCycle.js.map +1 -1
  69. package/dist/tools/cleanupTraces.d.ts +87 -0
  70. package/dist/tools/cleanupTraces.js +232 -0
  71. package/dist/tools/cleanupTraces.js.map +1 -0
  72. package/dist/tools/compareTracesByPattern.d.ts +2 -2
  73. package/dist/tools/detectLeaksInXCTest.d.ts +116 -0
  74. package/dist/tools/detectLeaksInXCTest.js +311 -0
  75. package/dist/tools/detectLeaksInXCTest.js.map +1 -0
  76. package/dist/tools/detectLeaksInXCUITest.d.ts +8 -3
  77. package/dist/tools/detectLeaksInXCUITest.js +30 -4
  78. package/dist/tools/detectLeaksInXCUITest.js.map +1 -1
  79. package/dist/tools/diffMemgraphs.d.ts +5 -2
  80. package/dist/tools/diffMemgraphs.js +2 -0
  81. package/dist/tools/diffMemgraphs.js.map +1 -1
  82. package/dist/tools/findCycles.d.ts +1 -1
  83. package/dist/tools/recordTimeProfile.d.ts +29 -9
  84. package/dist/tools/recordTimeProfile.js +70 -7
  85. package/dist/tools/recordTimeProfile.js.map +1 -1
  86. package/dist/tools/renderCycleGraph.d.ts +1 -1
  87. package/dist/tools/verifyFix.d.ts +2 -2
  88. package/dist/types.d.ts +24 -1
  89. package/package.json +3 -3
@@ -1,16 +1,38 @@
1
1
  import { z } from "zod";
2
+ import type { DataStatus } from "../types.js";
2
3
  export declare const analyzeAnimationHitchesSchema: z.ZodObject<{
3
4
  tracePath: z.ZodString;
4
5
  topN: z.ZodDefault<z.ZodNumber>;
5
6
  minDurationMs: z.ZodDefault<z.ZodNumber>;
7
+ timeRangeMs: z.ZodOptional<z.ZodObject<{
8
+ startMs: z.ZodNumber;
9
+ endMs: z.ZodNumber;
10
+ }, "strip", z.ZodTypeAny, {
11
+ startMs: number;
12
+ endMs: number;
13
+ }, {
14
+ startMs: number;
15
+ endMs: number;
16
+ }>>;
17
+ outputFormat: z.ZodOptional<z.ZodEnum<["markdown", "json", "both"]>>;
6
18
  }, "strip", z.ZodTypeAny, {
7
- topN: number;
8
19
  tracePath: string;
20
+ topN: number;
9
21
  minDurationMs: number;
22
+ outputFormat?: "markdown" | "json" | "both" | undefined;
23
+ timeRangeMs?: {
24
+ startMs: number;
25
+ endMs: number;
26
+ } | undefined;
10
27
  }, {
11
28
  tracePath: string;
29
+ outputFormat?: "markdown" | "json" | "both" | undefined;
12
30
  topN?: number | undefined;
13
31
  minDurationMs?: number | undefined;
32
+ timeRangeMs?: {
33
+ startMs: number;
34
+ endMs: number;
35
+ } | undefined;
14
36
  }>;
15
37
  export type AnalyzeAnimationHitchesInput = z.infer<typeof analyzeAnimationHitchesSchema>;
16
38
  export interface HitchEntry {
@@ -37,7 +59,15 @@ export interface AnalyzeAnimationHitchesResult {
37
59
  byType: Record<string, number>;
38
60
  top: HitchEntry[];
39
61
  diagnosis: string;
62
+ /**
63
+ * Disambiguates empty arrays into "no data in the trace" vs "trace could
64
+ * not be exported" vs "data was exported partially". See {@link DataStatus}.
65
+ */
66
+ status: DataStatus;
40
67
  }
41
68
  /** Pure: turn parsed XML into the analyzed result. */
42
- export declare function analyzeAnimationHitchesFromXml(xml: string, tracePath: string, topN?: number, minDurationMs?: number): AnalyzeAnimationHitchesResult;
69
+ export declare function analyzeAnimationHitchesFromXml(xml: string, tracePath: string, topN?: number, minDurationMs?: number, timeRangeMs?: {
70
+ startMs: number;
71
+ endMs: number;
72
+ }): AnalyzeAnimationHitchesResult;
43
73
  export declare function analyzeAnimationHitches(input: AnalyzeAnimationHitchesInput): Promise<AnalyzeAnimationHitchesResult>;
@@ -3,6 +3,7 @@ import { existsSync } from "node:fs";
3
3
  import { resolve as resolvePath } from "node:path";
4
4
  import { runCommand } from "../runtime/exec.js";
5
5
  import { parseXctraceXml, asNumber, asFormatted, } from "../parsers/xctraceXml.js";
6
+ import { outputFormatField } from "../runtime/responseFormatter.js";
6
7
  export const analyzeAnimationHitchesSchema = z.object({
7
8
  tracePath: z
8
9
  .string()
@@ -18,11 +19,19 @@ export const analyzeAnimationHitchesSchema = z.object({
18
19
  .number()
19
20
  .nonnegative()
20
21
  .default(0)
21
- .describe("Filter out hitches shorter than this duration in milliseconds. Apple categorizes hitches >100ms as user-perceptible pass 100 to focus on those."),
22
+ .describe("Filter out hitches shorter than this duration in milliseconds. Apple categorizes hitches >100ms as user-perceptible, pass 100 to focus on those."),
23
+ timeRangeMs: z
24
+ .object({
25
+ startMs: z.number().nonnegative(),
26
+ endMs: z.number().nonnegative(),
27
+ })
28
+ .optional()
29
+ .describe("Optional time-window filter. Only hitches whose `startNs` falls within `[startMs, endMs]` (milliseconds since recording start) are included. Use this to answer 'what hitches happened during this 5-second user-visible jank window?' without re-recording."),
30
+ outputFormat: outputFormatField,
22
31
  });
23
32
  const PERCEPTIBLE_MS = 100;
24
33
  /** Pure: turn parsed XML into the analyzed result. */
25
- export function analyzeAnimationHitchesFromXml(xml, tracePath, topN = 10, minDurationMs = 0) {
34
+ export function analyzeAnimationHitchesFromXml(xml, tracePath, topN = 10, minDurationMs = 0, timeRangeMs) {
26
35
  const tables = parseXctraceXml(xml);
27
36
  const table = tables.find((t) => t.schema === "animation-hitches");
28
37
  if (!table) {
@@ -39,6 +48,7 @@ export function analyzeAnimationHitchesFromXml(xml, tracePath, topN = 10, minDur
39
48
  byType: {},
40
49
  top: [],
41
50
  diagnosis: "No animation-hitches table found in the trace.",
51
+ status: "not_present",
42
52
  };
43
53
  }
44
54
  const all = [];
@@ -57,7 +67,17 @@ export function analyzeAnimationHitchesFromXml(xml, tracePath, topN = 10, minDur
57
67
  source: asFormatted(row.source),
58
68
  });
59
69
  }
60
- const filtered = all.filter((e) => e.durationMs >= minDurationMs);
70
+ const filtered = all.filter((e) => {
71
+ if (e.durationMs < minDurationMs)
72
+ return false;
73
+ if (timeRangeMs) {
74
+ const startMs = e.startNs / 1_000_000;
75
+ if (startMs < timeRangeMs.startMs || startMs > timeRangeMs.endMs) {
76
+ return false;
77
+ }
78
+ }
79
+ return true;
80
+ });
61
81
  const byType = {};
62
82
  for (const e of filtered) {
63
83
  byType[e.hitchType] = (byType[e.hitchType] ?? 0) + 1;
@@ -83,6 +103,7 @@ export function analyzeAnimationHitchesFromXml(xml, tracePath, topN = 10, minDur
83
103
  byType,
84
104
  top,
85
105
  diagnosis,
106
+ status: "available",
86
107
  };
87
108
  }
88
109
  function buildDiagnosis(rows, perceptible, longestMs, averageMs) {
@@ -116,6 +137,6 @@ export async function analyzeAnimationHitches(input) {
116
137
  if (result.code !== 0) {
117
138
  throw new Error(`xctrace export failed (code ${result.code}): ${result.stderr || result.stdout}`);
118
139
  }
119
- return analyzeAnimationHitchesFromXml(result.stdout, tracePath, input.topN ?? 10, input.minDurationMs ?? 0);
140
+ return analyzeAnimationHitchesFromXml(result.stdout, tracePath, input.topN ?? 10, input.minDurationMs ?? 0, input.timeRangeMs);
120
141
  }
121
142
  //# sourceMappingURL=analyzeAnimationHitches.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyzeAnimationHitches.js","sourceRoot":"","sources":["../../src/tools/analyzeAnimationHitches.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzeAnimationHitches.js","sourceRoot":"","sources":["../../src/tools/analyzeAnimationHitches.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,13 @@
1
1
  import { z } from "zod";
2
2
  export declare const analyzeAppLaunchSchema: z.ZodObject<{
3
3
  tracePath: z.ZodString;
4
+ outputFormat: z.ZodOptional<z.ZodEnum<["markdown", "json", "both"]>>;
4
5
  }, "strip", z.ZodTypeAny, {
5
6
  tracePath: string;
7
+ outputFormat?: "markdown" | "json" | "both" | undefined;
6
8
  }, {
7
9
  tracePath: string;
10
+ outputFormat?: "markdown" | "json" | "both" | undefined;
8
11
  }>;
9
12
  export type AnalyzeAppLaunchInput = z.infer<typeof analyzeAppLaunchSchema>;
10
13
  export interface PhaseEntry {
@@ -3,11 +3,13 @@ import { existsSync } from "node:fs";
3
3
  import { resolve as resolvePath } from "node:path";
4
4
  import { runCommand } from "../runtime/exec.js";
5
5
  import { parseXctraceXml, asNumber, asFormatted, } from "../parsers/xctraceXml.js";
6
+ import { outputFormatField } from "../runtime/responseFormatter.js";
6
7
  export const analyzeAppLaunchSchema = z.object({
7
8
  tracePath: z
8
9
  .string()
9
10
  .min(1)
10
11
  .describe("Absolute path to a `.trace` bundle recorded with the App Launch template (`xcrun xctrace record --template 'App Launch' --launch <bundleId>`)."),
12
+ outputFormat: outputFormatField,
11
13
  });
12
14
  /** Phases Apple breaks app launch into, ordered by occurrence. */
13
15
  const PHASE_ORDER = [
@@ -1 +1 @@
1
- {"version":3,"file":"analyzeAppLaunch.js","sourceRoot":"","sources":["../../src/tools/analyzeAppLaunch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzeAppLaunch.js","sourceRoot":"","sources":["../../src/tools/analyzeAppLaunch.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,82 @@
1
1
  import { z } from "zod";
2
+ import type { DataStatus } from "../types.js";
2
3
  export declare const analyzeHangsSchema: z.ZodObject<{
3
4
  tracePath: z.ZodString;
4
5
  topN: z.ZodDefault<z.ZodNumber>;
5
6
  minDurationMs: z.ZodDefault<z.ZodNumber>;
7
+ timeRangeMs: z.ZodOptional<z.ZodObject<{
8
+ startMs: z.ZodNumber;
9
+ endMs: z.ZodNumber;
10
+ }, "strip", z.ZodTypeAny, {
11
+ startMs: number;
12
+ endMs: number;
13
+ }, {
14
+ startMs: number;
15
+ endMs: number;
16
+ }>>;
17
+ topFramesByHangStartNs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
18
+ outputFormat: z.ZodOptional<z.ZodEnum<["markdown", "json", "both"]>>;
6
19
  }, "strip", z.ZodTypeAny, {
7
- topN: number;
8
20
  tracePath: string;
21
+ topN: number;
9
22
  minDurationMs: number;
23
+ outputFormat?: "markdown" | "json" | "both" | undefined;
24
+ timeRangeMs?: {
25
+ startMs: number;
26
+ endMs: number;
27
+ } | undefined;
28
+ topFramesByHangStartNs?: Record<string, string> | undefined;
10
29
  }, {
11
30
  tracePath: string;
31
+ outputFormat?: "markdown" | "json" | "both" | undefined;
12
32
  topN?: number | undefined;
13
33
  minDurationMs?: number | undefined;
34
+ timeRangeMs?: {
35
+ startMs: number;
36
+ endMs: number;
37
+ } | undefined;
38
+ topFramesByHangStartNs?: Record<string, string> | undefined;
14
39
  }>;
15
40
  export type AnalyzeHangsInput = z.infer<typeof analyzeHangsSchema>;
41
+ /**
42
+ * Catalog of main-thread-violation signatures. Each entry classifies a
43
+ * top-frame symbol pattern into one of four kinds that map onto the most
44
+ * common iOS user-perceived freezes:
45
+ *
46
+ * - `sync-io`: a blocking POSIX read/write or Foundation file API the
47
+ * runtime cannot async away from the main queue.
48
+ * - `db-lock`: SQLite mutex acquisition (the underlying primitive for
49
+ * Core Data, GRDB, and most Swift ORMs).
50
+ * - `network`: a blocking Network.framework/NSURLConnection sync call.
51
+ * - `lock-contention`: pthread/os_unfair_lock acquisition on the main
52
+ * thread, which serializes us against another thread.
53
+ *
54
+ * The matchers are case-sensitive substring checks. They deliberately
55
+ * stay close to the symbol name DebugSwift's Thread Checker flags so the
56
+ * coverage gap between the on-device tool and the offline catalog stays
57
+ * small. Adding new symbols later is a one-line append.
58
+ */
59
+ export type MainThreadViolationKind = "sync-io" | "db-lock" | "network" | "lock-contention";
60
+ export interface MainThreadViolation {
61
+ kind: MainThreadViolationKind;
62
+ topFrame: string;
63
+ samples: number;
64
+ }
65
+ /**
66
+ * Pure: classify a top-frame symbol into a `MainThreadViolation`. Returns
67
+ * `null` when nothing in the catalog matches. The `samples` count comes
68
+ * from the caller; with only a top-frame string available we set it to 1.
69
+ *
70
+ * Multiple signatures can match a single frame (e.g. a sync I/O call that
71
+ * also holds an unfair lock). We return the FIRST match in catalog order,
72
+ * which puts more user-actionable categories ahead of generic locks.
73
+ */
74
+ export declare function classifyHangFrame(topFrame: string, samples?: number): MainThreadViolation | null;
75
+ /** Stable key used to correlate the supplemental `topFramesByHangStartNs`
76
+ * map. Hang startNs values are nanoseconds (integers when xctrace exports
77
+ * them cleanly), so the key is just `String(startNs)`. Centralized so
78
+ * callers building the map use the same convention. */
79
+ export declare function hangFrameMapKey(startNs: number): string;
16
80
  export interface HangEntry {
17
81
  startNs: number;
18
82
  startFmt: string;
@@ -20,6 +84,10 @@ export interface HangEntry {
20
84
  durationMs: number;
21
85
  durationFmt: string;
22
86
  hangType: string;
87
+ /** Main-thread violations detected from the supplemental top-frame map.
88
+ * Empty array when the caller provided a frame but no signature matched;
89
+ * undefined when no frame was provided for this hang at all. */
90
+ mainThreadViolations?: MainThreadViolation[];
23
91
  }
24
92
  export interface AnalyzeHangsResult {
25
93
  ok: boolean;
@@ -35,7 +103,15 @@ export interface AnalyzeHangsResult {
35
103
  /** Filtered + sorted hangs, capped to topN. */
36
104
  top: HangEntry[];
37
105
  diagnosis: string;
106
+ /**
107
+ * Disambiguates empty arrays into "no data in the trace" vs "trace could
108
+ * not be exported" vs "data was exported partially". See {@link DataStatus}.
109
+ */
110
+ status: DataStatus;
38
111
  }
39
112
  /** Pure: turn parsed XML rows into our analyzed result. */
40
- export declare function analyzeHangsFromXml(xml: string, tracePath: string, topN?: number, minDurationMs?: number): AnalyzeHangsResult;
113
+ export declare function analyzeHangsFromXml(xml: string, tracePath: string, topN?: number, minDurationMs?: number, timeRangeMs?: {
114
+ startMs: number;
115
+ endMs: number;
116
+ }, topFramesByHangStartNs?: Readonly<Record<string, string>>): AnalyzeHangsResult;
41
117
  export declare function analyzeHangs(input: AnalyzeHangsInput): Promise<AnalyzeHangsResult>;
@@ -3,6 +3,7 @@ import { existsSync } from "node:fs";
3
3
  import { resolve as resolvePath } from "node:path";
4
4
  import { runCommand } from "../runtime/exec.js";
5
5
  import { parseXctraceXml, asNumber, asFormatted, } from "../parsers/xctraceXml.js";
6
+ import { outputFormatField } from "../runtime/responseFormatter.js";
6
7
  export const analyzeHangsSchema = z.object({
7
8
  tracePath: z
8
9
  .string()
@@ -18,10 +19,97 @@ export const analyzeHangsSchema = z.object({
18
19
  .number()
19
20
  .nonnegative()
20
21
  .default(0)
21
- .describe("Filter out hangs shorter than this duration in milliseconds (default 0 include all). Use 250 to focus on \"real\" hangs only."),
22
+ .describe("Filter out hangs shorter than this duration in milliseconds (default 0, include all). Use 250 to focus on 'real' hangs only."),
23
+ timeRangeMs: z
24
+ .object({
25
+ startMs: z.number().nonnegative(),
26
+ endMs: z.number().nonnegative(),
27
+ })
28
+ .optional()
29
+ .describe("Optional time-window filter. Only hangs whose `startNs` falls within `[startMs, endMs]` (milliseconds since recording start) are included. Use this to answer 'what hangs happened between t=2s and t=7s?' without re-recording."),
30
+ topFramesByHangStartNs: z
31
+ .record(z.string(), z.string())
32
+ .optional()
33
+ .describe("Optional supplemental map from a hang's `startNs` (as a string) to the top frame seen during that hang. When provided, each matching hang in `top[]` is enriched with `mainThreadViolations[]` that catalog the kind of work happening on the main thread (sync-io, db-lock, network, lock-contention). Typical pipeline: call `analyzeTimeProfile` separately on the same `.trace`, correlate samples to hang windows by timestamp, then re-call `analyzeHangs` with the resulting map. Omit to skip the enrichment."),
34
+ outputFormat: outputFormatField,
22
35
  });
36
+ const MAIN_THREAD_VIOLATION_SIGNATURES = [
37
+ // sync-io: POSIX read/write and Foundation/NSData blocking APIs.
38
+ // Foundation often calls through to the libsystem symbols below, but
39
+ // dSYM symbolication can land on either, so match both.
40
+ {
41
+ kind: "sync-io",
42
+ matches: (f) => /\b(read|pread|readv|write|pwrite|writev|fsync|fdatasync|aio_read|aio_write)\b/.test(f) ||
43
+ f.includes("Data initWithContentsOfFile") ||
44
+ f.includes("NSData _initWithContentsOfURL") ||
45
+ f.includes("FileHandle readDataOfLength") ||
46
+ f.includes("FileManager createFileAtPath") ||
47
+ f.includes("FileManager removeItem"),
48
+ },
49
+ // db-lock: SQLite mutex acquisition. Triggers under Core Data, GRDB,
50
+ // SQLite.swift, FMDB - any client that funnels through libsqlite3.
51
+ {
52
+ kind: "db-lock",
53
+ matches: (f) => f.includes("sqlite3_step") ||
54
+ f.includes("sqlite3_prepare") ||
55
+ f.includes("sqlite3_mutex_enter") ||
56
+ f.includes("sqlite3LockAndPrepare") ||
57
+ f.includes("pagerSharedLock") ||
58
+ f.includes("NSPersistentStoreCoordinator lock") ||
59
+ f.includes("NSManagedObjectContext save"),
60
+ },
61
+ // network: blocking Network.framework / legacy NSURLConnection sync
62
+ // call, or +[NSURLConnection sendSynchronousRequest:returningResponse:].
63
+ {
64
+ kind: "network",
65
+ matches: (f) => f.includes("sendSynchronousRequest") ||
66
+ f.includes("NSURLConnection sendSynchronousRequest") ||
67
+ f.includes("URLSession dataTaskWithRequest") ||
68
+ // CFNetwork sync path.
69
+ f.includes("CFReadStreamRead") ||
70
+ // Network.framework sync wait.
71
+ /\bnw_connection_(start|wait)\b/.test(f),
72
+ },
73
+ // lock-contention: pthread / os_unfair_lock acquisition on the main
74
+ // thread that blocks waiting for another thread.
75
+ {
76
+ kind: "lock-contention",
77
+ matches: (f) => f.includes("pthread_mutex_lock") ||
78
+ f.includes("pthread_rwlock_wrlock") ||
79
+ f.includes("pthread_rwlock_rdlock") ||
80
+ f.includes("os_unfair_lock_lock") ||
81
+ f.includes("dispatch_semaphore_wait") ||
82
+ f.includes("dispatch_sync") ||
83
+ f.includes("NSConditionLock lockWhenCondition") ||
84
+ f.includes("NSLock lock"),
85
+ },
86
+ ];
87
+ /**
88
+ * Pure: classify a top-frame symbol into a `MainThreadViolation`. Returns
89
+ * `null` when nothing in the catalog matches. The `samples` count comes
90
+ * from the caller; with only a top-frame string available we set it to 1.
91
+ *
92
+ * Multiple signatures can match a single frame (e.g. a sync I/O call that
93
+ * also holds an unfair lock). We return the FIRST match in catalog order,
94
+ * which puts more user-actionable categories ahead of generic locks.
95
+ */
96
+ export function classifyHangFrame(topFrame, samples = 1) {
97
+ for (const sig of MAIN_THREAD_VIOLATION_SIGNATURES) {
98
+ if (sig.matches(topFrame)) {
99
+ return { kind: sig.kind, topFrame, samples };
100
+ }
101
+ }
102
+ return null;
103
+ }
104
+ /** Stable key used to correlate the supplemental `topFramesByHangStartNs`
105
+ * map. Hang startNs values are nanoseconds (integers when xctrace exports
106
+ * them cleanly), so the key is just `String(startNs)`. Centralized so
107
+ * callers building the map use the same convention. */
108
+ export function hangFrameMapKey(startNs) {
109
+ return String(startNs);
110
+ }
23
111
  /** Pure: turn parsed XML rows into our analyzed result. */
24
- export function analyzeHangsFromXml(xml, tracePath, topN = 10, minDurationMs = 0) {
112
+ export function analyzeHangsFromXml(xml, tracePath, topN = 10, minDurationMs = 0, timeRangeMs, topFramesByHangStartNs) {
25
113
  const tables = parseXctraceXml(xml);
26
114
  const hangsTable = tables.find((t) => t.schema === "potential-hangs");
27
115
  if (!hangsTable) {
@@ -38,6 +126,7 @@ export function analyzeHangsFromXml(xml, tracePath, topN = 10, minDurationMs = 0
38
126
  },
39
127
  top: [],
40
128
  diagnosis: "No potential-hangs table found in the trace.",
129
+ status: "not_present",
41
130
  };
42
131
  }
43
132
  const allEntries = [];
@@ -53,7 +142,17 @@ export function analyzeHangsFromXml(xml, tracePath, topN = 10, minDurationMs = 0
53
142
  hangType: asFormatted(row["hang-type"]) ?? "",
54
143
  });
55
144
  }
56
- const filtered = allEntries.filter((e) => e.durationMs >= minDurationMs);
145
+ const filtered = allEntries.filter((e) => {
146
+ if (e.durationMs < minDurationMs)
147
+ return false;
148
+ if (timeRangeMs) {
149
+ const startMs = e.startNs / 1_000_000;
150
+ if (startMs < timeRangeMs.startMs || startMs > timeRangeMs.endMs) {
151
+ return false;
152
+ }
153
+ }
154
+ return true;
155
+ });
57
156
  const hangs = filtered.filter((e) => e.hangType === "Hang");
58
157
  const microhangs = filtered.filter((e) => e.hangType === "Microhang");
59
158
  const totalDurationMs = filtered.reduce((sum, e) => sum + e.durationMs, 0);
@@ -62,6 +161,19 @@ export function analyzeHangsFromXml(xml, tracePath, topN = 10, minDurationMs = 0
62
161
  const top = [...filtered]
63
162
  .sort((a, b) => b.durationMs - a.durationMs)
64
163
  .slice(0, topN);
164
+ // Enrich each top hang with main-thread violation classifications when
165
+ // the supplemental top-frame map was supplied. We mutate the cloned
166
+ // entries in `top` because they are not aliased back into `filtered`
167
+ // after the spread above.
168
+ if (topFramesByHangStartNs) {
169
+ for (const entry of top) {
170
+ const frame = topFramesByHangStartNs[hangFrameMapKey(entry.startNs)];
171
+ if (frame == null)
172
+ continue;
173
+ const violation = classifyHangFrame(frame);
174
+ entry.mainThreadViolations = violation ? [violation] : [];
175
+ }
176
+ }
65
177
  const diagnosis = buildHangDiagnosis(filtered.length, hangs.length, microhangs.length, longestMs, averageMs);
66
178
  return {
67
179
  ok: true,
@@ -76,6 +188,7 @@ export function analyzeHangsFromXml(xml, tracePath, topN = 10, minDurationMs = 0
76
188
  },
77
189
  top,
78
190
  diagnosis,
191
+ status: "available",
79
192
  };
80
193
  }
81
194
  function buildHangDiagnosis(rows, hangs, microhangs, longestMs, averageMs) {
@@ -109,6 +222,6 @@ export async function analyzeHangs(input) {
109
222
  if (result.code !== 0) {
110
223
  throw new Error(`xctrace export failed (code ${result.code}): ${result.stderr || result.stdout}`);
111
224
  }
112
- return analyzeHangsFromXml(result.stdout, tracePath, input.topN ?? 10, input.minDurationMs ?? 0);
225
+ return analyzeHangsFromXml(result.stdout, tracePath, input.topN ?? 10, input.minDurationMs ?? 0, input.timeRangeMs, input.topFramesByHangStartNs);
113
226
  }
114
227
  //# sourceMappingURL=analyzeHangs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyzeHangs.js","sourceRoot":"","sources":["../../src/tools/analyzeHangs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzeHangs.js","sourceRoot":"","sources":["../../src/tools/analyzeHangs.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { type ReferenceTreeEntry } from "../parsers/referenceTree.js";
2
3
  import { type Verbosity } from "../parsers/shortenClassName.js";
3
4
  import type { LeaksReport, NextCallSuggestion } from "../types.js";
4
5
  export declare const analyzeMemgraphSchema: z.ZodObject<{
@@ -6,16 +7,22 @@ export declare const analyzeMemgraphSchema: z.ZodObject<{
6
7
  fullChains: z.ZodDefault<z.ZodBoolean>;
7
8
  verbosity: z.ZodDefault<z.ZodEnum<["compact", "normal", "full"]>>;
8
9
  maxClassesInChain: z.ZodDefault<z.ZodNumber>;
10
+ referenceTreeTopN: z.ZodDefault<z.ZodNumber>;
11
+ outputFormat: z.ZodOptional<z.ZodEnum<["markdown", "json", "both"]>>;
9
12
  }, "strip", z.ZodTypeAny, {
10
13
  path: string;
11
14
  fullChains: boolean;
12
15
  verbosity: "compact" | "normal" | "full";
13
16
  maxClassesInChain: number;
17
+ referenceTreeTopN: number;
18
+ outputFormat?: "markdown" | "json" | "both" | undefined;
14
19
  }, {
15
20
  path: string;
16
21
  fullChains?: boolean | undefined;
17
22
  verbosity?: "compact" | "normal" | "full" | undefined;
18
23
  maxClassesInChain?: number | undefined;
24
+ referenceTreeTopN?: number | undefined;
25
+ outputFormat?: "markdown" | "json" | "both" | undefined;
19
26
  }>;
20
27
  export type AnalyzeMemgraphInput = z.infer<typeof analyzeMemgraphSchema>;
21
28
  export interface CycleSummary {
@@ -57,8 +64,21 @@ export interface AnalyzeMemgraphResult {
57
64
  fullReport?: LeaksReport;
58
65
  /** Plain-English diagnosis (one liner). */
59
66
  diagnosis: string;
60
- /** Pipeline hints chain `classifyCycle` next, then `reachableFromCycle` to scope blame. */
67
+ /** Pipeline hints. Chain `classifyCycle` next, then `reachableFromCycle` to scope blame. */
61
68
  suggestedNextCalls?: NextCallSuggestion[];
69
+ /**
70
+ * Top live classes by instance count from the heap reference tree.
71
+ * Populated when `leakCount` is 0 and `referenceTreeTopN > 0`. Surfaces
72
+ * the abandoned-memory shape that the standard `leaks` count misses:
73
+ * objects that are technically reachable (so not "leaked" in the strict
74
+ * sense) but whose growth across repeated workflows indicates a real
75
+ * accumulation bug (KVO observers not invalidated, NotificationCenter
76
+ * observers leaked, caches that never evict, etc.). These classes are
77
+ * not formal leaks; they are reachable-but-suspicious and worth diffing
78
+ * against a baseline via `analyzeAbandonedMemory(before, after)` for
79
+ * the verdict.
80
+ */
81
+ abandonedMemoryTop?: ReferenceTreeEntry[];
62
82
  }
63
83
  /**
64
84
  * Pure function: take a `leaks` stdout string and a source path, produce a structured analysis.
@@ -3,6 +3,8 @@ import { existsSync } from "node:fs";
3
3
  import { resolve as resolvePath } from "node:path";
4
4
  import { runCommand } from "../runtime/exec.js";
5
5
  import { parseLeaksOutput, rootCyclesOnly } from "../parsers/leaksOutput.js";
6
+ import { parseReferenceTreeText, } from "../parsers/referenceTree.js";
7
+ import { outputFormatField } from "../runtime/responseFormatter.js";
6
8
  import { shortenForVerbosity, } from "../parsers/shortenClassName.js";
7
9
  import { suggestionClassifyCycle, suggestionReachableFromCycle, } from "../runtime/suggestions.js";
8
10
  export const analyzeMemgraphSchema = z.object({
@@ -24,7 +26,15 @@ export const analyzeMemgraphSchema = z.object({
24
26
  .positive()
25
27
  .max(50)
26
28
  .default(10)
27
- .describe("Cap on how many unique class names to surface per cycle's `classesInChain` array. Default 10 enough to identify app-level types without flooding the response."),
29
+ .describe("Cap on how many unique class names to surface per cycle's `classesInChain` array. Default 10, enough to identify app-level types without flooding the response."),
30
+ referenceTreeTopN: z
31
+ .number()
32
+ .int()
33
+ .nonnegative()
34
+ .max(200)
35
+ .default(20)
36
+ .describe("When `leakCount` is 0 (the typical abandoned-memory case), also run `leaks --referenceTree --groupByType --noContent` and surface the top N classes by live instance count in `abandonedMemoryTop[]`. Set to 0 to skip the second leaks invocation. Default 20."),
37
+ outputFormat: outputFormatField,
28
38
  });
29
39
  /**
30
40
  * Pure function: take a `leaks` stdout string and a source path, produce a structured analysis.
@@ -130,6 +140,46 @@ export async function analyzeMemgraph(input) {
130
140
  if (result.code !== 0 && result.code !== 1) {
131
141
  throw new Error(`leaks failed (code ${result.code}): ${result.stderr || result.stdout}`);
132
142
  }
133
- return summarizeLeaks(result.stdout, path, input.fullChains ?? false, input.verbosity ?? "compact", input.maxClassesInChain ?? 10);
143
+ const summary = summarizeLeaks(result.stdout, path, input.fullChains ?? false, input.verbosity ?? "compact", input.maxClassesInChain ?? 10);
144
+ // Abandoned-memory surface: when `leaks` finds zero leaks, the reference
145
+ // tree still carries information about what the heap is holding alive.
146
+ // This is the only signal for the "orphaned KVO observer" / "abandoned
147
+ // cache" class of bugs that don't form a closed cycle. We invoke a second
148
+ // leaks pass with `--referenceTree --groupByType --noContent` and rank
149
+ // classes by live instance count. The caller can then chain into
150
+ // `analyzeAbandonedMemory(before, after)` to confirm growth shape across
151
+ // a workflow.
152
+ const topN = input.referenceTreeTopN ?? 20;
153
+ if (summary.totals.leakCount === 0 && topN > 0) {
154
+ const abandonedMemoryTop = await captureReferenceTreeTop(path, topN);
155
+ if (abandonedMemoryTop.length > 0) {
156
+ summary.abandonedMemoryTop = abandonedMemoryTop;
157
+ }
158
+ }
159
+ return summary;
160
+ }
161
+ /**
162
+ * Spawn a second `leaks` invocation with the reference-tree flags and parse
163
+ * the top N classes by instance count. Exposed as a helper so the
164
+ * integration is testable without spawning, by passing a precomputed
165
+ * stdout via the pure `parseReferenceTreeText` directly.
166
+ *
167
+ * Failure here is non-fatal: if leaks fails on the second invocation, we
168
+ * return an empty array rather than throwing, so the main analyze result
169
+ * is still returned to the caller. The most likely failure path is the
170
+ * same macOS 26.x kernel regression that hit the first invocation, which
171
+ * would already be surfaced via the earlier captureMemgraph step.
172
+ */
173
+ async function captureReferenceTreeTop(path, topN) {
174
+ try {
175
+ const result = await runCommand("leaks", [path, "--referenceTree", "--groupByType", "--noContent"], { timeoutMs: 5 * 60_000 });
176
+ if (result.code !== 0 && result.code !== 1) {
177
+ return [];
178
+ }
179
+ return parseReferenceTreeText(result.stdout, topN);
180
+ }
181
+ catch {
182
+ return [];
183
+ }
134
184
  }
135
185
  //# sourceMappingURL=analyzeMemgraph.js.map