56 """The routine that kicks off processing a ref file
59 filename The full path to the file to process
63 - A list of objects whose lifetimes were completed
64 (i.e., finished objects)
65 - A list of objects referenced after destruction
66 (i.e., invalid objects)
67 - A list of objects whose lifetimes were not completed
68 (i.e., leaked objects)
69 - A list of objects whose lifetimes are skewed
70 (i.e., Object history starting with an unusual ref count)
78 filename = options.filepath
80 with open(filename,
'r')
as ref_file:
87 obj = parsed_line[
'addr']
89 if obj
not in current_objects:
90 current_objects[obj] = {
'log': [],
'curcount': 1}
91 if 'constructor' in parsed_line[
'state']:
94 elif 'invalid' in parsed_line[
'state']:
96 current_objects[obj][
'curcount'] = 0
98 invalid_objects.append((obj, current_objects[obj]))
99 elif 'destructor' in parsed_line[
'state']:
100 current_objects[obj][
'curcount'] = 0
102 skewed_objects.append((obj, current_objects[obj]))
104 current_objects[obj][
'curcount'] = int(
105 parsed_line[
'state'])
107 skewed_objects.append((obj, current_objects[obj]))
109 current_objects[obj][
'curcount'] += int(parsed_line[
'delta'])
112 if 'constructor' in parsed_line[
'state']:
113 parsed_line[
'state'] =
'**constructor**'
114 elif 'destructor' in parsed_line[
'state']:
115 parsed_line[
'state'] =
'**destructor**'
117 current_objects[obj][
'log'].append(
118 "[%s] %s:%s %s: %s %s - [%s]" % (
119 parsed_line[
'thread_id'],
122 parsed_line[
'function'],
123 parsed_line[
'delta'],
125 parsed_line[
'state']))
131 if current_objects[obj][
'curcount'] <= 0:
132 if current_objects[obj][
'curcount'] < 0:
133 current_objects[obj][
'log'].append(
134 "[%s] %s:%s %s: %s %s - [%s]" % (
135 parsed_line[
'thread_id'],
138 parsed_line[
'function'],
140 "Object abnormally finalized",
141 "**implied destructor**"))
146 invalid_objects.append((obj, current_objects[obj]))
147 if not invalid
and options.normal:
148 finished_objects.append((obj, current_objects[obj]))
149 del current_objects[obj]
152 for (key, lines)
in current_objects.items():
153 leaked_objects.append((key, lines))
154 return (finished_objects, invalid_objects, leaked_objects, skewed_objects)
176 """Main entry point for the script"""
183 parser = OptionParser()
185 parser.add_option(
"-f",
"--file", action=
"store", type=
"string",
186 dest=
"filepath", default=
"/var/log/asterisk/refs",
187 help=
"The full path to the refs file to process")
188 parser.add_option(
"-i",
"--suppress-invalid", action=
"store_false",
189 dest=
"invalid", default=
True,
190 help=
"If specified, don't output invalid object "
192 parser.add_option(
"-l",
"--suppress-leaks", action=
"store_false",
193 dest=
"leaks", default=
True,
194 help=
"If specified, don't output leaked objects")
195 parser.add_option(
"-n",
"--suppress-normal", action=
"store_false",
196 dest=
"normal", default=
True,
197 help=
"If specified, don't output objects with a "
199 parser.add_option(
"-s",
"--suppress-skewed", action=
"store_false",
200 dest=
"skewed", default=
True,
201 help=
"If specified, don't output objects with a "
204 (options, args) = parser.parse_args(argv)
206 if not options.invalid
and not options.leaks
and not options.normal \
207 and not options.skewed:
208 print(
"All options disabled", file=sys.stderr)
211 if not os.path.isfile(options.filepath):
212 print(
"File not found: %s" % options.filepath, file=sys.stderr)
221 if options.invalid
and len(invalid_objects):
225 if options.leaks
and len(leaked_objects):
229 if options.skewed
and len(skewed_objects):
236 except (KeyboardInterrupt, SystemExit, IOError):
237 print(
"File processing cancelled", file=sys.stderr)