1 '''
2 Created on Oct 9, 2014
3
4 @author: decoder
5 '''
6 import json
7 import unittest
8
9 from FTB.ProgramConfiguration import ProgramConfiguration
10 from FTB.Signatures.CrashInfo import CrashInfo, NoCrashInfo
11 from FTB.Signatures.CrashSignature import CrashSignature
12 from FTB.Signatures.Matchers import StringMatch
13 from FTB.Signatures.Symptom import StackFramesSymptom
14
15
16 testTrace1 = """Program received signal SIGSEGV, Segmentation fault.
17 GetObjectAllocKindForCopy (obj=0x7ffff54001b0, nursery=...) at /srv/repos/mozilla-central/js/src/gc/Nursery.cpp:369
18 369 if (obj->is<ArrayObject>()) {
19 #0 GetObjectAllocKindForCopy (obj=0x7ffff54001b0, nursery=...) at /srv/repos/mozilla-central/js/src/gc/Nursery.cpp:369
20 #1 js::Nursery::moveToTenured (this=0x1673be0, trc=0x7fffffffa2d0, src=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Nursery.cpp:570
21 #2 0x00000000004d167a in MinorGCCallback (thingp=0x7fffffff9fd0, jstrc=<optimized out>, kind=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Nursery.cpp:721
22 #3 js::Nursery::MinorGCCallback (jstrc=<optimized out>, thingp=0x7fffffff9fd0, kind=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Nursery.cpp:717
23 #4 0x00000000004b8690 in MarkInternal<JSObject> (trc=0x7fffffffa2d0, thingp=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:317
24 #5 0x00000000004cc55e in MarkValueInternal (v=0x7fffffffa5d8, trc=0x7fffffffa2d0) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:804
25 #6 MarkValueInternal (v=0x7fffffffa5d8, trc=0x7fffffffa2d0) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:827
26 #7 js::gc::MarkValueRoot (trc=<optimized out>, v=0x7fffffffa5d8, name=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:831
27 rax 0x2b2b2b2b 3110627432037296939
28 rbx 0xf54001b0 140737308000688
29 rcx 0xbad0bad1 3134241489
30 rdx 0x1656120 23421216
31 rsi 0xffffa2d0 140737488331472
32 rdi 0x1673be0 23542752
33 rbp 0xf54001b0 140737308000688
34 rsp 0xffff9f10 140737488330512
35 r8 0x0 0
36 r9 0x0 0
37 r10 0x1 1
38 r11 0x1 1
39 r12 0x0 -1266637395197952
40 r13 0xffffa2d0 140737488331472
41 r14 0x1673be0 23542752
42 r15 0x201 513
43 rip 0x4d0b32 <js::Nursery::moveToTenured(js::gc::MinorCollectionTracer*, JSObject*)+34>
44 => 0x4d0b32 <js::Nursery::moveToTenured(js::gc::MinorCollectionTracer*, JSObject*)+34>: mov (%rax),%r8
45 """
46
47 testTrace2 = """Program terminated with signal 11, Segmentation fault.
48 #0 JSObject::markChildren (this=0x7fc33ef5a060, trc=0x3538be0)
49 at /srv/repos/mozilla-central/js/src/jsobj.cpp:4081
50 4081 if (clasp->trace)
51 Loading JavaScript value pretty-printers; see js/src/gdb/README.
52 If they cause trouble, type: disable pretty-printer .* SpiderMonkey
53 #0 JSObject::markChildren (this=(JSObject * const) 0x7fc33ef5a060 Cannot access memory at address 0x4949494949494949, trc=0x3538be0) at /srv/repos/mozilla-central/js/src/jsobj.cpp:4081
54 #1 0x00000000004e11e3 in MarkChildren (obj=(JSObject *) 0x7fc33ef5a060 Cannot access memory at address 0x4949494949494949, trc=0x3538be0) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:1323
55 #2 js::TraceChildren (trc=0x3538be0, thing=0x7fc33ef5a060, kind=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:1934
56 #3 0x0000000000625d87 in js::gc::GCRuntime::startVerifyPreBarriers (this=this@entry=0x33ac568) at /srv/repos/mozilla-central/js/src/gc/Verifier.cpp:239
57 #4 0x0000000000633a5e in maybeVerifyPreBarriers (always=<optimized out>, this=0x33ac568) at /srv/repos/mozilla-central/js/src/gc/Verifier.cpp:563
58 #5 js::gc::MaybeVerifyBarriers (cx=<optimized out>, always=<optimized out>) at /srv/repos/mozilla-central/js/src/gc/Verifier.cpp:588
59 #6 0x00000000007c8660 in js::jit::CheckOverRecursedWithExtra (cx=0x33ce390, frame=<optimized out>, extra=<optimized out>, earlyCheck=<optimized out>) at /srv/repos/mozilla-central/js/src/jit/VMFunctions.cpp:153
60 #7 0x00007fc33ee95394 in ?? ()
61 #8 0x0000000000000000 in ?? ()
62 rax 0x4949494949494949 5280832617179597129
63 rbx 0x7fc33ef5a060 140476551635040
64 rcx 0x4949494949494949 5280832617179597129
65 rdx 0x4 4
66 rsi 0xa8ae16 11054614
67 rdi 0x3538be0 55806944
68 rbp 0x3538be0 55806944
69 rsp 0x7fff9aec80c0 140735792578752
70 r8 0x0 0
71 r9 0x2cd1 11473
72 r10 0x37d2580 58533248
73 r11 0x4000 16384
74 r12 0x7fc3240c5030 140476100137008
75 r13 0x2 2
76 r14 0x7fc3240c4ff0 140476100136944
77 r15 0x0 0
78 rip 0x84de35 <JSObject::markChildren(JSTracer*)+53>
79 => 0x84de35 <JSObject::markChildren(JSTracer*)+53>: mov (%rax),%rax
80 0x84de38 <JSObject::markChildren(JSTracer*)+56>: mov 0x68(%rax),%rax
81 """
82
83 testTrace3 = """ASAN:SIGSEGV
84 =================================================================
85 ==7116==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x0000014662ba sp 0x7fffe804f180 bp 0x7fffe804f250 T0)
86 #0 0x14662b9 in JSObject::getClass() const /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jsobj.h:128
87 #1 0x14662b9 in bool JSObject::is<js::PropertyIteratorObject>() const /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jsobj.h:520
88 #2 0x14662b9 in js::CloseIterator(JSContext*, JS::Handle<JSObject*>) /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jsiter.cpp:1065
89 #3 0x14668e2 in js::UnwindIteratorForException(JSContext*, JS::Handle<JSObject*>) /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jsiter.cpp:1100
90 #4 0xe989c0 in js::jit::CloseLiveIterator(JSContext*, js::jit::InlineFrameIterator const&, unsigned int) /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jit/JitFrames.cpp:388
91 #5 0xe989c0 in js::jit::HandleExceptionIon(JSContext*, js::jit::InlineFrameIterator const&, js::jit::ResumeFromException*, bool*) /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jit/JitFrames.cpp:464
92 #6 0xe989c0 in js::jit::HandleException(js::jit::ResumeFromException*) /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jit/JitFrames.cpp:782
93
94 AddressSanitizer can not provide additional info.
95 SUMMARY: AddressSanitizer: SEGV /home/ownhero/homes/mozilla/repos/mozilla-central/js/src/jsobj.h:128 JSObject::getClass() const
96 ==7116==ABORTING
97 """
98
99 testTraceHeapWithCrashAddress = """
100 Program terminated with signal 11, Segmentation fault.
101 #0 0xe1afa070 in ?? ()
102 #0 0xe1afa070 in ?? ()
103 #1 0x00000000 in ?? ()
104 eax 0xfff869cc -497204
105 ebx 0x9469ff4 155623412
106 ecx 0xe20f6cc0 -502305600
107 edx 0xe1afa070 -508583824
108 esi 0xfff86934 -497356
109 edi 0xfff868cc -497460
110 ebp 0xe20f8790 3792668560
111 esp 0xfff8682c 4294469676
112 eip 0xe1afa070 3786383472
113 => 0xe1afa070: push %edi
114 0xe1afa071: push %esi
115 """
116
117 testTraceHeapWithoutCrashAddress = """
118 Program terminated with signal SIGSEGV, Segmentation fault.
119 #0 0x00007f2b41e78087 in ?? ()
120 #1 0xfff9000000000000 in ?? ()
121 #2 0x4275203ba1949000 in ?? ()
122 #3 0x00007fff5330bb01 in ?? ()
123 #4 0x00007f2b44d83e40 in ?? ()
124 rax 0x7f2b42c45bc0 139823780486080
125 rbx 0x0 0
126 rcx 0x4275203ba1949000 4788769219264417792
127 rdx 0x1 1
128 rsi 0x7f2b42c4a310 139823780504336
129 rdi 0x7f2b4aa19000 139823912423424
130 rbp 0x7f2b42c4a310 139823780504336
131 rsp 0x7fff5330bae0 140734589090528
132 r8 0x7f2b46261678 139823837222520
133 r9 0x0 0
134 r10 0x7f2b46261688 139823837222536
135 r11 0x7f2b4aa6a1e8 139823912755688
136 r12 0x0 0
137 r13 0x7b2 1970
138 r14 0x404 1028
139 r15 0x7f2b4aa19000 139823912423424
140 rip 0x7f2b41e78087 139823766012039
141 => 0x7f2b41e78087: xorpd %xmm5,%xmm5
142 0x7f2b41e7808b: ucomisd %xmm5,%xmm4
143 """
144
145 testSignature1 = '''{"symptoms": [
146 {
147 "functionName": "GetObjectAllocKindForCopy",
148 "frameNumber": 0,
149 "type": "stackFrame"
150 },
151 {
152 "functionName": "js::Nursery::moveToTenured",
153 "frameNumber": 1,
154 "type": "stackFrame"
155 },
156 {
157 "functionName": "MinorGCCallback",
158 "frameNumber": 2,
159 "type": "stackFrame"
160 },
161 {
162 "functionName": "js::Nursery::MinorGCCallback",
163 "frameNumber": 3,
164 "type": "stackFrame"
165 },
166 {
167 "address": "0x2b2b2b2b",
168 "type": "crashAddress"
169 }
170 ]}
171 '''
172
173 testSignature2 = '''{"symptoms": [
174 {
175 "functionName": "GetObjectAllocKindForCopy",
176 "frameNumber": 0,
177 "type": "stackFrame"
178 },
179 {
180 "functionName": "js::Nursery::moveToTenured",
181 "frameNumber": 1,
182 "type": "stackFrame"
183 },
184 {
185 "functionName": "MinorGCCallback",
186 "frameNumber": 2,
187 "type": "stackFrame"
188 }
189 ]}
190 '''
191
192 testSignature3 = '''{"symptoms": [
193 {
194 "functionName": "GetObjectAllocKindForCopy",
195 "frameNumber": 0,
196 "type": "stackFrame"
197 },
198 {
199 "functionName": "js::Nursery::moveToTenured",
200 "frameNumber": 1,
201 "type": "stackFrame"
202 },
203 {
204 "address": "0x2b2b2b2b",
205 "type": "crashAddress"
206 },
207 {
208 "type": "instruction",
209 "instructionName": "mov (%rax),%r8"
210 }
211 ]}
212 '''
213
214 testSignature4 = '''{"symptoms": [
215 {
216 "functionName": "GetObjectAllocKindForCopy",
217 "frameNumber": 0,
218 "type": "stackFrame"
219 },
220 {
221 "functionName": "js::Nursery::moveToTenured",
222 "frameNumber": 1,
223 "type": "stackFrame"
224 },
225 {
226 "type": "testcase",
227 "value": {
228 "matchType": "pcre",
229 "value": "SIMD\\\.float\\\d+x"
230 }
231 }
232 ]}
233 '''
234
235 testSignature5 = '''{"symptoms": [
236 {
237 "functionName": "GetObjectAllocKindForCopy",
238 "frameNumber": 0,
239 "type": "stackFrame"
240 },
241 {
242 "functionName": "js::Nursery::moveToTenured",
243 "frameNumber": 1,
244 "type": "stackFrame"
245 },
246 {
247 "type": "testcase",
248 "value": "SIMD.float32x4"
249 }
250 ]}
251 '''
252
253 testSignature6 = '''{"symptoms": [
254 {
255 "functionName": "GetObjectAllocKindForCopy",
256 "frameNumber": 0,
257 "type": "stackFrame"
258 },
259 {
260 "functionName": "js::Nursery::moveToTenured",
261 "frameNumber": 1,
262 "type": "stackFrame"
263 },
264 {
265 "type": "testcase",
266 "value": "SIMD.float64x4"
267 }
268 ]}
269 '''
270
271 testSignature7 = '''{"symptoms": [
272 {
273 "type": "stackFrames",
274 "functionNames": [
275 "js::UnwindIteratorForException",
276 "CloseLiveIterator",
277 "HandleExceptionIon",
278 "js::jit::HandleException"
279 ]
280 }
281 ]}
282 '''
283
284 testCase1 = '''
285 function test() {
286 var a = SIMD.float32x4();
287 if (typeof reportCompare === "function")
288 reportCompare(true, true);
289 }
290 test();
291 '''
292
293 testSignatureStackFrames1 = '''{"symptoms": [
294 {
295 "type": "stackFrames",
296 "functionNames": [ "GetObjectAllocKindForCopy", "moveToTenured", "?", "MinorGCCallback", "MarkInternal<JSObject>" ]
297 }
298 ]}
299 '''
300
301 testSignatureStackFrames2 = '''{"symptoms": [
302 {
303 "type": "stackFrames",
304 "functionNames": [ "GetObjectAllocKindForCopy", "moveToTenured", "?", "MinorGCCallback", "MinorGCCallback", "MarkInternal<JSObject>" ]
305 }
306 ]}
307 '''
308
309 testSignatureStackFrames3 = '''{"symptoms": [
310 {
311 "type": "stackFrames",
312 "functionNames": [ "GetObjectAllocKindForCopy", "moveToTenured", "?", "?", "MarkInternal<JSObject>" ]
313 }
314 ]}
315 '''
316
317 testSignatureStackFrames4 = '''{"symptoms": [
318 {
319 "type": "stackFrames",
320 "functionNames": [ "GetObjectAllocKindForCopy", "moveToTenured", "???", "MarkInternal<JSObject>" ]
321 }
322 ]}
323 '''
324
325 testSignatureStackFrames5 = '''{"symptoms": [
326 {
327 "type": "stackFrames",
328 "functionNames": [ "GetObjectAllocKindForCopy", "moveToTenured", "?", "MarkInternal<JSObject>" ]
329 }
330 ]}
331 '''
332
333
334 testSignaturePCREShort1 = '''{"symptoms": [
335 {
336 "functionName": "/.+KindForCopy/",
337 "type": "stackFrame"
338 }
339 ]}
340 '''
341
342 testSignaturePCREShort2 = '''{"symptoms": [
343 {
344 "functionName": "/^.KindForCopy/",
345 "type": "stackFrame"
346 }
347 ]}
348 '''
349
350 testSignatureEmptyCrashAddress = '''{"symptoms": [
351 {
352 "address": "",
353 "type": "crashAddress"
354 }
355 ]}
356 '''
357
360 config = ProgramConfiguration("test", "x86", "linux")
361
362 crashInfo = CrashInfo.fromRawCrashData([], [], config, auxCrashData=testTrace1.splitlines())
363 crashSig1 = crashInfo.createCrashSignature(forceCrashAddress=True, maxFrames=4, minimumSupportedVersion=10)
364 crashSig2 = crashInfo.createCrashSignature(forceCrashAddress=False, maxFrames=3, minimumSupportedVersion=10)
365 crashSig3 = crashInfo.createCrashSignature(forceCrashInstruction=True, maxFrames=2, minimumSupportedVersion=10)
366
367
368 self.assert_(crashSig1.matches(crashInfo))
369 self.assert_(crashSig2.matches(crashInfo))
370 self.assert_(crashSig3.matches(crashInfo))
371
372
373 self.assertEqual(json.loads(str(crashSig1)), json.loads(testSignature1))
374 self.assertEqual(json.loads(str(crashSig2)), json.loads(testSignature2))
375
376
377
378 self.assertEqual(json.loads(str(crashSig3)), json.loads(testSignature3))
379
409
427
430
431 self.assertTrue(StackFramesSymptom._match([], [StringMatch('???')]))
432 self.assertFalse(StackFramesSymptom._match([], [StringMatch('???'), StringMatch('a')]))
433
434
435
436 testArray = [
437 (['a', 'b', 'x', 'a', 'b', 'c'], ['a', 'b', '???', 'a', 'b', 'x', 'c'], 1, ['a', 'b', '???', 'a', 'b', '?', 'c']),
438 (['b', 'x', 'a', 'b', 'c'], ['a', 'b', '???', 'a', 'b', 'x', 'c'], 2, ['?', 'b', '???', 'a', 'b', '?', 'c']),
439 (['b', 'x', 'a', 'd', 'x'], ['a', 'b', '???', 'a', 'b', 'x', 'c'], 3, ['?', 'b', '???', 'a', '?', 'x', '?']),
440 ]
441
442 for (stack, rawSig, expectedDepth, expectedSig) in testArray:
443 for maxDepth in (expectedDepth, 3):
444 (actualDepth, actualSig) = StackFramesSymptom._diff(stack, [ StringMatch(x) for x in rawSig ], 0, 1, maxDepth)
445 self.assertEqual(expectedDepth, actualDepth)
446 self.assertEqual(expectedSig, [ str(x) for x in actualSig ])
447
459
473
484
485 if __name__ == "__main__":
486
487 unittest.main()
488