assafvayner HF Staff commited on
Commit
95a58a1
Β·
1 Parent(s): a8d61e7
Files changed (3) hide show
  1. .gitignore +1 -0
  2. README.md +14 -0
  3. src/App.svelte +46 -39
.gitignore CHANGED
@@ -1 +1,2 @@
 
1
  node_modules/
 
1
+ dist/
2
  node_modules/
README.md CHANGED
@@ -1,3 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # πŸ” Backtrace Viewer
2
 
3
  A modern web application for viewing and analyzing backtrace files from sampling profilers, built with Svelte.
 
1
+ ---
2
+ title: Macos Sample File Viewer
3
+ emoji: πŸŒ–
4
+ colorFrom: blue
5
+ colorTo: yellow
6
+ sdk: static
7
+ pinned: false
8
+ license: apache-2.0
9
+ app_build_command: npm run build
10
+ app_file: dist/index.html
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
14
+
15
  # πŸ” Backtrace Viewer
16
 
17
  A modern web application for viewing and analyzing backtrace files from sampling profilers, built with Svelte.
src/App.svelte CHANGED
@@ -75,18 +75,10 @@
75
 
76
  // Toggle thread visibility
77
  function toggleThread(threadId) {
78
- console.log("πŸ”„ Toggling thread:", threadId);
79
  // Create a new array with updated thread to trigger Svelte reactivity
80
  threads = threads.map((thread) => {
81
  if (thread.id === threadId) {
82
- const newThread = { ...thread, expanded: !thread.expanded };
83
- console.log(
84
- "πŸ“Š Thread expanded:",
85
- newThread.expanded,
86
- "backtrace lines:",
87
- newThread.backtrace.length
88
- );
89
- return newThread;
90
  }
91
  return thread;
92
  });
@@ -112,7 +104,6 @@
112
  if (response.ok) {
113
  backtraceData = await response.text();
114
  threads = parseBacktraceFile(backtraceData);
115
- console.log("βœ… Loaded", threads.length, "threads successfully");
116
  }
117
  } catch (error) {
118
  console.error("Could not load sample.txt:", error);
@@ -149,14 +140,32 @@
149
  return match ? match[1].length : 0;
150
  }
151
 
152
- // Find the end of a section (lines with greater indentation)
 
 
 
 
 
 
 
 
 
 
 
 
153
  function findSectionEnd(backtrace, startIndex) {
154
  const startIndentation = getIndentationLevel(backtrace[startIndex]);
155
 
156
  for (let i = startIndex + 1; i < backtrace.length; i++) {
157
- const currentIndentation = getIndentationLevel(backtrace[i]);
158
- // If we find a line with same or lesser indentation, that's where the section ends
159
- if (currentIndentation <= startIndentation) {
 
 
 
 
 
 
160
  return i - 1; // Return the last line of the section
161
  }
162
  }
@@ -168,8 +177,11 @@
168
  function createCollapsibleBacktrace(backtrace) {
169
  const result = backtrace.map((line, index) => {
170
  const indentationLevel = getIndentationLevel(line);
171
- const sectionEnd = findSectionEnd(backtrace, index);
172
- const hasSection = sectionEnd > index; // This line has child lines with greater indentation
 
 
 
173
 
174
  return {
175
  id: index,
@@ -178,8 +190,9 @@
178
  indentationLevel,
179
  hasSection,
180
  sectionEnd,
181
- sectionCollapsed: false,
182
  hidden: false, // Will be set based on parent section state
 
183
  };
184
  });
185
 
@@ -193,12 +206,6 @@
193
 
194
  // Toggle section collapse for a specific line
195
  function toggleSection(threadId, lineIndex) {
196
- console.log(
197
- "πŸ”„ Toggling section for thread:",
198
- threadId,
199
- "line:",
200
- lineIndex
201
- );
202
  threads = threads.map((thread) => {
203
  if (thread.id === threadId && thread.collapsibleBacktrace) {
204
  const updatedBacktrace = [...thread.collapsibleBacktrace];
@@ -207,21 +214,8 @@
207
  if (line.hasSection) {
208
  // Toggle the section collapsed state
209
  line.sectionCollapsed = !line.sectionCollapsed;
210
- console.log(
211
- "πŸ“Š Section",
212
- lineIndex,
213
- "collapsed:",
214
- line.sectionCollapsed,
215
- "affects lines",
216
- lineIndex + 1,
217
- "to",
218
- line.sectionEnd
219
- );
220
-
221
  // Update hidden state for all lines in this section
222
  updateSectionVisibility(updatedBacktrace, lineIndex);
223
- } else {
224
- console.log("⚠️ Line", lineIndex, "has no section to toggle");
225
  }
226
 
227
  return { ...thread, collapsibleBacktrace: updatedBacktrace };
@@ -249,11 +243,12 @@
249
  function isLineHiddenByParentSection(backtrace, lineIndex) {
250
  const currentIndentation = backtrace[lineIndex].indentationLevel;
251
 
252
- // Look backwards for any parent sections that are collapsed
253
  for (let i = lineIndex - 1; i >= 0; i--) {
254
  const parentLine = backtrace[i];
255
  if (
256
- parentLine.indentationLevel < currentIndentation &&
 
257
  parentLine.hasSection &&
258
  parentLine.sectionCollapsed &&
259
  i + 1 <= lineIndex &&
@@ -328,7 +323,7 @@
328
  <div class="backtrace">
329
  {#each thread.collapsibleBacktrace as backtraceLine (backtraceLine.id)}
330
  {#if !backtraceLine.hidden}
331
- {#if backtraceLine.hasSection}
332
  <div
333
  class="backtrace-line has-section"
334
  class:section-collapsed={backtraceLine.sectionCollapsed}
@@ -350,7 +345,19 @@
350
  {/if}
351
  <span class="content">{backtraceLine.parsed.content}</span>
352
  </div>
 
 
 
 
 
 
 
 
 
 
 
353
  {:else}
 
354
  <div class="backtrace-line">
355
  <span class="indent">{backtraceLine.parsed.indent}</span>
356
  {#if backtraceLine.parsed.sampleCount}
 
75
 
76
  // Toggle thread visibility
77
  function toggleThread(threadId) {
 
78
  // Create a new array with updated thread to trigger Svelte reactivity
79
  threads = threads.map((thread) => {
80
  if (thread.id === threadId) {
81
+ return { ...thread, expanded: !thread.expanded };
 
 
 
 
 
 
 
82
  }
83
  return thread;
84
  });
 
104
  if (response.ok) {
105
  backtraceData = await response.text();
106
  threads = parseBacktraceFile(backtraceData);
 
107
  }
108
  } catch (error) {
109
  console.error("Could not load sample.txt:", error);
 
140
  return match ? match[1].length : 0;
141
  }
142
 
143
+ // Check if a line starts with a numerical digit (0-9) after any leading + : | characters
144
+ function startsWithDigit(line) {
145
+ const trimmedLine = line.trim();
146
+ const result = /^[\+\!\:\|\s]*[0-9]/.test(trimmedLine);
147
+ if (
148
+ trimmedLine.includes("5898 tokio::runtime::scheduler::multi_thread::")
149
+ ) {
150
+ console.log(trimmedLine, "\n\n\n", result);
151
+ }
152
+ return result;
153
+ }
154
+
155
+ // Find the end of a section for lines starting with digits
156
  function findSectionEnd(backtrace, startIndex) {
157
  const startIndentation = getIndentationLevel(backtrace[startIndex]);
158
 
159
  for (let i = startIndex + 1; i < backtrace.length; i++) {
160
+ const currentLine = backtrace[i];
161
+ const currentIndentation = getIndentationLevel(currentLine);
162
+
163
+ // If we find a line that starts with a digit at same or lower indentation,
164
+ // that's where the section ends
165
+ if (
166
+ startsWithDigit(currentLine) &&
167
+ currentIndentation <= startIndentation
168
+ ) {
169
  return i - 1; // Return the last line of the section
170
  }
171
  }
 
177
  function createCollapsibleBacktrace(backtrace) {
178
  const result = backtrace.map((line, index) => {
179
  const indentationLevel = getIndentationLevel(line);
180
+ const startsWithDigitFlag = startsWithDigit(line);
181
+ const sectionEnd = startsWithDigitFlag
182
+ ? findSectionEnd(backtrace, index)
183
+ : index;
184
+ const hasSection = startsWithDigitFlag && sectionEnd > index; // Only lines starting with digits can have sections
185
 
186
  return {
187
  id: index,
 
190
  indentationLevel,
191
  hasSection,
192
  sectionEnd,
193
+ sectionCollapsed: false, // Initially uncollapsed as requested
194
  hidden: false, // Will be set based on parent section state
195
+ startsWithDigit: startsWithDigitFlag,
196
  };
197
  });
198
 
 
206
 
207
  // Toggle section collapse for a specific line
208
  function toggleSection(threadId, lineIndex) {
 
 
 
 
 
 
209
  threads = threads.map((thread) => {
210
  if (thread.id === threadId && thread.collapsibleBacktrace) {
211
  const updatedBacktrace = [...thread.collapsibleBacktrace];
 
214
  if (line.hasSection) {
215
  // Toggle the section collapsed state
216
  line.sectionCollapsed = !line.sectionCollapsed;
 
 
 
 
 
 
 
 
 
 
 
217
  // Update hidden state for all lines in this section
218
  updateSectionVisibility(updatedBacktrace, lineIndex);
 
 
219
  }
220
 
221
  return { ...thread, collapsibleBacktrace: updatedBacktrace };
 
243
  function isLineHiddenByParentSection(backtrace, lineIndex) {
244
  const currentIndentation = backtrace[lineIndex].indentationLevel;
245
 
246
+ // Look backwards for any parent sections that are collapsed (must start with digit)
247
  for (let i = lineIndex - 1; i >= 0; i--) {
248
  const parentLine = backtrace[i];
249
  if (
250
+ parentLine.startsWithDigit &&
251
+ parentLine.indentationLevel <= currentIndentation &&
252
  parentLine.hasSection &&
253
  parentLine.sectionCollapsed &&
254
  i + 1 <= lineIndex &&
 
323
  <div class="backtrace">
324
  {#each thread.collapsibleBacktrace as backtraceLine (backtraceLine.id)}
325
  {#if !backtraceLine.hidden}
326
+ {#if backtraceLine.startsWithDigit && backtraceLine.hasSection}
327
  <div
328
  class="backtrace-line has-section"
329
  class:section-collapsed={backtraceLine.sectionCollapsed}
 
345
  {/if}
346
  <span class="content">{backtraceLine.parsed.content}</span>
347
  </div>
348
+ {:else if backtraceLine.startsWithDigit && !backtraceLine.hasSection}
349
+ <!-- Lines starting with digits but no section (e.g., single line entries) -->
350
+ <div class="backtrace-line">
351
+ <span class="indent">{backtraceLine.parsed.indent}</span>
352
+ {#if backtraceLine.parsed.sampleCount}
353
+ <span class="sample-count"
354
+ >{backtraceLine.parsed.sampleCount}</span
355
+ >
356
+ {/if}
357
+ <span class="content">{backtraceLine.parsed.content}</span>
358
+ </div>
359
  {:else}
360
+ <!-- Lines not starting with digits (continuation lines) -->
361
  <div class="backtrace-line">
362
  <span class="indent">{backtraceLine.parsed.indent}</span>
363
  {#if backtraceLine.parsed.sampleCount}