0
# Chrome DevTools Integration
1
2
Support for symbolicating Chrome DevTools formats including CPU profiles and heap snapshots.
3
4
## Capabilities
5
6
### ChromeHeapSnapshotProcessor Class
7
8
Processes and symbolicates Chrome DevTools heap snapshots and heap timelines to translate bundled locations back to original source positions.
9
10
```javascript { .api }
11
/**
12
* Processes Chrome heap snapshots for symbolication
13
* @param snapshot - Chrome heap snapshot data structure
14
*/
15
class ChromeHeapSnapshotProcessor {
16
constructor(snapshot: ChromeHeapSnapshot);
17
18
/**
19
* Symbolicates a specific location in the heap snapshot
20
* @param locationIdx - Index of location in snapshot.locations array
21
* @param context - Symbolication context for position translation
22
*/
23
symbolicateLocation(locationIdx: number, context: SymbolicationContext): void;
24
25
/**
26
* Symbolicates all locations in the heap snapshot
27
* @param context - Symbolication context for position translations
28
*/
29
expandLocations(context: SymbolicationContext): void;
30
}
31
```
32
33
**Usage Examples:**
34
35
```javascript
36
const { ChromeHeapSnapshotProcessor } = require('metro-symbolicate/private/ChromeHeapSnapshot');
37
const Symbolication = require('metro-symbolicate/private/Symbolication');
38
const { SourceMapConsumer } = require('source-map');
39
const fs = require('fs');
40
41
// Load heap snapshot and source map
42
const snapshotData = JSON.parse(fs.readFileSync('heap.heapsnapshot', 'utf8'));
43
const sourceMapContent = fs.readFileSync('bundle.js.map', 'utf8');
44
45
// Create processor and symbolication context
46
const processor = new ChromeHeapSnapshotProcessor(snapshotData);
47
const context = Symbolication.createContext(SourceMapConsumer, sourceMapContent);
48
49
// Symbolicate all locations in the snapshot
50
processor.expandLocations(context);
51
52
// Save symbolicated snapshot
53
fs.writeFileSync('symbolicated-heap.json', JSON.stringify(snapshotData));
54
```
55
56
### Heap Snapshot Structure Processing
57
58
Handles the complex Chrome heap snapshot format with its various data structures and indices.
59
60
**Heap Snapshot Components:**
61
62
```javascript { .api }
63
type ChromeHeapSnapshot = {
64
snapshot: {
65
meta: {
66
trace_function_info_fields: Array<string>;
67
location_fields: Array<string>;
68
edge_fields: Array<string>;
69
edge_types: Array<string | Array<string>>;
70
node_fields: Array<string>;
71
node_types: Array<string | Array<string>>;
72
trace_node_fields: Array<string>;
73
};
74
};
75
trace_function_infos: Array<number>;
76
locations: Array<number>;
77
edges: Array<number>;
78
nodes: Array<number>;
79
strings: Array<string>;
80
trace_tree: RawBuffer;
81
};
82
83
type RawBuffer = Array<number | RawBuffer>;
84
```
85
86
**Processing Example:**
87
88
```javascript
89
// Accessing heap snapshot data
90
const processor = new ChromeHeapSnapshotProcessor(snapshot);
91
92
// The processor provides internal utilities for working with:
93
// - String table lookups
94
// - Record field access
95
// - Location data manipulation
96
// - Trace tree navigation
97
98
// Symbolicate specific locations
99
const locationCount = snapshot.locations.length / snapshot.snapshot.meta.location_fields.length;
100
for (let i = 0; i < locationCount; i++) {
101
processor.symbolicateLocation(i, context);
102
}
103
```
104
105
### CPU Profile Symbolication
106
107
Integrates with the core symbolication API to process Chrome DevTools CPU profiles.
108
109
```javascript
110
// CPU profile symbolication is handled through the core API
111
const context = Symbolication.createContext(SourceMapConsumer, sourceMapContent);
112
113
// Process CPU profile file directly
114
context.symbolicateChromeTrace('./profile.cpuprofile', {
115
stdout: process.stdout,
116
stderr: process.stderr
117
});
118
```
119
120
**CPU Profile Structure:**
121
122
CPU profiles contain stack frame information that gets symbolicated:
123
124
```javascript { .api }
125
type ChromeTrace = {
126
stackFrames: { [string]: ChromeTraceEntry };
127
};
128
129
type ChromeTraceEntry = {
130
column: number;
131
funcColumn: number;
132
funcLine: number;
133
funcVirtAddr: number;
134
line: number;
135
name: string;
136
offset: number;
137
};
138
```
139
140
### String Table Management
141
142
Efficiently manages the Chrome heap snapshot string table for lookups and modifications.
143
144
**Internal String Table Operations:**
145
146
```javascript
147
// String table operations are handled internally by ChromeHeapSnapshotProcessor
148
// The processor provides utilities for:
149
// - String lookups by index
150
// - String additions and modifications
151
// - String table consistency maintenance
152
153
// Example: the processor automatically handles string table updates
154
// when symbolication replaces bundled paths with original source paths
155
```
156
157
### Record Access Utilities
158
159
Provides structured access to Chrome heap snapshot records with their various field types.
160
161
**Record Field Processing:**
162
163
```javascript
164
// The processor handles different field types:
165
// - String fields (indices into string table)
166
// - Numeric fields (direct values)
167
// - Enum fields (indices into type arrays)
168
169
// Field access is abstracted through internal utilities:
170
// - ChromeHeapSnapshotRecordAccessor: Field-based record access
171
// - ChromeHeapSnapshotRecordIterator: Iteration over record collections
172
```
173
174
### Location Symbolication
175
176
Translates bundled JavaScript locations in heap snapshots to original source positions.
177
178
**Location Processing:**
179
180
```javascript
181
const processor = new ChromeHeapSnapshotProcessor(snapshot);
182
const context = Symbolication.createContext(SourceMapConsumer, sourceMapContent);
183
184
// Symbolicate individual location
185
processor.symbolicateLocation(locationIndex, context);
186
187
// The location data gets updated in-place:
188
// Before: { script_id: 123, line: 1, column: 234 }
189
// After: { script_id: 123, line: 15, column: 8, source: 'src/component.js' }
190
191
// Symbolicate all locations at once
192
processor.expandLocations(context);
193
```
194
195
### Error Handling
196
197
Gracefully handles malformed heap snapshots and symbolication failures.
198
199
```javascript
200
const { ChromeHeapSnapshotProcessor } = require('metro-symbolicate/private/ChromeHeapSnapshot');
201
202
try {
203
const processor = new ChromeHeapSnapshotProcessor(snapshot);
204
processor.expandLocations(context);
205
} catch (error) {
206
if (error.message.includes('Invalid heap snapshot format')) {
207
console.error('Heap snapshot data is malformed');
208
} else if (error.message.includes('Missing source map data')) {
209
console.error('Cannot symbolicate without valid source map');
210
} else {
211
console.error('Symbolication failed:', error);
212
}
213
}
214
215
// The processor validates heap snapshot structure
216
// and handles missing or invalid fields gracefully
217
```
218
219
### Memory Efficiency
220
221
Processes large heap snapshots efficiently with in-place modifications and streaming access patterns.
222
223
**Performance Considerations:**
224
225
```javascript
226
// Large heap snapshots are processed efficiently:
227
// - In-place modification of location data
228
// - Lazy string table operations
229
// - Minimal memory overhead during processing
230
231
const processor = new ChromeHeapSnapshotProcessor(largeSnapshot);
232
233
// Process locations incrementally if needed
234
const locationFieldCount = largeSnapshot.snapshot.meta.location_fields.length;
235
const totalLocations = largeSnapshot.locations.length / locationFieldCount;
236
237
for (let i = 0; i < totalLocations; i++) {
238
processor.symbolicateLocation(i, context);
239
240
// Optional: process in batches to manage memory
241
if (i % 1000 === 0) {
242
console.log(`Processed ${i}/${totalLocations} locations`);
243
}
244
}
245
```
246
247
### Integration Examples
248
249
Complete examples showing integration with various Chrome DevTools workflows.
250
251
**Heap Timeline Processing:**
252
253
```javascript
254
const processHeapTimeline = (timelineFile, sourceMapFile) => {
255
const timelineData = JSON.parse(fs.readFileSync(timelineFile, 'utf8'));
256
const sourceMapContent = fs.readFileSync(sourceMapFile, 'utf8');
257
258
// Create processor and context
259
const processor = new ChromeHeapSnapshotProcessor(timelineData);
260
const context = Symbolication.createContext(SourceMapConsumer, sourceMapContent);
261
262
// Symbolicate all locations
263
processor.expandLocations(context);
264
265
return timelineData;
266
};
267
268
// Usage
269
const symbolicatedTimeline = processHeapTimeline(
270
'allocation-timeline.heaptimeline',
271
'bundle.js.map'
272
);
273
```
274
275
**Memory Profiling Workflow:**
276
277
```javascript
278
const analyzeMemoryProfile = (profilePath, sourceMapPath) => {
279
// Load and symbolicate heap snapshot
280
const snapshot = JSON.parse(fs.readFileSync(profilePath, 'utf8'));
281
const sourceMap = fs.readFileSync(sourceMapPath, 'utf8');
282
283
const processor = new ChromeHeapSnapshotProcessor(snapshot);
284
const context = Symbolication.createContext(SourceMapConsumer, sourceMap);
285
286
// Symbolicate locations
287
processor.expandLocations(context);
288
289
// Now analyze with original source locations
290
// Extract allocation stacks, object references, etc.
291
return {
292
totalObjects: snapshot.nodes.length,
293
symbolicatedLocations: snapshot.locations.length,
294
snapshot: snapshot
295
};
296
};
297
```
298
299
## Types
300
301
```javascript { .api }
302
type ChromeHeapSnapshotFieldType =
303
| 'pointer'
304
| 'array'
305
| 'synthetic'
306
| 'numeric'
307
| 'string'
308
| 'object'
309
| 'code'
310
| 'closure'
311
| 'regexp'
312
| 'number'
313
| 'native'
314
| 'symbol'
315
| 'bigint';
316
317
type DenormalizedRecordInput = $ReadOnly<{
318
[fieldName: string]: string | number;
319
}>;
320
```