1#!/usr/bin/env python3
2# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
3
4import sys
5
6# to use this script, first run 'sample' to sample your libtorrent based process
7# the output can then be passed to this script to auto-fold call stacks at
8# relevant depths and to filter out low sample counts
9f = open(sys.argv[1])
10
11
12def parse_line(line):
13    indentation = 0
14    while indentation < len(line) and line[indentation] == ' ':
15        indentation += 1
16    if indentation == 0:
17        return (0, 0, '')
18
19    line = line.strip().split(' ')
20    samples = int(line[0])
21    fun = ' '.join(line[1:])
22
23    return (indentation, samples, fun)
24
25
26fold = -1
27
28try:
29    sample_limit = int(sys.argv[2])
30except Exception:
31    sample_limit = 5
32
33fun_samples = {}
34
35for line in f:
36    if 'Sort by top of stack' in line:
37        break
38
39    indentation, samples, fun = parse_line(line)
40    if samples < sample_limit:
41        continue
42    if fold != -1 and indentation > fold:
43        continue
44    fold = -1
45
46    if '__gnu_cxx::__normal_iterator<' in fun:
47        fold = indentation - 1
48        continue
49
50    if 'boost::_bi::bind_t' in fun:
51        continue
52    if 'boost::_bi::list' in fun:
53        continue
54    if 'boost::_mfi::mf' in fun:
55        continue
56    if 'boost::_bi::storage' in fun:
57        continue
58
59# should only add leaves
60    if fun in fun_samples:
61        fun_samples[fun] += samples
62    else:
63        fun_samples[fun] = samples
64
65    output = '%s%-4d %s' % (' ' * (indentation / 2), samples, fun)
66    if len(output) > 200:
67        output = output[0:200]
68    print(output)
69
70    if 'invariant_checker_impl' in fun:
71        fold = indentation
72    if 'free_multiple_buffers' in fun:
73        fold = indentation
74    if 'libtorrent::condition::wait' in fun:
75        fold = indentation
76    if 'allocate_buffer' in fun:
77        fold = indentation
78    if '::find_POD' in fun:
79        fold = indentation
80    if 'SHA1_Update' in fun:
81        fold = indentation
82    if 'boost::detail::function::basic_vtable' in fun:
83        fold = indentation
84    if 'operator new' in fun:
85        fold = indentation
86    if 'malloc' == fun:
87        fold = indentation
88    if 'free' == fun:
89        fold = indentation
90    if 'std::_Rb_tree' in fun:
91        fold = indentation
92    if 'pthread_cond_wait' in fun:
93        fold = indentation
94    if 'mp_exptmod' == fun:
95        fold = indentation
96    if '::check_invariant()' in fun:
97        fold = indentation
98    if 'libtorrent::condition::wait' in fun:
99        fold = indentation
100    if '_sigtramp' in fun:
101        fold = indentation
102    if 'time_now_hires' in fun:
103        fold = indentation
104    if 'libtorrent::sleep' in fun:
105        fold = indentation
106    if 'puts' == fun:
107        fold = indentation
108    if 'boost::asio::basic_stream_socket' in fun:
109        fold = indentation
110    if 'recvmsg' == fun:
111        fold = indentation
112    if 'sendmsg' == fun:
113        fold = indentation
114    if 'semaphore_signal_trap' == fun:
115        fold = indentation
116    if 'boost::detail::atomic_count::operator' in fun:
117        fold = indentation
118    if 'pthread_mutex_lock' == fun:
119        fold = indentation
120    if 'pthread_mutex_unlock' == fun:
121        fold = indentation
122    if '>::~vector()' == fun:
123        fold = indentation
124    if 'szone_free_definite_size' == fun:
125        fold = indentation
126    if 'snprintf' == fun:
127        fold = indentation
128    if 'usleep' == fun:
129        fold = indentation
130    if 'pthread_mutex_lock' == fun:
131        fold = indentation
132    if 'pthread_mutex_unlock' == fun:
133        fold = indentation
134    if 'std::string::append' in fun:
135        fold = indentation
136    if 'getipnodebyname' == fun:
137        fold = indentation
138    if '__gnu_debug::_Safe_iterator<std::' in fun:
139        fold = indentation
140    if 'fflush' == fun:
141        fold = indentation
142    if 'vfprintf' == fun:
143        fold = indentation
144    if 'fprintf' == fun:
145        fold = indentation
146    if 'BN_mod_exp' == fun:
147        fold = indentation
148    if 'BN_CTX_free' == fun:
149        fold = indentation
150    if 'cerror' == fun:
151        fold = indentation
152    if '0xffffffff' == fun:
153        fold = indentation
154
155list = []
156for k in fun_samples:
157    list.append((fun_samples[k], k))
158
159list = sorted(list, reverse=True)
160
161for i in list:
162    print('%-4d %s' % (i[0], i[1]))
163