Skip to content

SerialForBreakfast/SignalLab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SignalLab

SignalLab app icon

SignalLab is a hands-on iOS learning app for junior and intermediate developers who want practical experience debugging real application problems with Xcode and Instruments.

The project is a working guided lab environment rather than a generic sample app. Each lab contains a realistic bug, diagnostic setup, or performance problem, along with a reproducible trigger and a recommended investigation workflow.

For CLI build defaults, preferred simulator settings, and other machine-readable notes aimed at contributors and coding agents, see AGENTS.md in this repository.

Vision

SignalLab exists to help developers build confidence with debugging by practicing on controlled, repeatable scenarios that mirror common production issues.

Instead of reading about breakpoints, leaks, hangs, and profiling in the abstract, learners will launch a scenario, trigger the issue, inspect the evidence with Apple tooling, identify the cause, and validate the fix.

The app should feel like a polished, modern Apple-platform developer tool while remaining approachable for engineers who are still building intuition around stacks, memory ownership, responsiveness, and performance.

Target Audience

SignalLab is primarily intended for:

  • Junior iOS developers learning how to debug with Xcode
  • Intermediate iOS developers who want more practical experience with Instruments
  • Mentors, instructors, and interview coaches who want concrete debugging exercises
  • Engineers who learn best by investigating realistic bugs rather than reading isolated examples

Core Product Goals

SignalLab should help learners:

  • Understand how to use breakpoints and inspect stack traces
  • Build intuition around call stacks, frames, locals, and caller relationships
  • Diagnose non-crashing logic bugs with line, conditional, and action breakpoints
  • Find and explain memory leaks and ownership problems
  • Identify hangs and main-thread abuse
  • Use Time Profiler to locate hot code paths and repeated expensive work
  • Compare broken and fixed implementations using the same debugging workflow
  • Build a repeatable mental model for investigating app problems instead of guessing

Non-Goals

The first version of SignalLab is intentionally constrained.

It is not intended to be:

  • A general-purpose reference for every Xcode feature
  • A broad survey of every possible Instruments template
  • A production observability platform
  • A replacement for Apple documentation
  • A highly advanced concurrency lab on day one
  • A networking-dependent demo that relies on unstable external services

The early focus is clarity, reproducibility, and strong teaching value.

Product Concept

SignalLab is structured as a catalog of self-contained debugging labs.

Each lab should provide:

  • A focused scenario with one dominant lesson
  • A clear symptom that is visible in the UI or behavior
  • A reproducible trigger that works quickly and consistently
  • A recommended first tool to investigate the issue
  • Hints that guide the learner without immediately giving away the answer
  • A fixed mode or fixed implementation for comparison
  • Notes explaining why the issue occurred and why the fix works

This approach keeps the learning experience concrete and repeatable.

Design Theme

SignalLab uses a modern, dark-forward visual style inspired by Apple developer tools and observability interfaces.

The intended theme is:

  • Calm, precise, and technical
  • Beautiful and modern without becoming flashy
  • Glassy, layered, and depth-aware where appropriate
  • Highly readable with strong visual hierarchy
  • Semantic in its use of color for warnings, faults, memory, success, and neutral tooling states

This theme supports the product goal of making debugging feel intentional and approachable.

Learning Model

SignalLab is meant to support both guided learning and free exploration.

Each lab should be usable in several ways:

  • Independent exploration by launching the lab and investigating the symptom
  • Guided instruction with hints and recommended tools
  • Mentor-led walkthroughs in training or interview prep settings
  • Before-and-after comparison using broken and fixed implementations

The app should emphasize reasoning, not memorization.

Working Labs

The app currently ships a locked MVP sequence of six core labs, followed by scheme-diagnostics entries and additional Phase 2 scenarios. The summaries below match that teaching order; SignalLab/SignalLab/Shared/LabDomain/LabCatalog.swift is the source of truth for titles, slugs, and copy.

MVP labs:

  1. Crash Lab
  2. Exception Breakpoint Lab
  3. Breakpoint Lab
  4. Memory Graph Lab
  5. Hang Lab
  6. CPU Hotspot Lab

Additional working catalog labs:

  • Thread Performance Checker Lab
  • Zombie Objects Lab
  • Thread Sanitizer Lab
  • Malloc Stack Logging Lab
  • Retain Cycle Lab
  • Heap Growth Lab
  • Deadlock Lab
  • Background Thread UI Lab
  • Main Thread I/O Lab
  • Scroll Hitch Lab
  • Startup Signpost Lab
  • Concurrency Isolation Lab

1. Crash Lab

This lab teaches the default Xcode stop after a crash: finding the first relevant app frame, inspecting locals, and moving one caller up for context—before treating exception breakpoints as the first tool.

Scenario: A sample import flow loads malformed local data and crashes because the parser makes unsafe assumptions.

Key learning goals:

  • Find the first relevant frame in your code after a crash
  • Inspect locals and caller context in the stopped debugger
  • Identify the bad assumption in the parser and how Fixed mode validates input safely

2. Exception Breakpoint Lab

This lab compares debugger stop policy: the same failure family as Crash Lab, once with Xcode’s default stop and again with an Exception Breakpoint, so you can articulate what the extra breakpoint adds.

Key learning goals:

  • Compare default crash stop vs Exception Breakpoint on the same repro
  • Recognize when changing stop policy gives clearer or earlier context
  • Keep this lab distinct from Breakpoint Lab (logic bugs while the app keeps running)

3. Breakpoint Lab

This lab teaches practical use of one line breakpoint for a logic bug that does not crash.

Scenario: A student order shows the wrong final total because the discount calculation applies 5% when the expected discount is 20%.

Key learning goals:

  • Use a line breakpoint when the app keeps running but produces a wrong result
  • Inspect local variables at the paused calculation line before changing code
  • Explain the bad total from one visible calculation input: discountPercent

4. Memory Graph Lab

This lab teaches the first Memory Graph workflow: navigate the left Memory Graph hierarchy to one named app object and read the arrow to the object it keeps alive.

Scenario: An open note should be easy to inspect in Memory Graph. MemoryGraphOpenNoteHolder keeps MemoryGraphOpenNote alive so learners can practice following one straight ownership path before diagnosing retain cycles.

Key learning goals:

  • Use the Memory Graph left navigator instead of relying on the default canvas selection
  • Navigate SignalLab.debug.dylib -> MemoryGraphOpenNoteHolder before reading the graph
  • Read the arrow from MemoryGraphOpenNoteHolder to MemoryGraphOpenNote as "the holder keeps this note alive"
  • Use the right inspector Backtrace to jump from the live object to the source line that allocated it
  • Learn the basic "who owns this object?" workflow before the later Retain Cycle Lab

5. Hang Lab

This lab teaches hang investigation and main-thread responsiveness analysis.

Scenario: A report-loading flow performs heavy JSON parsing and transformation work on the main thread, causing the UI to freeze.

Key learning goals:

  • Recognize a visible hang
  • Pause execution during a freeze and inspect threads
  • Identify work that should not be happening on the main thread
  • Compare broken and fixed responsiveness behavior

6. CPU Hotspot Lab

This lab teaches Time Profiler and hot-path investigation.

Scenario: A searchable list becomes sluggish because each keystroke triggers repeated expensive work, unnecessary sorting, and repeated helper creation.

Key learning goals:

  • Profile a slow interaction with Time Profiler
  • Identify the hottest functions in the trace
  • Separate core causes from framework noise
  • Validate that the optimized implementation improves responsiveness

Future Lab Candidates

Several topics below already have catalog entries (see Tasks.md MVP exit criteria); this list remains for additional depth or new templates as Apple tooling evolves.

  • Deeper heap and allocation workflows beyond the current Heap Growth and Malloc Stack Logging labs
  • Broader race and isolation coverage beyond Thread Sanitizer and Concurrency Isolation labs
  • Additional Instruments templates or platform-specific rendering tools as Apple ships them
  • Glossary, structured hint progression, and mentor-style prompts (see roadmap phases)

Product Roadmap

Phase 0: Foundation

Establish the reusable structure for the app.

Planned work:

  • Create the app shell and lab catalog
  • Define shared lab metadata and navigation patterns
  • Build reusable UI for lab descriptions, triggers, hints, and fixed-mode comparison
  • Set up documentation structure for labs and investigation guides

Phase 1: Foundational Labs

Ship the six MVP labs in locked curriculum order (see LabRefinement.md).

Delivered in the app:

  • Crash Lab
  • Exception Breakpoint Lab
  • Breakpoint Lab
  • Memory Graph Lab
  • Hang Lab
  • CPU Hotspot Lab

Goal: Ship a strong MVP that already teaches the most important debugging workflows.

Phase 2: Diagnostics Expansion

Broaden the curriculum into scheme diagnostics and more advanced debugging scenarios.

Post-MVP scheme diagnostics (in catalog, order per LabRefinement.md):

  • Thread Performance Checker Lab (thread_performance_checker) — guided, ties to Hang Lab + Xcode scheme diagnostics
  • Zombie Objects Lab (zombie_objects)
  • Thread Sanitizer Lab (thread_sanitizer)
  • Malloc Stack Logging Lab (malloc_stack_logging)
  • Retain Cycle Lab (retain_cycle) — preserved slug and terminology, now later than the first Memory Graph lesson

Shipped (Phase 2 curriculum slice):

  • Heap Growth Lab (heap_growth) — unbounded buffer retention vs capped ring buffer (contrast with retain cycles)
  • Deadlock Lab (deadlock) — main-queue sync self-deadlock vs safe main-actor work
  • Background Thread UI Lab (background_thread_ui) — notification from detached task vs MainActor delivery before UI observers run
  • Main Thread I/O Lab (main_thread_io) — synchronous repeated file reads on main vs detached Data(contentsOf:)
  • Scroll Hitch Lab (scroll_hitch) — per-row compositing + shadow cost during scroll vs lighter chrome
  • Startup Signpost Lab (startup_signpost) — phased main-thread work with vs without os_signpost / Points of Interest
  • Concurrency Isolation Lab (concurrency_isolation) — unstructured Task.detached ordering vs sequential async work (before reaching for Thread Sanitizer)

Still on the roadmap:

  • Additional Instruments templates or platform-specific rendering tools as Apple ships them
  • Deeper Swift 6 strict-concurrency curriculum beyond Concurrency Isolation Lab

Phase 3: Pedagogy and Curriculum

Turn the app into a more complete teaching product.

Planned work:

  • Progressive difficulty levels
  • Structured hint system
  • Glossary of debugging terms
  • Mentor and workshop prompts
  • Lab completion and validation checklists

Phase 4: Automation and Regression Workflows

Improve reproducibility and maintainability.

Planned work:

  • Repeat-trigger controls for scenarios
  • Optional automation for selected labs
  • Before-and-after verification checklists
  • Consistent comparison workflows for broken and fixed traces

Product Principles

To keep SignalLab useful and teachable, every lab should follow a consistent set of principles.

One primary lesson per lab

Each lab should teach one dominant concept. Supporting details are fine, but the learner should always know what the main lesson is.

Fast reproduction

A learner should be able to trigger the issue quickly. If the issue takes too long to reproduce, the lab becomes frustrating and loses teaching value.

Clear symptoms

The issue should be visible and understandable.

Examples:

  • The app crashes
  • The UI freezes
  • Results are wrong
  • An object does not deallocate
  • Search becomes sluggish

Broken and fixed comparison

Whenever possible, each lab should provide a broken and fixed mode so the learner can compare behavior and validate the results of the investigation.

Realistic bugs

The project should prefer realistic app patterns over contrived algorithm puzzles.

Examples of good scenario sources:

  • Data import and parsing
  • Search and filtering
  • Timers and closures
  • Main-thread JSON processing
  • Expensive repeated UI-related work

Apple-native tooling first

The product is built around learning Apple’s own debugging stack, especially:

  • Xcode breakpoints and LLDB
  • Call stack and thread inspection
  • Xcode Memory Graph
  • Instruments Leaks
  • Instruments Allocations
  • Hang analysis
  • Time Profiler
  • Early diagnostics and runtime checks

Proposed App Structure

The codebase should eventually be organized around reusable lab concepts rather than one-off screens.

Possible structure:

  • SignalLabApp/
  • Labs/
  • Shared/
  • Docs/
  • Guides/

Potential shared concepts:

  • LabCatalog
  • LabScenario
  • LabCategory
  • InvestigationGuide
  • BrokenImplementation
  • FixedImplementation

The exact implementation may evolve, but the project should preserve strong separation between shared infrastructure and lab-specific scenario code.

In-App Experience Goals

The app should eventually support:

  • A home screen with all labs grouped by category or difficulty
  • Rich lab detail screens with overview, trigger controls, and hints
  • A clear broken/fixed mode toggle
  • Investigation guides that explain which tool to use first and why
  • Visual summaries of symptoms, tool recommendations, and validation steps
  • A polished, modern interface that feels at home on Apple platforms

Documentation Strategy

SignalLab should be documented like a real teaching product.

Recommended documentation areas:

  • Project vision and roadmap
  • Lab design principles
  • Investigation workflow checklists
  • One guide per lab
  • Contributor guidance for adding future labs
  • Notes for mentors or workshop facilitators

Documentation should explain not only how to use the app, but also why each scenario was designed the way it was.

Success Criteria

SignalLab is successful if a learner can:

  • Launch a lab and reproduce the issue quickly
  • Choose an appropriate first debugging tool
  • Gather evidence from the debugger or Instruments
  • Explain the root cause in simple terms
  • Understand why the fix resolves the issue
  • Build confidence debugging similar problems in real projects

Current Status

SignalLab is now a working iOS lab app with the MVP curriculum implemented and additional diagnostics/Phase 2 labs available in the catalog.

Work completed so far includes:

  • Shared SwiftUI app shell and lab detail scaffold
  • Working catalog navigation for MVP, diagnostics, and Phase 2 labs
  • MVP labs for crash debugging, exception breakpoints, line breakpoints, Memory Graph, hangs, and CPU hotspots
  • Post-MVP diagnostics labs for Thread Performance Checker, Zombies, Thread Sanitizer, and Malloc Stack Logging
  • Phase 2 labs for heap growth, deadlocks, background-thread UI work, main-thread I/O, scroll hitching, startup signposts, and concurrency isolation
  • Memory Graph Lab at MVP quality with the Open Note fixture, Malloc Stack Logging scheme support, and allocation-backtrace workflow
  • Generated SignalLab app icon installed in the Xcode asset catalog

The next major step is a PR review pass focused on consistency, screenshots, and any remaining lab evidence gaps before merging the Memory Graph MVP work.

References

SignalLab is intended to complement Apple’s debugging and performance tooling documentation, not replace it.

Helpful Apple references include:

  • Instruments tutorials
  • Xcode hang analysis guidance
  • Memory, thread, and crash diagnostics guidance
  • WWDC sessions on heap analysis, hang investigation, and debugging tools

Contributing Direction

As the project grows, new labs should only be added if they meet the product’s teaching standards.

A good new lab should:

  • Have a clear primary lesson
  • Reproduce consistently
  • Use realistic code patterns
  • Teach a meaningful Apple debugging workflow
  • Include a clear fixed implementation or explanation
  • Be understandable by the intended audience

Summary

SignalLab is a polished, educational debugging lab for iOS developers.

Its purpose is to make Xcode debugging and Instruments feel practical, approachable, and memorable by teaching through direct investigation of realistic bugs.

The current focus is making the MVP labs concise, reproducible, and consistent enough to teach well. From there, the project can continue expanding into a broader curriculum covering more advanced debugging scenarios.

About

SignalLab is a hands-on iOS learning app for junior and intermediate developers who want practical experience debugging real application problems with Xcode and Instruments.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors