def _find_calls(self):
        calls = []
        stack = []
        for m in self._profile_mmaps:
            m.seek(0)
            while True:
                b = m.read(struct.calcsize("=B"))
                if not b:
                    break
                marker, = struct.unpack("=B", b)
                if marker == 0:
                    m.close()
                    break
                elif marker != PROFILE_IDENTIFIER:
                    raise Exception

                event_id, timestamp = read_unpack("=Bd", m)
                if event_id == CALL_EVENT:
                    func_name_len, = read_unpack("=L", m)
                    func_name = m.read(func_name_len)
                    stack.append((func_name, timestamp, []))
                elif event_id == RETURN_EVENT:
                    try:
                        prev_func_name, prev_timestamp, subcalls = stack.pop()
                    except __HOLE__:
                        # The function where the profile hook was enabled
                        # (and everything up the stack from there) will
                        # have returns recorded, but no call, so we ignore
                        # them.
                        if not stack:
                            continue
                    call = PythonCall(prev_func_name, prev_timestamp, timestamp, subcalls)
                    if stack:
                        stack[-1][2].append(call)
                    else:
                        calls.append(call)

        while stack:
            prev_func_name, prev_timestamp, subcalls = stack.pop()
            call = PythonCall(prev_func_name, prev_timestamp, self._end_time, subcalls)
            if stack:
                stack[-1][2].append(call)
            else:
                calls.append(call)

        self.calls = calls
dataset/ETHPy150Open alex/tracebin/client/tracebin/recorder.py/Recorder._find_calls