fastmail / Moonpig

the moonpig billing system
69 stars 12 forks source link

t/storage.t fails consumes memory until it dies #4

Open mjdominus opened 10 years ago

mjdominus commented 10 years ago

The following is the output of the command /usr/bin/time --verbose perl5.18.1 -Ilib t/storage.t :

    Deep recursion on subroutine "YAML::Dumper::_prewalk" at /usr/local/lib/perl5/site_perl/5.18.1/YAML/Dumper.pm line 79.

    Command terminated by signal 9
    Command being timed: "perl5.18.1 -Ilib t/storage.t"
    User time (seconds): 27.38
    System time (seconds): 1.99
    Percent of CPU this job got: 57%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:51.13
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 6454352
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 29
    Minor (reclaiming a frame) page faults: 404321
    Voluntary context switches: 1006
    Involuntary context switches: 4422
    Swaps: 0
    File system inputs: 25848
    File system outputs: 520
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0
mjdominus commented 10 years ago

The problem is as follows: storage.t throws a large, complex value as an exception. This is handled by an exception reported built in Moonpig::Role::Env::ExceptionReportEmail. The exception reporter defines four summarizers, the last of which is a fallback summarizer that calls ->dump on the exception. This is handled by Exception::Reporter::Dumper::YAML, which eventually uses YAML::Dump() to dump the exception value.

But YAML::Dump has some horrible behavior under perl 5.18.2 and 5.19.6 that causes it to go into the infinite loop or crash in some other horrible way; I sent Ingy a bug report about it. It behaves properly under 5.10.1.

To work around the bug, change Exception::Reporter::Dumper::YAML to use YAML::XS::Dump instead of YAML::Dump.