Skip to content

Instantly share code, notes, and snippets.

@amit08255
Created November 3, 2025 18:22
Show Gist options
  • Select an option

  • Save amit08255/c82cc5b31162c4ddc7aac684d95e2b84 to your computer and use it in GitHub Desktop.

Select an option

Save amit08255/c82cc5b31162c4ddc7aac684d95e2b84 to your computer and use it in GitHub Desktop.
Chrome debug trace origin of an object
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chrome DevTools - Real Object Tracing Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
border-radius: 12px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 40px 30px;
text-align: center;
}
.header h1 {
font-size: 28px;
margin-bottom: 10px;
}
.header p {
font-size: 14px;
opacity: 0.9;
line-height: 1.6;
}
.content {
padding: 40px 30px;
}
.section {
margin-bottom: 40px;
}
.section h2 {
font-size: 18px;
color: #333;
margin-bottom: 15px;
border-bottom: 2px solid #667eea;
padding-bottom: 10px;
}
.demo-box {
background: #f8f9fa;
border-left: 4px solid #667eea;
padding: 20px;
border-radius: 4px;
margin-bottom: 15px;
}
.demo-box p {
color: #555;
line-height: 1.7;
font-size: 14px;
margin-bottom: 10px;
}
.demo-box p:last-child {
margin-bottom: 0;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 20px;
flex-wrap: wrap;
}
button {
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover {
background: #5568d3;
transform: translateY(-2px);
box-shadow: 0 8px 16px rgba(102, 126, 234, 0.3);
}
.btn-secondary {
background: #f0f0f0;
color: #333;
}
.btn-secondary:hover {
background: #e0e0e0;
transform: translateY(-2px);
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-danger:hover {
background: #c82333;
transform: translateY(-2px);
}
.code-block {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 6px;
font-family: "Courier New", monospace;
font-size: 13px;
overflow-x: auto;
margin: 15px 0;
line-height: 1.5;
}
.code-block .keyword {
color: #569cd6;
}
.code-block .string {
color: #ce9178;
}
.code-block .comment {
color: #6a9955;
}
.code-block .class-name {
color: #4ec9b0;
}
.instruction-box {
background: #e7f3ff;
border-left: 4px solid #0066cc;
padding: 15px;
border-radius: 4px;
margin: 15px 0;
font-size: 13px;
color: #003d99;
line-height: 1.7;
}
.warning {
background: #fff3cd;
border-left: 4px solid #ffc107;
padding: 15px;
border-radius: 4px;
margin: 15px 0;
font-size: 13px;
color: #856404;
}
.success {
background: #d4edda;
border-left: 4px solid #28a745;
padding: 15px;
border-radius: 4px;
margin: 15px 0;
font-size: 13px;
color: #155724;
}
.step-list {
list-style: none;
}
.step-list li {
padding: 12px 0;
padding-left: 30px;
position: relative;
color: #555;
font-size: 14px;
line-height: 1.6;
}
.step-list li:before {
content: attr(data-step);
position: absolute;
left: 0;
top: 12px;
background: #667eea;
color: white;
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 600;
}
.footer {
background: #f8f9fa;
padding: 30px;
text-align: center;
border-top: 1px solid #eee;
font-size: 13px;
color: #666;
line-height: 1.8;
}
.status {
padding: 12px;
border-radius: 6px;
margin: 15px 0;
font-size: 13px;
font-weight: 600;
}
.status.waiting {
background: #fff3cd;
color: #856404;
}
.status.ready {
background: #d4edda;
color: #155724;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Real Object Tracing with Chrome DevTools</h1>
<p>Actually create objects through multiple layers and trace them using the memory profiler</p>
</div>
<div class="content">
<!-- Introduction -->
<div class="section">
<h2>What This Demo Does</h2>
<div class="demo-box">
<p>This page creates real JavaScript objects through multiple processing layers, exactly like in production code. You'll use actual Chrome DevTools to find where these objects originated.</p>
<p>No simulation. No fake output. Real debugging.</p>
</div>
</div>
<!-- Step 1: Create Real Object -->
<div class="section">
<h2>Step 1: Create a Mystery Object</h2>
<div class="demo-box">
<p>Click the button below to create a real JavaScript object. It gets processed through multiple layers of code, just like in a real application.</p>
</div>
<button class="btn-primary" onclick="createMysteryObject()">Create Mystery Object</button>
<div id="status1" class="status waiting">Click the button to create an object.</div>
<div class="instruction-box">
<strong>What happens:</strong> An object is created by function A, processed by function B through middleware, and batched by function C. The origin becomes unclear through the multiple layers.
</div>
</div>
<!-- Step 2: Open DevTools -->
<div class="section">
<h2>Step 2: Open Chrome DevTools and Set Breakpoint</h2>
<ol class="step-list">
<li data-step="1">
<strong>Open DevTools</strong>
<p>Press <code>F12</code> (Windows/Linux) or <code>Cmd+Option+I</code> (Mac)</p>
</li>
<li data-step="2">
<strong>Go to Sources Tab</strong>
<p>Click the "Sources" tab at the top of DevTools</p>
</li>
<li data-step="3">
<strong>Find this file in the left panel</strong>
<p>Under "Page", find this HTML file. Click it to view the source code.</p>
</li>
<li data-step="4">
<strong>Search for the function</strong>
<p>Press <code>Ctrl+F</code> (or <code>Cmd+F</code> on Mac) and search for: <code>function batchProcessing</code></p>
</li>
<li data-step="5">
<strong>Set a breakpoint</strong>
<p>Find the line that says <code>return processedData;</code> inside the <code>batchProcessing</code> function. Click the line number on the left to set a breakpoint (a blue dot will appear).</p>
</li>
</ol>
<div class="instruction-box">
<strong>Why this line:</strong> This is where your mystery object exists in scope before it gets returned. You'll be able to see it in the debugger at this point.
</div>
</div>
<!-- Step 3: Create and Hit Breakpoint -->
<div class="section">
<h2>Step 3: Trigger the Breakpoint</h2>
<div class="demo-box">
<p>Now that you have a breakpoint set, click the button below. The code will run and stop at your breakpoint.</p>
</div>
<button class="btn-primary" onclick="createMysteryObjectWithBreak()">Create Object (Will Hit Breakpoint)</button>
<div id="status2" class="status waiting">After clicking, check DevTools - the code should be paused.</div>
</div>
<!-- Step 4: Find Object in Scope -->
<div class="section">
<h2>Step 4: Find Your Mystery Object in DevTools Scope</h2>
<div class="demo-box">
<p>The code is now paused at the breakpoint. Look at the right side of DevTools in the "Scope" pane.</p>
</div>
<div class="instruction-box">
<strong>What you'll see:</strong>
<ul style="margin-top: 10px; margin-left: 20px; line-height: 1.8;">
<li>Local</li>
<li style="margin-left: 20px;">└─ processedData (this is your mystery object)</li>
<li style="margin-left: 20px;"> └─ id: "mystery_12345"</li>
<li style="margin-left: 20px;"> └─ timestamp: 1234567890</li>
<li style="margin-left: 20px;"> └─ userId: "user_xyz"</li>
<li style="margin-left: 20px;"> └─ processed: true</li>
<li style="margin-left: 20px;"> └─ metadata: {...}</li>
</ul>
</div>
<div class="instruction-box">
<strong>Next action:</strong> Right-click on <code>processedData</code> in the Scope pane and select "Store as global variable". This will create <code>temp1</code> that holds your object.
</div>
</div>
<!-- Step 5: Create Beacon -->
<div class="section">
<h2>Step 5: Create Beacon Object in Console</h2>
<div class="demo-box">
<p>After storing your object as a global variable, go to the Console tab and paste this command:</p>
</div>
<div class="code-block">
temp2 = <span class="keyword">new</span> <span class="keyword">class</span> <span class="class-name">AAAAAAAA</span> { a = temp1 }
</div>
<div class="instruction-box">
<strong>What this does:</strong> Creates a distinctive wrapper object around your mystery object. The class name "AAAAAAAA" is unique and easy to filter in the memory profiler. When you search for this class name later, you'll find your object instantly among millions of others.
</div>
</div>
<!-- Step 6: Memory Profiler -->
<div class="section">
<h2>Step 6: Start Memory Profiling First (Before Creating Objects)</h2>
<div class="demo-box">
<p>For best results, start the memory profiler before you create your object. This captures the allocation stack trace from the very beginning.</p>
</div>
<ol class="step-list">
<li data-step="1">
<strong>Go to Memory Tab</strong>
<p>In DevTools, click the "Memory" tab</p>
</li>
<li data-step="2">
<strong>Select Allocation Timeline</strong>
<p>Choose "Allocation timeline" from the options at the top</p>
</li>
<li data-step="3">
<strong>Enable Stack Traces</strong>
<p>Make sure "Allocation stack traces" checkbox is checked</p>
</li>
<li data-step="4">
<strong>Start Recording</strong>
<p>Click the "Start" button (or the red circle to begin recording)</p>
</li>
</ol>
</div>
<!-- Step 7: Complete Flow -->
<div class="section">
<h2>Step 7: Complete Workflow</h2>
<div class="demo-box">
<p>Here's the complete sequence once profiling is running:</p>
</div>
<ol class="step-list">
<li data-step="1">
<strong>Start memory profiling</strong> (Memory tab → Allocation timeline → Start)
</li>
<li data-step="2">
<strong>Set breakpoint</strong> in the Sources tab at the line inside <code>batchProcessing</code> function
</li>
<li data-step="3">
<strong>Click "Create Object (Will Hit Breakpoint)"</strong> button below
</li>
<li data-step="4">
<strong>Store as global variable</strong> - Right-click your object in Scope pane, select "Store as global variable"
</li>
<li data-step="5">
<strong>Create beacon</strong> - In Console, run: <code>temp2 = new class AAAAAAAA { a = temp1 }</code>
</li>
<li data-step="6">
<strong>Resume execution</strong> - Press F10 or click the resume button
</li>
<li data-step="7">
<strong>Stop profiling</strong> - Go back to Memory tab and stop the recording
</li>
<li data-step="8">
<strong>Filter results</strong> - Use "Filter by class" and type: <code>AAAAAAAA</code>
</li>
<li data-step="9">
<strong>View allocation stack</strong> - Expand "Allocation stack" tab below the filtered result. You'll see the exact call stack showing where your object was created.
</li>
</ol>
</div>
<!-- Code Reference -->
<div class="section">
<h2>Code Reference (What's Happening Behind the Scenes)</h2>
<div class="demo-box">
<p>These are the actual functions creating your mystery object:</p>
</div>
<div class="code-block">
<span class="comment">// Layer 1: Initial data creation</span>
<span class="keyword">function</span> createInitialData() {
<span class="keyword">return</span> {
id: <span class="string">'mystery_'</span> + Math.<span class="keyword">random</span>().toString(36).substr(2, 9),
timestamp: Date.<span class="keyword">now</span>(),
userId: <span class="string">'user_xyz'</span>
};
}
<span class="comment">// Layer 2: Middleware processing</span>
<span class="keyword">function</span> applyMiddleware(data) {
<span class="keyword">return</span> {
...data,
processed: <span class="keyword">true</span>,
metadata: { source: <span class="string">'middleware'</span>, version: 1 }
};
}
<span class="comment">// Layer 3: Batching (where breakpoint goes)</span>
<span class="keyword">function</span> batchProcessing() {
<span class="keyword">const</span> initial = createInitialData();
<span class="keyword">const</span> processedData = applyMiddleware(initial);
<span class="keyword">return</span> processedData; <span class="comment">← SET BREAKPOINT HERE</span>
}
</div>
</div>
<!-- Final Tips -->
<div class="section">
<h2>Pro Tips</h2>
<div class="success">
<strong>✓ The beacon class name is your filter hook:</strong> It must be distinctive. "AAAAAAAA" works great because nothing else in your heap will have that name. When you search for it, you instantly find your one object among millions.
</div>
<div class="warning">
<strong>⚠ Timing matters:</strong> Start the memory profiler before clicking "Create Object". This captures the full allocation stack trace from the very beginning of object creation.
</div>
<div class="success">
<strong>✓ The allocation stack shows the call chain:</strong> Once you filter by your beacon class and expand the "Allocation stack" tab, you'll see exactly which functions called which functions. It traces backward from where the object was created.
</div>
</div>
</div>
<div class="footer">
<p>This is a real-world debugging technique used by frontend engineers to trace object origins in complex applications without spending hours chasing through prop chains and middleware transformations.</p>
<p style="margin-top: 15px; font-size: 12px;">Works with Chrome, Edge, and any Chromium-based browser with DevTools supporting Allocation timeline profiling.</p>
</div>
</div>
<script>
// Layer 1: Initial data creation
function createInitialData() {
return {
id: 'mystery_' + Math.random().toString(36).substr(2, 9),
timestamp: Date.now(),
userId: 'user_xyz'
};
}
// Layer 2: Middleware processing
function applyMiddleware(data) {
return {
...data,
processed: true,
metadata: { source: 'middleware', version: 1 }
};
}
// Layer 3: Batching (where the mystery happens)
function batchProcessing() {
const initial = createInitialData();
const processedData = applyMiddleware(initial);
return processedData;
}
// Create the mystery object and log it
function createMysteryObject() {
const mysteryObject = batchProcessing();
window.lastMysteryObject = mysteryObject;
console.log('Mystery object created and stored in window.lastMysteryObject:', mysteryObject);
document.getElementById('status1').innerHTML = '✓ Mystery object created. Check console. Now set a breakpoint and create another one.';
document.getElementById('status1').className = 'status ready';
}
// Create object with breakpoint
function createMysteryObjectWithBreak() {
debugger; // This will pause here if DevTools is open
const mysteryObject = batchProcessing();
window.lastMysteryObject = mysteryObject;
console.log('Breakpoint object created:', mysteryObject);
document.getElementById('status2').innerHTML = '✓ Object created and paused at breakpoint. You should see it in DevTools Scope pane now.';
document.getElementById('status2').className = 'status ready';
}
// Log instructions when page loads
console.log('=== Chrome DevTools Real Object Tracing Demo ===');
console.log('Ready to trace real objects through multiple processing layers.');
console.log('Follow the steps on the page to debug with Chrome DevTools.');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment