summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-10-14 15:00:12 -0700
committerBen Longbons <b.r.longbons@gmail.com>2013-10-15 21:50:46 -0700
commit3fa6f4b4c400c7354e05ac7bae128d4d9ee30e5c (patch)
treec6b3f39e51aeaf6ff04061bb264211086e7e3fcc
parent60d9e17f3719eca2eb4531f9f01976b1e26c411b (diff)
downloadtmwa-3fa6f4b4c400c7354e05ac7bae128d4d9ee30e5c.tar.gz
tmwa-3fa6f4b4c400c7354e05ac7bae128d4d9ee30e5c.tar.bz2
tmwa-3fa6f4b4c400c7354e05ac7bae128d4d9ee30e5c.tar.xz
tmwa-3fa6f4b4c400c7354e05ac7bae128d4d9ee30e5c.zip
Add infrastructure for debug pretty printers
-rw-r--r--Makefile.in2
-rwxr-xr-xconfigure11
m---------deps/attoconf0
-rw-r--r--real.make65
-rw-r--r--src/main-gdb-head.py59
-rw-r--r--src/main-gdb-tail.py2
-rw-r--r--src/strings/zstring.py18
7 files changed, 141 insertions, 16 deletions
diff --git a/Makefile.in b/Makefile.in
index 77c9873..1030212 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -27,6 +27,7 @@ HTMLDIR = @HTMLDIR@
DVIDIR = @DVIDIR@
PDFDIR = @PDFDIR@
PSDIR = @PSDIR@
+DEBUGDIR = @DEBUGDIR@
BISON = @BISON@
@@ -43,6 +44,7 @@ ENABLE_WARNINGS = @ENABLE_WARNINGS@
ENABLE_ABI6 = @ENABLE_ABI6@
ENABLE_CYGWIN_HACKS = @ENABLE_CYGWIN_HACKS@
ENABLE_COMPAT_SYMLINKS = @ENABLE_COMPAT_SYMLINKS@
+ENABLE_DEBUG = @ENABLE_DEBUG@
diff --git a/configure b/configure
index 584f965..838cb34 100755
--- a/configure
+++ b/configure
@@ -55,6 +55,14 @@ class Configuration(Cxx, Flex, Bison, Install, ConfigHash, Templates):
self.add_alias('--dev', ['--user', '--enable-warnings', '--enable-abi6'],
help=None, hidden=False)
+ def paths(self):
+ super(Configuration, self).paths()
+
+ self.add_option('--debugdir', init='/',
+ type=filepath, check=lambda build, DIR: None,
+ help='root for split debug files (often /usr/lib/debug)', hidden=False,
+ help_var='DIR')
+
def features(self):
super(Configuration, self).features()
# TODO: check VERSION_CONTROL environment variable?
@@ -75,6 +83,9 @@ class Configuration(Cxx, Flex, Bison, Install, ConfigHash, Templates):
self.add_bool_feature('compat-symlinks', init='yes',
check=lambda build, ENABLE_COMPAT_SYMLINKS: None,
help='Install symlinks to avoid breaking old scripts')
+ self.add_bool_feature('debug', init='yes',
+ check=lambda build, ENABLE_DEBUG: None,
+ help='Install extra files useful for debugging')
def vars(self):
super(Configuration, self).vars()
diff --git a/deps/attoconf b/deps/attoconf
-Subproject 2c30aa6572b9c8e455fb0aba5b5ed75361962d6
+Subproject 0f0e6300534b8b847f139c04b9e6ed1cc1100d9
diff --git a/real.make b/real.make
index e8442fe..acf656e 100644
--- a/real.make
+++ b/real.make
@@ -273,6 +273,10 @@ include ${DEPENDS}
bin/%:
$(MKDIR_FIRST)
${CXX} ${LDFLAGS} $^ ${LDLIBS} -o $@
+ cat ${SRC_DIR}/src/main-gdb-head.py \
+ $(wildcard $(patsubst obj/%.o,${SRC_DIR}/src/%.py,$^)) \
+ ${SRC_DIR}/src/main-gdb-tail.py \
+ > $@-gdb.py
${TEST_BINARIES}: obj/gtest-all.o
@@ -287,26 +291,46 @@ test: $(patsubst bin/%,.run-%,${TEST_BINARIES})
.run-%: bin/%
$<
+install := install --backup=${ENABLE_BACKUPS_DURING_INSTALL}
+install_exe := ${install}
+install_dir := ${install} -d
+install_data := ${install} -m 0644
+install_symlink := ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf
+
install:
- install -d ${DESTDIR}${BINDIR}
- install --backup=${ENABLE_BACKUPS_DURING_INSTALL} -t ${DESTDIR}${BINDIR} \
- $(wildcard ${BINARIES})
-# Is wildcard really the right thing to do? ^
-# cases to consider:
-# all binaries built
-# all binaries present, but some outdated. This is hard unless I dep.
-# some binaries built
-# no binaries built
+ @echo = Done installing
+
+install: install-bin
+install-bin:
+ @echo + Installing binaries
+ ${install_dir} ${DESTDIR}${BINDIR}
+ ${install_exe} -t ${DESTDIR}${BINDIR} \
+ ${BINARIES}
+install-bin: install-bin-compat
+install-bin-compat:
ifeq (${ENABLE_COMPAT_SYMLINKS},yes)
- @echo Installing compatibility symlinks
- ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf tmwa-login ${DESTDIR}${BINDIR}/login-server
- ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf tmwa-char ${DESTDIR}${BINDIR}/char-server
- ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf tmwa-map ${DESTDIR}${BINDIR}/map-server
- ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf tmwa-admin ${DESTDIR}${BINDIR}/ladmin
- ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf tmwa-monitor ${DESTDIR}${BINDIR}/eathena-monitor
+ @echo + Installing compatibility symlinks
+ ${install_dir} ${DESTDIR}${BINDIR}
+ ${install_symlink} tmwa-login ${DESTDIR}${BINDIR}/login-server
+ ${install_symlink} tmwa-char ${DESTDIR}${BINDIR}/char-server
+ ${install_symlink} tmwa-map ${DESTDIR}${BINDIR}/map-server
+ ${install_symlink} tmwa-admin ${DESTDIR}${BINDIR}/ladmin
+ ${install_symlink} tmwa-monitor ${DESTDIR}${BINDIR}/eathena-monitor
else
- @echo Not installing compatibility symlinks
+ @echo - Not installing compatibility symlinks
endif
+
+install: install-debug
+install-debug:
+ifeq (${ENABLE_DEBUG},yes)
+ @echo + Installing debug files
+ ${install_dir} ${DESTDIR}${DEBUGDIR}${BINDIR}
+ ${install_data} -t ${DESTDIR}${DEBUGDIR}${BINDIR} \
+ $(patsubst %,%-gdb.py,${BINARIES})
+else
+ @echo - Not installing debug files
+endif
+
tags: ${SOURCES} ${HEADERS}
ctags --totals --c-kinds=+px -f $@ $^
@@ -326,6 +350,15 @@ conf-raw/int-%.h: FORCE
echo "#define $* \\"; \
echo '$(value $*)'; \
} > $@
+bool_yes := true
+bool_no := false
+conf-raw/bool-%.h: FORCE
+ $(MKDIR_FIRST)
+ @grep -s -q '^$(bool_$(value $*))$$' $@ \
+ || { \
+ echo "#define $* \\"; \
+ echo '$(bool_$(value $*))'; \
+ } > $@
conf-raw/str-%.h: FORCE
$(MKDIR_FIRST)
@grep -s -q '^"$(value $*)"$$' $@ \
diff --git a/src/main-gdb-head.py b/src/main-gdb-head.py
new file mode 100644
index 0000000..cfdce2b
--- /dev/null
+++ b/src/main-gdb-head.py
@@ -0,0 +1,59 @@
+# Work around awkwardness in gdb's python printers:
+# 1. In src/main-gdb-head.py, define the printer mechanism.
+# 2. In src/*/*.py, define all the printer classes.
+# 3. In src/main-gdb-tail.py, reflect to actually add the printers.
+
+# gdb sticks everything in one scope.
+# This lets us enumerate what *we* added.
+initial_globals = set(globals())
+
+def finish():
+ diff = set(globals()) - initial_globals
+ fp = FastPrinters()
+ # After this, don't access any more globals in this function.
+ global finish, initial_globals, FastPrinters
+ del finish, initial_globals, FastPrinters
+
+ for k in diff:
+ v = globals()[k]
+ if hasattr(v, 'children') or hasattr(v, 'to_string'):
+ fp.add_printer(v)
+
+ gdb.current_objfile().pretty_printers.append(fp)
+
+class FastPrinters(object):
+ ''' printer dispatch the way gdb *should* have done it
+ '''
+ __slots__ = ('name', 'enabled', 'printers')
+
+ def __init__(self):
+ self.name = 'tmwa'
+ self.enabled = True
+ self.printers = {}
+
+ def add_printer(self, cls):
+ assert hasattr(cls, 'enabled')
+ self.printers[cls.name] = cls
+
+ @property
+ def subprinters(self):
+ return self.printers.values()
+
+ def strip_templates(self, name, __pattern=re.compile('<[^<>]>')):
+ # TODO what about '<' and '>' as non-type template parameters?
+ changed = 1
+ while changed:
+ name, changed = __pattern.subn('', name)
+ return name
+
+ def __call__(self, value):
+ stype = gdb.types.get_basic_type(value.type).tag
+ #dtype = gdb.types.get_basic_type(value.dynamic_type).tag
+ if stype is None:
+ return
+
+ stype = self.strip_templates(stype)
+ p = self.printers.get(stype)
+ if p is not None and p.enabled:
+ return p(value)
+ return None
diff --git a/src/main-gdb-tail.py b/src/main-gdb-tail.py
new file mode 100644
index 0000000..241444f
--- /dev/null
+++ b/src/main-gdb-tail.py
@@ -0,0 +1,2 @@
+# call the function defined in src/gdb-main-head.py
+finish()
diff --git a/src/strings/zstring.py b/src/strings/zstring.py
new file mode 100644
index 0000000..5021e1c
--- /dev/null
+++ b/src/strings/zstring.py
@@ -0,0 +1,18 @@
+class ZString(object):
+ ''' print a ZString
+ '''
+ __slots__ = ('_value')
+ name = 'strings::ZString'
+ enabled = True
+
+ def __init__(self, value):
+ self._value = value
+
+ def children(self):
+ yield 'base', self._value['_base']
+
+ def to_string(self):
+ b = self._value['_b']['_ptr']
+ e = self._value['_e']['_ptr']
+ d = e - b
+ return b.lazy_string(length=d)