Skip to content

Commit

Permalink
add txn assert
Browse files Browse the repository at this point in the history
  • Loading branch information
Andi Kleen committed Apr 11, 2012
1 parent fc937fd commit 5362121
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 3 deletions.
9 changes: 8 additions & 1 deletion assert-test.c
@@ -1,6 +1,13 @@
#include "txn-assert.h"

int foo;

f2()
{
TXN_ASSERT_ONLY(foo);
}

main()
{
TXN_ASSERT(0);
TXN_ASSERT_ONLY(!foo);
}
79 changes: 79 additions & 0 deletions assign-assert.py
@@ -0,0 +1,79 @@
#!/usr/bin/python
# generate table of TXN_ASSERT() locations and assign unique ids for each
# by patching the binary
# all object files using TXN_ASSERT must be processed on the same command line!
# then the resulting .c file should be compiled and linked in

import sys
import os
import re

global identifier
identifier = 0

class Section:
def __init__(self, name, foff, vma):
self.name = name
self.foff = foff
self.vaddr = vma

def addr2line(fn, addr):
a2l = os.popen("addr2line -e %s %#x" % (fn, addr))
res = a2l.readline()
a2l.close()
return res.rstrip()

def process(i, pfile):
global identifier
sections = {}
func = None
section = None
objdump = os.popen("objdump -dfh " + i + " | expand", 'r', 8192)
for o in objdump:
if re.match("^Sections:$", o):
for o in objdump:
if re.match(r"\s+\d+\s", o):
(idx, name, size, vma, lma, foff, algn) = o.split()
if name != ".txn_abort":
continue
sections[name] = Section(name, int(foff, 16), int(vma, 16))
#print >>sys.stderr,"section header %s" % (name,)
if re.match(r"^$", o):
break
m = re.match(r"Disassembly of section ([^:]+):", o)
if m:
if m.group(1) == ".txn_abort":
section = sections[m.group(1)]
else:
section = None
continue
if section:
m = re.match(r"\s+([0-9a-f]+):\s+", o)
if m:
vaddr = int(m.group(1), 16)
if re.match("\s*xabort", o[32:]):
foff = vaddr - section.vaddr + section.foff
if pfile:
print "patch at %d" % (foff + 2,)
if identifier > 254:
# XXX fix assert code to print multiple
print >>sys.stderr, "error: too many txn_asserts"
pfile.seek(foff + 2)
pfile.write("%c" % (identifier & 0xff, ))
m = re.match("\s*jmpq\s+([0-9a-f]+)", o[32:])
if m:
pos = addr2line(i, int(m.group(1), 16))
print " [%d] = \"%s\"," % (identifier, pos)
identifier += 1


print "/* Auto generated. Do not edit */"
print "char *txn_assert_table[] = {"
for i in sys.argv[1:]:
pfile = open(i, "r+")
process(i, pfile)
pfile.close()
print "};"
print
print "int txn_assert_table_size = sizeof(txn_assert_table) / sizeof(char *);"

2 changes: 1 addition & 1 deletion remove-hle.py
Expand Up @@ -34,7 +34,7 @@ def process(i, pfile):
for o in objdump:
if re.match(r"\s+\d+\s", o):
(idx, name, size, vma, lma, foff, algn) = o.split()
sections[name] = Section(name, int(vma, 16), int(foff, 16))
sections[name] = Section(name, int(foff, 16), int(vma, 16))
#print "section header %s" % (name,)
if re.match(r"^$", o):
break
Expand Down
22 changes: 22 additions & 0 deletions txn-assert.c
@@ -0,0 +1,22 @@
#include "hle.h"

typedef void (*tsx_assert_hook_t)(unsigned);
extern tsx_assert_hook_t __tsx_set_abort_hook(tsx_assert_hook_t);

extern char *txn_assert_table[];
extern int txn_assert_table_size;

static void assert_hook(unsigned status)
{
if ((status & XABORT_EXPLICIT_ABORT) &&
XABORT_STATUS(status) < txn_assert_table_size) {
write(2, PAIR("txn assert failure at "));
write(2, txn_assert_table[XABORT_STATUS(status)]);
}
}

static void __attribute__((constructor)) init_txn_assert(void)
{
__tsx_set_abort_hook(assert_hook);
}

2 changes: 1 addition & 1 deletion txn-assert.h
Expand Up @@ -16,7 +16,7 @@
do if (!(x)) { TXN_ABORT(); assert(0); } while(0)

/* Only assert when in a transction. nop when not */
#define TSX_ASSERT_ONLY(x) \
#define TXN_ASSERT_ONLY(x) \
do if (!(x)) TXN_ABORT(); while(0)


Expand Down

0 comments on commit 5362121

Please sign in to comment.