Skip to main content

How to call a python script from gdb - Automate coredump investigation

· 2 min read
Hreniuc Cristian-Alexandru

Here is an example script that I've created to investigate a coredump. This automates the investigation by printing some objects from multiple sessions.

To call this script into gdb run the following inside gdb:

source ~/scripts/print_sessions.py
print_sessions Namespace::object
from collections import Counter
from operator import truediv
from pprint import pprint
import sys

import gdb

class PrintSessionsCmd(gdb.Command):
"""Prints the ListNode from our example in a nice format!"""

def __init__(self):
super(PrintSessionsCmd, self).__init__(
"print_sessions", gdb.COMMAND_USER
)

def print_sessions(self):
#self.print_session_from_addr()
self.print_sessions_from_file()

return

def print_sessions_from_file(self):
count = 0
sessions = Counter()
with open("/home/cristian.hreniuc/data/projects/investigations/OPS-26075/cores/session_adresses.log") as fp:
while True:
count += 1
line = fp.readline()

if not line:
break
session_addr = line.strip() # iterate through elements from the file
session = self.get_session(session_addr)
sessions.update({str(session.type): 1})
tv_client = self.get_tv_client(session)
stats = self.get_stats(tv_client)

print(sessions)

def print_session_from_addr(self):
session_addr = "0x7fa532877d30"
session = self.get_session(session_addr)
tv_client = self.get_tv_client(session)

def get_session(self, session):
session_address = gdb.Value(int(str(session), 0))
interface_session_pointer = session_address.cast(gdb.lookup_type('ISession').pointer())
session_pointer = interface_session_pointer.cast(interface_session_pointer.dynamic_type)

session_obj = session_pointer.dereference()

return session_obj

def get_tv_client(self,session):
interface_client_address = session["m_client"]["_M_t"]["_M_t"]["_M_head_impl"]
interface_client_address_number =int(str(interface_client_address), 0)

if interface_client_address_number == 0:
interface_client_address = session["m_tvClient"]["_M_ptr"]
interface_client_address_number =int(str(interface_client_address), 0)

client_address = gdb.Value(interface_client_address_number)
interface_client_pointer = client_address.cast(gdb.lookup_type('IClient').pointer())
client_pointer = interface_client_pointer.cast(interface_client_pointer.dynamic_type)

client_obj = client_pointer.dereference()
return client_obj

def get_stats(self,tv_client):
stats_address = tv_client["m_stats"]["px"]
stats_address_number = int(str(stats_address), 0)

if stats_address_number == 0:
return None

stats = stats_address.cast(gdb.lookup_type('Stats').pointer()).dereference()

return stats["m_seg"]

def complete(self, text, word):
# We expect the argument passed to be a symbol so fallback to the
# internal tab-completion handler for symbols
return gdb.COMPLETE_SYMBOL

def invoke(self, args, from_tty):
# We can pass args here and use Python CLI utilities like argparse
# to do argument parsing
print("Args Passed: %s" % args)

sessions = gdb.parse_and_eval(args)

self.print_sessions()

PrintSessionsCmd()