forked from Archive/PX4-Autopilot
Poor man's profiler - proper stack folder that handles generic C++ types
This commit is contained in:
parent
1898b51c74
commit
d1abf9c133
|
@ -84,7 +84,7 @@ gdberrfile=/tmp/pmpn-gdberr.log
|
||||||
#
|
#
|
||||||
cd $root
|
cd $root
|
||||||
|
|
||||||
if [[ $nsamples > 0 && "$taskname" != "" ]]
|
if [[ $nsamples > 0 ]]
|
||||||
then
|
then
|
||||||
[[ $append = 0 ]] && (rm -f $stacksfile; echo "Old stacks removed")
|
[[ $append = 0 ]] && (rm -f $stacksfile; echo "Old stacks removed")
|
||||||
|
|
||||||
|
@ -92,12 +92,20 @@ then
|
||||||
|
|
||||||
for x in $(seq 1 $nsamples)
|
for x in $(seq 1 $nsamples)
|
||||||
do
|
do
|
||||||
|
if [[ "$taskname" = "" ]]
|
||||||
|
then
|
||||||
|
arm-none-eabi-gdb $elf --batch -ex "set print asm-demangle on" -ex bt \
|
||||||
|
2> $gdberrfile \
|
||||||
|
| sed -n 's/\(#.*\)/\1/p' \
|
||||||
|
>> $stacksfile
|
||||||
|
else
|
||||||
arm-none-eabi-gdb $elf --batch -ex "set print asm-demangle on" \
|
arm-none-eabi-gdb $elf --batch -ex "set print asm-demangle on" \
|
||||||
-ex "source $root/Debug/Nuttx.py" \
|
-ex "source $root/Debug/Nuttx.py" \
|
||||||
-ex "show mybt $taskname" \
|
-ex "show mybt $taskname" \
|
||||||
2> $gdberrfile \
|
2> $gdberrfile \
|
||||||
| sed -n 's/0\.0:\(#.*\)/\1/p' \
|
| sed -n 's/0\.0:\(#.*\)/\1/p' \
|
||||||
>> $stacksfile
|
>> $stacksfile
|
||||||
|
fi
|
||||||
echo -e '\n\n' >> $stacksfile
|
echo -e '\n\n' >> $stacksfile
|
||||||
echo -ne "\r$x/$nsamples"
|
echo -ne "\r$x/$nsamples"
|
||||||
sleep $sleeptime
|
sleep $sleeptime
|
||||||
|
@ -106,7 +114,7 @@ then
|
||||||
echo
|
echo
|
||||||
echo "Stacks saved to $stacksfile"
|
echo "Stacks saved to $stacksfile"
|
||||||
else
|
else
|
||||||
echo "Sampling skipped - set 'nsamples' and 'taskname' to re-sample."
|
echo "Sampling skipped - set 'nsamples' to re-sample."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -114,22 +122,103 @@ fi
|
||||||
#
|
#
|
||||||
[ -f $stacksfile ] || die "Where are the stack samples?"
|
[ -f $stacksfile ] || die "Where are the stack samples?"
|
||||||
|
|
||||||
cat $stacksfile | perl -e 'use File::Basename;
|
cat $stacksfile | python -c "
|
||||||
my $current = "";
|
#
|
||||||
my %stacks;
|
# This stack folder correctly handles C++ types.
|
||||||
while(<>) {
|
#
|
||||||
if(m/^#[0-9]*\s*0x[a-zA-Z0-9]*\s*in (.*) at (.*)/) {
|
|
||||||
my $x = $1 eq "None" ? basename($2) : ("$1 at " . basename($2));
|
from __future__ import print_function, division
|
||||||
if ($current eq "") { $current = $x; }
|
import fileinput, collections, os
|
||||||
else { $current = $x . ";" . $current; }
|
|
||||||
} elsif(!($current eq "")) {
|
def enforce(x, msg='Invalid input'):
|
||||||
$stacks{$current} += 1;
|
if not x:
|
||||||
$current = "";
|
raise Exception(msg)
|
||||||
}
|
|
||||||
}
|
def split_first_part_with_parens(line):
|
||||||
foreach my $k (sort { $a cmp $b } keys %stacks) {
|
LBRACES = {'(':'()', '<':'<>', '[':'[]', '{':'{}'}
|
||||||
print "$k $stacks{$k}\n";
|
RBRACES = {')':'()', '>':'<>', ']':'[]', '}':'{}'}
|
||||||
}' > $foldfile
|
braces = collections.defaultdict(int)
|
||||||
|
out = ''
|
||||||
|
for ch in line:
|
||||||
|
out += ch
|
||||||
|
# special cases
|
||||||
|
if out.endswith('operator>') or out.endswith('operator->'): # gotta love c++
|
||||||
|
braces['<>'] += 1
|
||||||
|
if out.endswith('operator<'):
|
||||||
|
braces['<>'] -= 1
|
||||||
|
# counting parens
|
||||||
|
if ch in LBRACES.keys():
|
||||||
|
braces[LBRACES[ch]] += 1
|
||||||
|
if ch in RBRACES.keys():
|
||||||
|
braces[RBRACES[ch]] -= 1
|
||||||
|
# sanity check
|
||||||
|
for v in braces.values():
|
||||||
|
enforce(v >= 0, 'Unaligned braces: ' + str(dict(braces)))
|
||||||
|
# termination condition
|
||||||
|
if ch == ' ' and sum(braces.values()) == 0:
|
||||||
|
break
|
||||||
|
out = out.strip()
|
||||||
|
return out, line[len(out):]
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
def take_path(line, output):
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith('at '):
|
||||||
|
line = line[3:].strip()
|
||||||
|
if line:
|
||||||
|
output['file_full_path'] = line.rsplit(':', 1)[0].strip()
|
||||||
|
output['file_base_name'] = os.path.basename(output['file_full_path'])
|
||||||
|
output['line'] = int(line.rsplit(':', 1)[1])
|
||||||
|
return output
|
||||||
|
|
||||||
|
def take_args(line, output):
|
||||||
|
line = line.lstrip()
|
||||||
|
if line[0] == '(':
|
||||||
|
output['args'], line = split_first_part_with_parens(line)
|
||||||
|
return take_path(line.lstrip(), output)
|
||||||
|
|
||||||
|
def take_function(line, output):
|
||||||
|
output['function'], line = split_first_part_with_parens(line.lstrip())
|
||||||
|
return take_args(line.lstrip(), output)
|
||||||
|
|
||||||
|
def take_mem_loc(line, output):
|
||||||
|
line = line.lstrip()
|
||||||
|
if line.startswith('0x'):
|
||||||
|
end = line.find(' ')
|
||||||
|
num = line[:end]
|
||||||
|
output['memloc'] = int(num, 16)
|
||||||
|
line = line[end:].lstrip()
|
||||||
|
end = line.find(' ')
|
||||||
|
enforce(line[:end] == 'in')
|
||||||
|
line = line[end:].lstrip()
|
||||||
|
return take_function(line, output)
|
||||||
|
|
||||||
|
def take_frame_num(line, output):
|
||||||
|
line = line.lstrip()
|
||||||
|
enforce(line[0] == '#')
|
||||||
|
end = line.find(' ')
|
||||||
|
num = line[1:end]
|
||||||
|
output['frame_num'] = int(num)
|
||||||
|
return take_mem_loc(line[end:], output)
|
||||||
|
|
||||||
|
return take_frame_num(line, {})
|
||||||
|
|
||||||
|
stacks = collections.defaultdict(int)
|
||||||
|
current = ''
|
||||||
|
|
||||||
|
for line in fileinput.input():
|
||||||
|
line = line.strip()
|
||||||
|
if line:
|
||||||
|
inf = parse(line)
|
||||||
|
fun = inf['function']
|
||||||
|
current = (fun + ';' + current) if current else fun
|
||||||
|
elif current:
|
||||||
|
stacks[current] += 1
|
||||||
|
current = ''
|
||||||
|
|
||||||
|
for s, f in sorted(stacks.items(), key=lambda (s, f): s):
|
||||||
|
print(s, f)
|
||||||
|
" > $foldfile
|
||||||
|
|
||||||
echo "Folded stacks saved to $foldfile"
|
echo "Folded stacks saved to $foldfile"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue