1. Overview
  2. Debugging workflow
  3. Debugging workflow: CI
  4. Basic interface
  5. Visualizing control flow
  6. Call stacks
  7. Explaining dataflow
  8. Multiprocess
  9. Search box
  10. Source files
  11. Condition and print expressions
  12. Toolbox
  13. Alerts
  14. Application logs
  15. Callees
  16. View operators
  17. Notebook
  18. Instruction execution
  19. Javascript
  20. Browser UI integration
  21. Screenshots
  22. Additional views
  23. GDB
  24. System debug info
  25. Compiler issues
  26. The Pernosco vision
  27. Related work

Overview

Many developers spend a lot of time debugging, using traditional debuggers or no tools at all. Pernosco is a much better debugger that can reduce this debugging time dramatically and make it more fun.

Try out Pernosco on some examples: libbcc, Firefox, Chromium JS

Pernosco enables new, more flexible workflows

Traditional debugging: Reproduce a bug many times while you debug it

Pernosco: Record your program once and debug at your leisure

Traditional: Debugging interrupts the program

Pernosco: Your program runs normally during recording

Traditional: The developer has to reproduce the bug locally

Pernosco: Record the bug on any machine (local, QA, CI or user), debug it from anywhere

Pernosco revolutionizes the debugging interface

Traditional debugging: Shows you the current program state, forcing you to singlestep to see what happens over time

Pernosco: Shows you program states across time, so you see what happened (e.g. control flow or instructions executed) at a glance

Traditional: Runs the program to examine states at other times

Pernosco: Precomputes all program states so shifting time is instantaneous

Traditional: Set breakpoints on functions and source lines, hit them one at a time

Pernosco: Query for executions of specific functions and lines (via unified search-oriented interface) and get bulk results instantly

Traditional: Can walk upward in the dynamic call graph, but not downward

Pernosco: Navigate the full dynamic call graph by showing the callees of the current function activation as well as call stacks

Traditional: Debugging multiple processes is painful

Pernosco: Multiprocess debugging is first-class

Traditional: Advanced users can track dataflow using data watchpoints, but only one step at a time

Pernosco: Easy tracking of data values back to their sources, across multiple copy steps and shared memory

Traditional: Limited ability to manipulate debugger output without scripting

Pernosco: Merge views to create custom visualizations with simple drag and drop

Traditional: Non-discoverable interface so many great features you never learn about

Pernosco: Toolbox exposes most Pernosco features

Pernosco leverages knowledge of applications and frameworks

Traditional debugging: Does not know about test failures

Pernosco: Highlights fatal errors and can be taught about test failures

Traditional: Doesn't know about application/framework logging

Pernosco: Can be taught to extract application/framework logs even if logging was disabled during recording

Traditional: Doesn't know how your application draws to the screen

Pernosco: Captures rendered windows and explains how pixel data was computed

Pernosco supports and supercharges traditional debugging approaches

Traditional debugging: Feels comfortably familiar

Pernosco: Deeply integrates gdb and boosts it with unprecedented speed and features

Traditional: You like "printf debugging", but it can be a pain

Pernosco: Annotate function calls and executed lines with condition and print expressions and get results instantly

Traditional: Acquiring debug symbols and sources for system libraries is hard work

Pernosco: Handles that for you

Pernosco enables collaboration

Traditional debugging: Your debugging progress is invisible and transient; take notes in an editor

Pernosco: Track your debugging state in our integrated notebook

Traditional: Your debugging progress can't easily be shared

Pernosco: Other users can easily share your Pernosco sessions and notebooks to work together to understand a bug

Pernosco crosses language boundaries

Traditional debugging: Debugging compiled/VM languages together is practically impossible

Pernosco: Debug compiled languages and VM languages (so far, V8 JS) together

Pernosco has a unifying vision

Traditional debugging: Designed around what could be easily implemented by inspecting program state at a single point in time

Pernosco: Designed from scratch with the assumption that we can compute any information about program states we need, and therefore we can treat debugging as a data analysis problem

Traditional debugging: Widely understood to suck

Pernosco: Shows that investing in debugging can make it great

Caveats and restrictions

Pernosco currently targets C, C++, Rust, Ada, and V8 JS (e.g. node.js) applications that run on x86-64 Linux and work with rr.

Currently we provide debuginfo for system libraries for Ubuntu distributions only.

A Pernosco recording contains binaries and input data for your project. We keep them secret and we won't use them for anything other than your debugging session, but if you need to keep that data on-premises we offer an on-premises version of Pernosco — contact us.