summaryrefslogtreecommitdiffstats
path: root/js/src/gdb/mozilla/asmjs.py
blob: 43fac20c737f2b0b073dd8f475d22bf2bcd0c482 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""
In asm code, out-of-bounds heap accesses cause segfaults, which the engine
handles internally. Make GDB ignore them.
"""

import gdb

SIGSEGV = 11

# A sigaction buffer for each inferior process.
sigaction_buffers = {}

def on_stop(event):
    if isinstance(event, gdb.SignalEvent) and event.stop_signal == 'SIGSEGV':
        # Allocate memory for sigaction, once per js shell process.
        process = gdb.selected_inferior()
        buf = sigaction_buffers.get(process)
        if buf is None:
            buf = gdb.parse_and_eval("(struct sigaction *) malloc(sizeof(struct sigaction))")
            sigaction_buffers[process] = buf

        # See if AsmJSFaultHandler is installed as the SIGSEGV signal action.
        sigaction_fn = gdb.parse_and_eval('__sigaction')
        sigaction_fn(SIGSEGV, 0, buf)
        AsmJSFaultHandler = gdb.parse_and_eval("AsmJSFaultHandler")
        if buf['__sigaction_handler']['sa_handler'] == AsmJSFaultHandler:
            # Advise the user that magic is happening.
            print("js/src/gdb/mozilla/asmjs.py: Allowing AsmJSFaultHandler to run.")

            # If AsmJSFaultHandler doesn't handle this segfault, it will unhook
            # itself and re-raise.
            gdb.execute("continue")

def on_exited(event):
    if event.inferior in sigaction_buffers:
        del sigaction_buffers[event.inferior]

def install():
    gdb.events.stop.connect(on_stop)
    gdb.events.exited.connect(on_exited)