Last active
August 29, 2015 14:04
-
-
Save jonathan-beard/10e2916d228165d050a7 to your computer and use it in GitHub Desktop.
Stupid simple script to get leaks on programs running on OS X...doesn't quite parse the output of ps -A correctly but I don't have time to fix right now and it works well enough to be used.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use strict; | |
use warnings; | |
## | |
# getProcessList - returns an array of an arrays | |
# first index is the pid, second the executable | |
# it refers to | |
## | |
sub getProcessList(); | |
## | |
# runLeaks - writes the output of the "leaks" exe | |
# for each of the pids returned from getProcessList() | |
# first param is the process list, second param is | |
# the filename | |
## | |
sub runLeaks( $$ ); | |
## | |
# processOutput - simply parses the output of the OS X 'leaks' | |
# exe (which it takes as the input param). | |
## | |
sub processOutput( $ ); | |
### | |
# actual program starts here | |
### | |
if( ( 0 + @ARGV ) != 1 ) | |
{ | |
print STDERR "Must provide an outputfile for leak stats as argument, e.g.,\n./findleaks.pl outputfile.csv\nexiting!!\n"; | |
exit( -1 ); | |
} | |
my ($filename) = @ARGV; | |
my $processList = getProcessList(); | |
runLeaks( $processList, $filename ); | |
exit( 0 ); | |
## | |
# start subroutines | |
## | |
sub getProcessList() | |
{ | |
my @rawlist = split/\n/, `ps -A`; | |
## | |
# Discard heading | |
## | |
shift( @rawlist ); | |
my @output; | |
foreach my $line( @rawlist ) | |
{ | |
my @fields = split /\s+/, $line; | |
my $pid = 0; | |
my $exe = ""; | |
my $index = 0; | |
while ( ! $pid =~ m/\d+/ ) | |
{ | |
$pid = shift( @fields ); | |
} | |
$exe = pop( @fields ); | |
push( @output, [ $pid, $exe ]); | |
} | |
return( \@output ); | |
} | |
sub runLeaks( $$ ) | |
{ | |
my ($list, $outputfile) = @_; | |
open(OUTPUT, ">", $outputfile) or die "Couldn't open $outputfile\n"; | |
foreach my $info (@$list) | |
{ | |
my $pid = $info->[ 0 ]; | |
my $data = ""; | |
$data = `leaks $pid 2> /dev/null`; | |
if( ! $data eq "" ) | |
{ | |
my $usefulLine = ""; | |
$usefulLine = processOutput( $data ); | |
print OUTPUT "$usefulLine\n"; | |
print OUTPUT join('', "#" x 80 )."\n"; | |
} | |
} | |
close( OUTPUT ); | |
} | |
sub processOutput( $ ) | |
{ | |
my ($leak) = @_; | |
my @lines = split /\n/, $leak; | |
my $output = ""; | |
foreach my $line ( @lines ) | |
{ | |
if( $line =~ m/leaks for/ || $line=~ m/leak for/ ) | |
{ | |
$output .= $line; | |
return( $output ); | |
} | |
elsif( $line =~ m/Path: / ) | |
{ | |
$output .= $line."\n"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to throw an error when output file is not given, other than that error checking is rather basic with corner cases more than likely causing undefined behavior.