Add simple script with caching (just one startup can take quite some time and
it saved hours during debugging).
Script expects 2 symlinks ("crash vmlinux core") and is designed
for post-mortem analysis.
Script contains one example: fetching all inodes.
Basically it is an example on how to run "crash" from Python.
---
diff --git a/contrib/crash.py b/contrib/crash.py
new file mode 100755
index 0000000..8dae0e1
--- /dev/null
+++ b/contrib/crash.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python2
+import hashlib
+import os
+import subprocess
+import tempfile
+
+# create "vmlinux" and "core" symlinks before running
+#CRASH='/usr/bin/crash'
+CRASH=os.path.join(os.path.expanduser('~'), 'bin', 'crash')
+
+# split() without empty strings
+def xsplit(s, c):
+ i = 0
+ while True:
+ j = s.find(c, i)
+ if j == -1:
+ if i == len(s):
+ return
+ yield s[i:]
+ return
+ elif i == j:
+ i = i + 1
+ continue
+ else:
+ yield s[i:j]
+ i = j + 1
+
+_CRASH_CACHE_DIR='.crash'
+def crash(cmd):
+ idx = cmd.find('\n')
+ if idx >= 0:
+ print 'CRASH "%s" ...' % cmd[:idx]
+ else:
+ print 'CRASH "%s"' % cmd
+
+ try:
+ os.mkdir(_CRASH_CACHE_DIR)
+ except OSError:
+ pass
+
+ cache_filename = os.path.join(_CRASH_CACHE_DIR, hashlib.sha1(cmd).hexdigest())
+ if os.path.isfile(cache_filename):
+ with open(cache_filename, 'r') as f:
+ return f.read()
+
+ fd, filename = tempfile.mkstemp()
+ f = os.fdopen(fd, 'w')
+ f.write(cmd)
+ if cmd[-1] != '\n':
+ f.write('\n')
+ f.write('q\n')
+ f.close()
+
+ with open(filename, 'r') as f:
+ x = subprocess.check_output([CRASH, '-s', 'vmlinux',
'core'], stdin=f)
+ os.unlink(filename)
+
+ with open(cache_filename, 'w+') as f:
+ f.write(x)
+ return x
+
+def make_cmd(fmt, it):
+ return '\n'.join(map(lambda x: fmt % x, it))
+
+#def struct_inode():
+# cmd = 'list -H super_blocks super_block.s_list'
+# x = crash(cmd)
+# list_sb = map(lambda x: int(x, 16), xsplit(x, '\n'))
+#
+# cmd = 'struct super_block.s_inodes'
+# x = crash(cmd)
+# s = [line for line in xsplit(x, '\n')]
+# OFFSETOF_STRUCT_INODE_S_INODES = int(s[1].split()[0][1:-1])
+#
+## set_inode = set()
+## for sb in list_sb:
+## cmd = 'list -H %x inode.i_sb_list' % (sb +
OFFSETOF_STRUCT_INODE_S_INODES)
+## x = crash(cmd)
+## set_inode.update(map(lambda x: int(x, 16), xsplit(x, '\n')))
+## print len(set_inode)
+#
+# set_inode = set()
+# cmd = make_cmd('list -H %x inode.i_sb_list', map(lambda x: x +
OFFSETOF_STRUCT_INODE_S_INODES, list_sb))
+# x = crash(cmd)
+# set_inode = set(map(lambda x: int(x, 16), xsplit(x, '\n')))
+# print len(set_inode)
+#
+#struct_inode()