mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-24 13:24:56 +08:00
86 lines
2.4 KiB
Python
86 lines
2.4 KiB
Python
# $OpenLDAP$
|
|
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
|
##
|
|
## Copyright 2020-2021 The OpenLDAP Foundation.
|
|
## All rights reserved.
|
|
##
|
|
## Redistribution and use in source and binary forms, with or without
|
|
## modification, are permitted only as authorized by the OpenLDAP
|
|
## Public License.
|
|
##
|
|
## A copy of this license is available in the file LICENSE in the
|
|
## top-level directory of the distribution or, alternatively, at
|
|
## <http://www.OpenLDAP.org/license.html>.
|
|
"""
|
|
This GDB script sets up the debugger to run the program and see if it finishes
|
|
of its own accord or is terminated by a signal (like SIGABRT/SIGSEGV). In the
|
|
latter case, it saves a full backtrace and core file.
|
|
|
|
These signals are considered part of normal operation and will not trigger the
|
|
above handling:
|
|
- SIGPIPE: normal in a networked environment
|
|
- SIGHUP: normally used to tell a process to shut down
|
|
"""
|
|
|
|
import os
|
|
import os.path
|
|
|
|
import gdb
|
|
|
|
|
|
def format_program(inferior=None, thread=None):
|
|
"Format program name and p(t)id"
|
|
|
|
if thread:
|
|
inferior = thread.inferior
|
|
elif inferior is None:
|
|
inferior = gdb.selected_inferior()
|
|
|
|
try:
|
|
name = os.path.basename(inferior.progspace.filename)
|
|
except AttributeError: # inferior has died already
|
|
name = "unknown"
|
|
|
|
if thread:
|
|
pid = ".".join(tid for tid in thread.ptid if tid)
|
|
else:
|
|
pid = inferior.pid
|
|
|
|
return "{}.{}".format(name, pid)
|
|
|
|
|
|
def stop_handler(event):
|
|
"Inferior stopped on a signal, record core, backtrace and exit"
|
|
|
|
if not isinstance(event, gdb.SignalEvent):
|
|
# Ignore breakpoints
|
|
return
|
|
|
|
thread = event.inferior_thread
|
|
|
|
identifier = format_program(thread=thread)
|
|
prefix = os.path.expandvars("${TESTDIR}/") + identifier
|
|
|
|
if event.stop_signal == "SIGHUP":
|
|
# TODO: start a timer to catch shutdown issues/deadlocks
|
|
gdb.execute("continue")
|
|
return
|
|
|
|
gdb.execute('generate-core-file {}.core'.format(prefix))
|
|
|
|
with open(prefix + ".backtrace", "w") as bt_file:
|
|
backtrace = gdb.execute("thread apply all backtrace full",
|
|
to_string=True)
|
|
bt_file.write(backtrace)
|
|
|
|
gdb.execute("continue")
|
|
|
|
|
|
# We or we could allow the runner to disable randomisation
|
|
gdb.execute("set disable-randomization off")
|
|
|
|
gdb.execute("handle SIGPIPE noprint")
|
|
gdb.execute("handle SIGINT pass")
|
|
gdb.events.stop.connect(stop_handler)
|
|
gdb.execute("run")
|