my @lines; # Array of lines to be kept for output. push(@lines, ''); # Preload output array with null line 0 (for correct line counts). my %locks; # Hash of currently open locks. while () { my $count = push(@lines, $_) - 1; Log 2, "Analysing line $count"; if ($_ =~ /Mutex\((.*)\)::(\w+)/) { # Regexp to obtain address and action info from line. Log 2, "Address and action parsed correctly."; my $address = $1; my $action = $2; if ($action eq 'locking') { Log 2, "Address $address locked at line $count"; if (defined $locks{$address}) { Log 0, "ERROR: Address $address locked at line $count, but already locked at line $locks{$address}."; } $locks{$address} = $count; } if ($action eq 'unlocked') { Log 2, "Address $address unlocked at line $count"; unless (defined $locks{$address}) { Log 0, "ERROR: Address $address not locked, but unlocked at line $count."; } else { $lines[$locks{$address}] = ''; Log 1, "Found a match for address $address: locked $locks{$address}, unlocked $count. Removing from output."; } $locks{$address} = ''; $lines[$count] = ''; } } } foreach (@lines) {print}