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

Application logs

First-class debugging tools should reduce developers' reliance on bespoke logging, but logging code in applications captures and abstracts information important to developers, and will no doubt remain useful. Pernosco leverages logging by capturing log output and presenting it in a dedicated log view, using built-in knowledge of logging frameworks used by our customers. When log output is categorized by "log modules", Pernosco indexes on those modules to support efficient filtering by module. Clicking on log output jumps to where and when it was produced.

For applications like Firefox, enabling all logging is prohibitively expensive, so most logs are disabled by default and developers opt into collecting subsets of logs. This is cumbersome, often requiring multiple iterations of enabling logs, running tests, and investigating results. Worse, each iteration may behave differently, exhibiting different bugs or no bug at all, either because the application is nondeterministic or because the logging itself perturbs the application. Pernosco fixes this by recording test execution with all logging disabled and then capturing log output during a specially instrumented replay. During this replay, whenever the application tests whether logging is enabled, Pernosco forks the program state and executes ahead as if logging is enabled, capturing any log results. Once control returns to the main execution path, the forked state is discarded and replay continues normally. Each "diversion" needs to be very efficient because they can occur at a very high rate.

This approach is not perfect. For example, sometimes logging code will capture some data (e.g. a timestamp) if logging is enabled, then do some work, and then log results based on the previously captured data. With our approach, after the first step the captured data will be thrown away and the actual log output will fail. Nevertheless it generally works well in practice.

<< Alerts Callees >>