docs/project/hacking_tips.pod - A Collection of Useful Tips for Parrot Hacking


Parrot is a complex project that can fail in mysterious and spectacular ways and has a tendency to exhibit surprising performance bottlenecks. When that happens, you have the exciting job of figuring out what's wrong and how to fix it. This document exists to provide a repository of knowledge and techniques to make that job easier.

Debugging Parrot (external tools)


gdb should be a familiar tool, but many developers only use a small subset of its capabilities. This section covers some of its lesser known features that may come in handy while debugging Parrot. Note that this is not intended to be an exhaustive resource. If your favorite technique is missing, please add it.

Conditional Breakpoints

gdb's breakpoints are great for inspecting the state of a running (or recently crashed) program, but sometimes the function or line you want to break on will be entered many times before it becomes interesting. gdb allows breakpoints to be tied to conditions like so:

  (gdb) br Parrot_FixedPMCArray_elements if _self == 0
  Breakpoint 1 at 0xb7e69830: file ./src/pmc/fixedpmcarray.c, line 163.


A very nice feature implemented by Nolan Lum as a Google Code-In project is gdb pretty-printing support for Parrot's STRING and PMC structs. This makes those structs much more discoverable. Instead of seeing this: $1 = {flags = 512, vtable = 0x8096388, data = 0x80b64a4, _metadata = 0x0} when debugging a PMC or STRING, you'll see this: <INSERT AWESOME GDB 7.1 OUTPUT HERE> Note that you'll need gdb 7.1 or later for this to work.


Reducing Nondeterminism

When trying to chase down GC bugs, reproducibility is often a major barrier. These tools and techniques reduce randomness in a running interpreter and may make garbage collection bugs (and other memory-sensitive problems) easier to isolate.


Disabling address space layout and VDSO can make a program run less randomly. Be careful with this, though. Disabling ASLR also makes certain kinds of attacks easier to perform. Don't do this on a production system, and be sure to reenable these settings once you're done debugging.

 sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
 sudo sh -c "echo 0 > /proc/sys/vm/vdso_enabled"

Hash Seed Randomization

Parrot's hashing algorithms use a randomized hash seed. This makes execution of PIR code less vulnerable to an algorithmic complexity attack based on the performance of our hashing algorithm, but also means that iteration through an unordered hash won't always happen in the same order. If your bug fails intermittently, try passing several different hash seeds to the parrot executable until you find one that triggers the bug:

  parrot --hash-seed=0x1234 ./perl6.pbc foo.p6

Debugging Parrot (internal tools)

When it crashes, Parrot makes an effort to provide a PIR-level backtrace in addition the typical C-level backtrace. This may not be entirely useful because libparrot gets its debugging information from imcc, but there's potential for it to help.

TODO: parrot_debugger

Profiling (external tools)

TODO: valgrind (memgrind, callgrind)

Profiling (internal tools)

TODO: profiling runcore


When hacking on the Configure system, it's helpful to be able to run a single step instead of having to go through the whole process. tools/dev/ exists for that purpose:

  perl tools/dev/ --step=gen::makefile

When hacking on Makefile template files such as config/gen/makefiles/, please: