Merge lp:~julian-edwards/launchpad/buildd-regex-bug-719162 into lp:launchpad

Proposed by Julian Edwards
Status: Merged
Approved by: Leonard Richardson
Approved revision: no longer in the source branch.
Merged at revision: 12388
Proposed branch: lp:~julian-edwards/launchpad/buildd-regex-bug-719162
Merge into: lp:launchpad
Diff against target: 184 lines (+101/-52)
2 files modified
lib/canonical/buildd/check-implicit-pointer-functions (+58/-52)
lib/canonical/buildd/tests/test_check_implicit_pointer_functions.py (+43/-0)
To merge this branch: bzr merge lp:~julian-edwards/launchpad/buildd-regex-bug-719162
Reviewer Review Type Date Requested Status
Leonard Richardson (community) Approve
Review via email: mp+49796@code.launchpad.net

Commit message

[r=leonardr][bug=719162] Make buildd pointer check regexes work on natty

Description of the change

= Summary =
Make buildd pointer check regexes work on natty

== Proposed fix ==
64-bit architecture builds have a possible problem with implicit casting of
integers to pointers, which will cause segfaults in the real world. A check
is made for this in the buildds, but unfortunately it's broken on natty
because the regex that's used doesn't pick up the subtle change in compiler
output.

== Pre-implementation notes ==
See the bug.

== Implementation details ==
There's a few changes as I needed to juggle stuff around so that tests could
be written:

 * lib/canonical/buildd/check-implicit-pointer-functions now has a symlink
lib/canonical/buildd/check_implicit_pointer_functions.py so that I can import
it for testing
 * check-implicit-pointer-functions was altered so the code is all inside a
function so it doesn't get run when it's imported.
 * new tests at
lib/canonical/buildd/tests/test_check_implicit_pointer_functions.py

== Tests ==
bin/test -cvv test_check_implicit_pointer_functions

== Demo and Q/A ==
Quite hard, requires some builds on dogfood/staging to test it, but manual
shell testing shows the script is working fine.

To post a comment you must log in.
Revision history for this message
Leonard Richardson (leonardr) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/buildd/check-implicit-pointer-functions'
2--- lib/canonical/buildd/check-implicit-pointer-functions 2010-01-13 23:16:43 +0000
3+++ lib/canonical/buildd/check-implicit-pointer-functions 2011-02-15 12:36:51 +0000
4@@ -35,10 +35,11 @@
5 import re
6 import sys
7
8-implicit_pattern = re.compile("([^:]*):(\d+): warning: implicit declaration "
9- + "of function [`']([^']*)'")
10+implicit_pattern = re.compile(
11+ "([^:]*):(\d+):(\d+:)? warning: implicit declaration "
12+ "of function [`']([^']*)'")
13 pointer_pattern = re.compile(
14- "([^:]*):(\d+): warning: "
15+ "([^:]*):(\d+):(\d+:)? warning: "
16 + "("
17 + "(assignment"
18 + "|initialization"
19@@ -48,53 +49,55 @@
20 + ") makes pointer from integer without a cast"
21 + "|"
22 + "cast to pointer from integer of different size)")
23-last_implicit_filename = ""
24-last_implicit_linenum = -1
25-last_implicit_func = ""
26-
27-errlist = ""
28-
29-in_line = False
30-warn_only = False
31-
32-for arg in sys.argv[1:]:
33- if arg == '--inline':
34- in_line = True
35- elif arg == '--warnonly':
36- warn_only = True
37-
38-rv = 0
39-while True:
40- line = sys.stdin.readline()
41- if in_line:
42- sys.stdout.write(line)
43- sys.stdout.flush()
44- if line == '':
45- break
46- m = implicit_pattern.match(line)
47- if m:
48- last_implicit_filename = m.group(1)
49- last_implicit_linenum = int(m.group(2))
50- last_implicit_func = m.group(3)
51- else:
52- m = pointer_pattern.match(line)
53+
54+def main():
55+ last_implicit_filename = ""
56+ last_implicit_linenum = -1
57+ last_implicit_func = ""
58+
59+ errlist = ""
60+
61+ in_line = False
62+ warn_only = False
63+
64+ for arg in sys.argv[1:]:
65+ if arg == '--inline':
66+ in_line = True
67+ elif arg == '--warnonly':
68+ warn_only = True
69+
70+ rv = 0
71+ while True:
72+ line = sys.stdin.readline()
73+ if in_line:
74+ sys.stdout.write(line)
75+ sys.stdout.flush()
76+ if line == '':
77+ break
78+ m = implicit_pattern.match(line)
79 if m:
80- pointer_filename = m.group(1)
81- pointer_linenum = int(m.group(2))
82- if (last_implicit_filename == pointer_filename
83- and last_implicit_linenum == pointer_linenum):
84- err = "Function `%s' implicitly converted to pointer at " \
85- "%s:%d" % (last_implicit_func, last_implicit_filename,
86- last_implicit_linenum)
87- errlist += err+"\n"
88- print err
89- if not warn_only:
90- rv = 3
91+ last_implicit_filename = m.group(1)
92+ last_implicit_linenum = int(m.group(2))
93+ last_implicit_func = m.group(4)
94+ else:
95+ m = pointer_pattern.match(line)
96+ if m:
97+ pointer_filename = m.group(1)
98+ pointer_linenum = int(m.group(2))
99+ if (last_implicit_filename == pointer_filename
100+ and last_implicit_linenum == pointer_linenum):
101+ err = "Function `%s' implicitly converted to pointer at " \
102+ "%s:%d" % (last_implicit_func, last_implicit_filename,
103+ last_implicit_linenum)
104+ errlist += err+"\n"
105+ print err
106+ if not warn_only:
107+ rv = 3
108
109-if len(errlist):
110- if in_line:
111- print errlist
112- print """
113+ if len(errlist):
114+ if in_line:
115+ print errlist
116+ print """
117
118 Our automated build log filter detected the problem(s) above that will
119 likely cause your package to segfault on architectures where the size of
120@@ -106,7 +109,10 @@
121 on ia64, they are errors. Please correct them for your next upload.
122
123 More information can be found at:
124- http://wiki.debian.org/ImplicitPointerConversions
125-
126-"""
127-sys.exit(rv)
128+http://wiki.debian.org/ImplicitPointerConversions
129+
130+ """
131+ sys.exit(rv)
132+
133+if __name__ == '__main__':
134+ main()
135
136=== added symlink 'lib/canonical/buildd/check_implicit_pointer_functions.py'
137=== target is u'check-implicit-pointer-functions'
138=== added file 'lib/canonical/buildd/tests/test_check_implicit_pointer_functions.py'
139--- lib/canonical/buildd/tests/test_check_implicit_pointer_functions.py 1970-01-01 00:00:00 +0000
140+++ lib/canonical/buildd/tests/test_check_implicit_pointer_functions.py 2011-02-15 12:36:51 +0000
141@@ -0,0 +1,43 @@
142+# Copyright 2011 Canonical Ltd. This software is licensed under the
143+# GNU Affero General Public License version 3 (see the file LICENSE).
144+
145+from lp.testing import TestCase
146+
147+from canonical.buildd.check_implicit_pointer_functions import implicit_pattern
148+from canonical.buildd.check_implicit_pointer_functions import pointer_pattern
149+
150+
151+class TestPointerCheckRegexes(TestCase):
152+
153+ def test_catches_pointer_from_integer_without_column_number(self):
154+ # Regex should match compiler errors that don't include the
155+ # column number.
156+ line = (
157+ "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: "
158+ "warning: assignment makes pointer from integer without a cast")
159+ self.assertIsNot(None, pointer_pattern.match(line))
160+
161+ def test_catches_pointer_from_integer_with_column_number(self):
162+ # Regex should match compiler errors that do include the
163+ # column number.
164+ line = (
165+ "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94:7: "
166+ "warning: assignment makes pointer from integer without a cast")
167+ self.assertIsNot(None, pointer_pattern.match(line))
168+
169+ def test_catches_implicit_function_without_column_number(self):
170+ # Regex should match compiler errors that do include the
171+ # column number.
172+ line = (
173+ "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: "
174+ "warning: implicit declaration of function 'foo'")
175+ self.assertIsNot(None, implicit_pattern.match(line))
176+
177+ def test_catches_implicit_function_with_column_number(self):
178+ # Regex should match compiler errors that do include the
179+ # column number.
180+ line = (
181+ "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94:7: "
182+ "warning: implicit declaration of function 'foo'")
183+ self.assertIsNot(None, implicit_pattern.match(line))
184+