revamp code, the way to the first stable release 0.2

reference counting for breakpoints and tasks
fix non interactive mode
eliminate dead code
new option --nocpp, useful when tracing c++ programs linked against
libstdc++
fix verbose mode
fix about exit and exit
This commit is contained in:
Stefani Seibold 2015-05-05 17:11:20 +02:00
parent 7acdb6f5e6
commit bd061133db
25 changed files with 773 additions and 548 deletions

View File

@ -78,6 +78,9 @@ noinst_HEADERS = \
thread.h \ thread.h \
trace.h trace.h
dist_man1_MANS = mtrace.1
dist_man5_MANS = mtrace.conf.5
dist_doc_DATA = COPYING CREDITS INSTALL README TODO dist_doc_DATA = COPYING CREDITS INSTALL README TODO
EXTRA_DIST = EXTRA_DIST =

View File

@ -128,7 +128,8 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES = CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
"$(DESTDIR)$(man5dir)" "$(DESTDIR)$(docdir)"
PROGRAMS = $(bin_PROGRAMS) PROGRAMS = $(bin_PROGRAMS)
am_mtrace_OBJECTS = breakpoint.$(OBJEXT) common.$(OBJEXT) \ am_mtrace_OBJECTS = breakpoint.$(OBJEXT) common.$(OBJEXT) \
debug.$(OBJEXT) dict.$(OBJEXT) dwarf.$(OBJEXT) event.$(OBJEXT) \ debug.$(OBJEXT) dict.$(OBJEXT) dwarf.$(OBJEXT) event.$(OBJEXT) \
@ -217,6 +218,10 @@ am__uninstall_files_from_dir = { \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \ $(am__cd) "$$dir" && rm -f $$files; }; \
} }
man1dir = $(mandir)/man1
man5dir = $(mandir)/man5
NROFF = nroff
MANS = $(dist_man1_MANS) $(dist_man5_MANS)
DATA = $(dist_doc_DATA) DATA = $(dist_doc_DATA)
HEADERS = $(noinst_HEADERS) HEADERS = $(noinst_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
@ -249,7 +254,8 @@ ETAGS = etags
CTAGS = ctags CTAGS = ctags
CSCOPE = cscope CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS) DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ am__DIST_COMMON = $(dist_man1_MANS) $(dist_man5_MANS) \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/config/autoconf/compile \ $(top_srcdir)/config/autoconf/compile \
$(top_srcdir)/config/autoconf/config.guess \ $(top_srcdir)/config/autoconf/config.guess \
$(top_srcdir)/config/autoconf/config.sub \ $(top_srcdir)/config/autoconf/config.sub \
@ -476,6 +482,8 @@ noinst_HEADERS = \
thread.h \ thread.h \
trace.h trace.h
dist_man1_MANS = mtrace.1
dist_man5_MANS = mtrace.conf.5
dist_doc_DATA = COPYING CREDITS INSTALL README TODO dist_doc_DATA = COPYING CREDITS INSTALL README TODO
EXTRA_DIST = EXTRA_DIST =
MAINTAINERCLEANFILES = \ MAINTAINERCLEANFILES = \
@ -658,6 +666,88 @@ clean-libtool:
distclean-libtool: distclean-libtool:
-rm -f libtool config.lt -rm -f libtool config.lt
install-man1: $(dist_man1_MANS)
@$(NORMAL_INSTALL)
@list1='$(dist_man1_MANS)'; \
list2=''; \
test -n "$(man1dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.1[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
install-man5: $(dist_man5_MANS)
@$(NORMAL_INSTALL)
@list1='$(dist_man5_MANS)'; \
list2=''; \
test -n "$(man5dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.5[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
done; }
uninstall-man5:
@$(NORMAL_UNINSTALL)
@list='$(dist_man5_MANS)'; test -n "$(man5dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
install-dist_docDATA: $(dist_doc_DATA) install-dist_docDATA: $(dist_doc_DATA)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
@list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
@ -975,10 +1065,10 @@ distcleancheck: distclean
exit 1; } >&2 exit 1; } >&2
check-am: all-am check-am: all-am
check: check-recursive check: check-recursive
all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS) config.h all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) config.h
installdirs: installdirs-recursive installdirs: installdirs-recursive
installdirs-am: installdirs-am:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)"; do \ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(docdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: install-recursive install: install-recursive
@ -1035,7 +1125,7 @@ info: info-recursive
info-am: info-am:
install-data-am: install-dist_docDATA install-data-am: install-dist_docDATA install-man
install-dvi: install-dvi-recursive install-dvi: install-dvi-recursive
@ -1051,7 +1141,7 @@ install-info: install-info-recursive
install-info-am: install-info-am:
install-man: install-man: install-man1 install-man5
install-pdf: install-pdf-recursive install-pdf: install-pdf-recursive
@ -1084,7 +1174,10 @@ ps: ps-recursive
ps-am: ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-dist_docDATA uninstall-am: uninstall-binPROGRAMS uninstall-dist_docDATA \
uninstall-man
uninstall-man: uninstall-man1 uninstall-man5
.MAKE: $(am__recursive_targets) all install-am install-strip .MAKE: $(am__recursive_targets) all install-am install-strip
@ -1100,13 +1193,14 @@ uninstall-am: uninstall-binPROGRAMS uninstall-dist_docDATA
install-data-am install-dist_docDATA install-dvi \ install-data-am install-dist_docDATA install-dvi \
install-dvi-am install-exec install-exec-am install-html \ install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \ install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \ install-man1 install-man5 install-pdf install-pdf-am \
install-strip installcheck installcheck-am installdirs \ install-ps install-ps-am install-strip installcheck \
installdirs-am maintainer-clean maintainer-clean-generic \ installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-local mostlyclean mostlyclean-compile \ maintainer-clean-generic maintainer-clean-local mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-dist_docDATA uninstall-binPROGRAMS uninstall-dist_docDATA uninstall-man \
uninstall-man1 uninstall-man5
.PRECIOUS: Makefile .PRECIOUS: Makefile

0
README
View File

1
README Symbolic link
View File

@ -0,0 +1 @@
README.md

View File

@ -8,24 +8,31 @@ The mtrace utility was designed to run in a very constrained environment, like s
The mtrace utility intercepts the following GLIBC calls: The mtrace utility intercepts the following GLIBC calls:
malloc() void *malloc(size_t size);
memalign() void free(void *ptr);
realloc() void *calloc(size_t nmemb, size_t size);
free() void *realloc(void *ptr, size_t size);
posix_memalign() int posix_memalign(void **memptr, size_t alignment, size_t size);
aligned_alloc() void *aligned_alloc(size_t alignment, size_t size);
valloc() void *valloc(size_t size);
pvalloc() void *memalign(size_t alignment, size_t size);
mmap() void *pvalloc(size_t size);
munmap() void cfree(void *ptr);
clone() void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
system() void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
execve() int munmap(void *addr, size_t length);
exit() void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */);
The operator new() method is using malloc(), so memory allocations of a C++ application can also be traced. void *operator new(size_t size) throw (std::bad_alloc)
void *operator new(size_t size, const std::nothrow_t& nt) __THROW
void *operator new[](size_t size) throw (std::bad_alloc)
void *operator new[](size_t size, const std::nothrow_t& nt) __THROW
void operator delete(void* p) __THROW
void operator delete(void* p, const std::nothrow_t& nt) __THROW
void operator delete[](void* p) __THROW
void operator delete[](void* p, const std::nothrow_t& nt) __THROW
There is currently support for X86 (32 udn 64 Bit), PowerPC (32 Bit) and ARM (32 Bit). Only Linux is now supported, but there are plans to support different operating systems and CPU's. There is currently support for X86 (32 and 64 Bit), PowerPC (32 Bit) and ARM (32 Bit). Only Linux is now supported, but there are plans to support different operating systems and CPU's.
Stay tuned... Stay tuned...

6
TODO
View File

@ -1,9 +1,9 @@
ppc single step ppc single step enhancement
arm thumb support arm thumb support
dwarf debug support dwarf debug support
arm & ppc hw bp support arm & ppc hw bp support
dwarf caching dwarf caching
invalid stack trace cache for unmapped libraries invalid stack trace cache for unmapped libraries
restore REALLOC_TRY when realloc fails restore REALLOC_TRY when realloc fails
manual page mremap revamp
documentation write documentation

View File

@ -42,186 +42,186 @@
'configure.ac' 'configure.ac'
], ],
{ {
'AC_ENABLE_FAST_INSTALL' => 1,
'_AM_PROG_CC_C_O' => 1,
'_LT_AC_CHECK_DLFCN' => 1,
'_LT_CC_BASENAME' => 1,
'AC_LTDL_OBJDIR' => 1,
'AC_LIB_LTDL' => 1,
'_LT_PATH_TOOL_PREFIX' => 1,
'LT_SYS_SYMBOL_USCORE' => 1,
'AM_SET_LEADING_DOT' => 1,
'AM_SILENT_RULES' => 1,
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
'_LT_PROG_CXX' => 1,
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
'LT_FUNC_DLSYM_USCORE' => 1,
'AC_LTDL_PREOPEN' => 1,
'AC_ENABLE_STATIC' => 1,
'AC_PROG_LD_RELOAD_FLAG' => 1,
'_LT_AC_TRY_DLOPEN_SELF' => 1,
'_LT_PROG_LTMAIN' => 1,
'_m4_warn' => 1,
'AM_RUN_LOG' => 1,
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
'_AM_MANGLE_OPTION' => 1,
'_LT_AC_PROG_CXXCPP' => 1,
'AC_LTDL_DLLIB' => 1,
'AC_LTDL_DLSYM_USCORE' => 1,
'LT_INIT' => 1,
'AM_DEP_TRACK' => 1,
'_LT_COMPILER_OPTION' => 1,
'AC_PROG_EGREP' => 1,
'_LT_LIBOBJ' => 1,
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'_AM_PROG_TAR' => 1,
'LT_AC_PROG_GCJ' => 1,
'_AM_IF_OPTION' => 1,
'LTDL_INIT' => 1,
'LT_FUNC_ARGZ' => 1,
'AC_DISABLE_FAST_INSTALL' => 1,
'AC_PROG_LD' => 1,
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
'_AC_PROG_LIBTOOL' => 1,
'_AM_SET_OPTION' => 1,
'AC_LIBTOOL_GCJ' => 1,
'AC_PROG_LD_GNU' => 1,
'AC_PROG_LIBTOOL' => 1,
'_LT_LINKER_OPTION' => 1,
'LT_PROG_GCJ' => 1,
'LT_AC_PROG_RC' => 1,
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
'AM_CONDITIONAL' => 1,
'_AM_SET_OPTIONS' => 1,
'AC_LIBTOOL_PICMODE' => 1,
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
'_AM_AUTOCONF_VERSION' => 1,
'AC_DEFUN' => 1,
'm4_pattern_forbid' => 1,
'_LT_AC_SYS_LIBPATH_AIX' => 1,
'AC_LIBTOOL_FC' => 1,
'AC_DISABLE_STATIC' => 1,
'LT_CMD_MAX_LEN' => 1,
'LT_PROG_RC' => 1,
'AC_DEPLIBS_CHECK_METHOD' => 1,
'_LTDL_SETUP' => 1,
'_AM_DEPENDENCIES' => 1,
'AM_SUBST_NOTMAKE' => 1,
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
'AC_PATH_TOOL_PREFIX' => 1,
'm4_pattern_allow' => 1,
'LT_SYS_DLSEARCH_PATH' => 1,
'AM_PROG_CC_C_O' => 1,
'_LT_AC_LANG_CXX_CONFIG' => 1,
'LT_OUTPUT' => 1,
'AC_ENABLE_SHARED' => 1,
'_LT_LINKER_BOILERPLATE' => 1,
'AC_LIBTOOL_RC' => 1,
'AC_LIBTOOL_DLOPEN' => 1,
'AM_DISABLE_STATIC' => 1,
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
'LT_PROG_GO' => 1,
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
'AM_PROG_NM' => 1,
'AC_DEFUN_ONCE' => 1,
'_LT_AC_TAGVAR' => 1,
'AC_LIBTOOL_SETUP' => 1,
'LT_SYS_DLOPEN_SELF' => 1,
'LT_PATH_LD' => 1,
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
'AC_DISABLE_SHARED' => 1,
'_LT_AC_LANG_GCJ' => 1, '_LT_AC_LANG_GCJ' => 1,
'AC_LIBTOOL_WIN32_DLL' => 1, 'LT_SYS_DLSEARCH_PATH' => 1,
'AM_MISSING_HAS_RUN' => 1, 'AC_PROG_LD' => 1,
'AM_MAINTAINER_MODE' => 1, 'LT_FUNC_DLSYM_USCORE' => 1,
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
'LT_WITH_LTDL' => 1,
'AC_CHECK_LIBM' => 1,
'_LT_AC_FILE_LTDLL_C' => 1,
'_LT_AC_LANG_CXX' => 1,
'LT_SUPPORTED_TAG' => 1,
'_LT_DLL_DEF_P' => 1,
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
'AC_CONFIG_MACRO_DIR' => 1,
'LTSUGAR_VERSION' => 1,
'LT_PATH_NM' => 1,
'LTOPTIONS_VERSION' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_LIBTOOL_CXX' => 1,
'AC_LIBLTDL_CONVENIENCE' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'_LT_AC_LANG_F77' => 1,
'LTOBSOLETE_VERSION' => 1,
'LTDL_INSTALLABLE' => 1,
'_LT_PROG_ECHO_BACKSLASH' => 1,
'AC_LTDL_SYMBOL_USCORE' => 1,
'AM_SET_DEPDIR' => 1,
'LT_AC_PROG_EGREP' => 1,
'LT_LIB_DLLOAD' => 1,
'_LT_AC_LANG_GCJ_CONFIG' => 1,
'AC_LIBTOOL_CONFIG' => 1,
'LT_AC_PROG_SED' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'LTDL_CONVENIENCE' => 1,
'AM_MAKE_INCLUDE' => 1,
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
'AC_LTDL_SYSSEARCHPATH' => 1,
'LT_LANG' => 1,
'_LT_AC_SHELL_INIT' => 1,
'AM_AUX_DIR_EXPAND' => 1,
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AC_LIBTOOL_PROG_CC_C_O' => 1,
'AC_LTDL_SHLIBEXT' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AC_LTDL_SHLIBPATH' => 1,
'AC_LTDL_ENABLE_INSTALL' => 1,
'_AM_CONFIG_MACRO_DIRS' => 1,
'AM_PROG_INSTALL_STRIP' => 1,
'AC_LIBTOOL_F77' => 1,
'AC_LIBTOOL_OBJDIR' => 1,
'AC_LIBTOOL_LINKER_OPTION' => 1, 'AC_LIBTOOL_LINKER_OPTION' => 1,
'AM_PROG_LD' => 1, 'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1, '_AC_AM_CONFIG_HEADER_HOOK' => 1,
'm4_include' => 1, 'AM_RUN_LOG' => 1,
'AM_PROG_LIBTOOL' => 1, 'LTSUGAR_VERSION' => 1,
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AC_LIBTOOL_SETUP' => 1,
'_LT_LINKER_BOILERPLATE' => 1,
'_AM_CONFIG_MACRO_DIRS' => 1,
'AM_PROG_NM' => 1,
'AM_PROG_INSTALL_STRIP' => 1,
'LT_FUNC_ARGZ' => 1,
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
'AC_LIBTOOL_FC' => 1,
'LT_AC_PROG_SED' => 1,
'_LT_AC_LANG_C_CONFIG' => 1,
'AC_ENABLE_FAST_INSTALL' => 1,
'_AM_SET_OPTIONS' => 1,
'AC_LIB_LTDL' => 1,
'AC_DEPLIBS_CHECK_METHOD' => 1,
'AC_LTDL_DLSYM_USCORE' => 1,
'LTDL_INSTALLABLE' => 1,
'_LT_PATH_TOOL_PREFIX' => 1,
'_LT_AC_SYS_COMPILER' => 1,
'AM_MISSING_HAS_RUN' => 1,
'LTDL_CONVENIENCE' => 1,
'AC_PROG_NM' => 1,
'_LT_COMPILER_BOILERPLATE' => 1,
'LT_AC_PROG_EGREP' => 1,
'_LT_AC_SYS_LIBPATH_AIX' => 1,
'_AM_MANGLE_OPTION' => 1,
'LT_PROG_GO' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'AC_LIBTOOL_RC' => 1,
'_AM_IF_OPTION' => 1,
'AC_LIBTOOL_WIN32_DLL' => 1,
'AM_MAKE_INCLUDE' => 1,
'_m4_warn' => 1,
'_LT_LIBOBJ' => 1,
'_AM_PROG_CC_C_O' => 1,
'_LT_WITH_SYSROOT' => 1,
'AC_LIBLTDL_INSTALLABLE' => 1,
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'_LT_AC_SHELL_INIT' => 1,
'LT_PROG_GCJ' => 1,
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
'LT_SUPPORTED_TAG' => 1,
'_LT_AC_LANG_F77_CONFIG' => 1,
'_LT_LINKER_OPTION' => 1,
'_LT_AC_FILE_LTDLL_C' => 1,
'AC_PROG_EGREP' => 1,
'AM_MAINTAINER_MODE' => 1,
'_LT_PROG_CXX' => 1,
'AC_LTDL_SYMBOL_USCORE' => 1,
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
'_LT_AC_LANG_F77' => 1,
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
'LT_SYS_MODULE_PATH' => 1, 'LT_SYS_MODULE_PATH' => 1,
'_LT_PROG_FC' => 1, 'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
'AC_LIBTOOL_DLOPEN_SELF' => 1, 'AC_DISABLE_FAST_INSTALL' => 1,
'AM_ENABLE_SHARED' => 1, 'LT_PATH_LD' => 1,
'LT_CMD_MAX_LEN' => 1,
'AM_DISABLE_SHARED' => 1,
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
'AM_ENABLE_STATIC' => 1, 'AM_ENABLE_STATIC' => 1,
'AC_PATH_MAGIC' => 1, 'AC_PATH_MAGIC' => 1,
'LTVERSION_VERSION' => 1, 'AC_LTDL_ENABLE_INSTALL' => 1,
'_LT_AC_LANG_F77_CONFIG' => 1, 'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1, '_LT_PROG_F77' => 1,
'LT_CONFIG_LTDL_DIR' => 1, '_LT_AC_PROG_CXXCPP' => 1,
'_LT_AC_LANG_RC_CONFIG' => 1,
'_LT_AC_SYS_COMPILER' => 1,
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
'AM_DISABLE_SHARED' => 1,
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
'LT_SYS_DLOPEN_DEPLIBS' => 1,
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
'_LT_COMPILER_BOILERPLATE' => 1,
'AC_LIBTOOL_COMPILER_OPTION' => 1,
'AC_WITH_LTDL' => 1,
'_LT_AC_LOCK' => 1,
'LT_LIB_M' => 1,
'LT_SYS_MODULE_EXT' => 1,
'AC_LIBLTDL_INSTALLABLE' => 1,
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
'_LT_AC_LANG_C_CONFIG' => 1,
'AM_MISSING_PROG' => 1, 'AM_MISSING_PROG' => 1,
'AC_PROG_NM' => 1, 'AC_CONFIG_MACRO_DIR' => 1,
'AM_SANITY_CHECK' => 1, 'AC_CONFIG_MACRO_DIR_TRACE' => 1,
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
'AC_PROG_LD_RELOAD_FLAG' => 1,
'AC_DEFUN_ONCE' => 1,
'_LTDL_SETUP' => 1,
'_AM_SET_OPTION' => 1,
'AC_LIBLTDL_CONVENIENCE' => 1,
'_LT_PROG_LTMAIN' => 1,
'include' => 1, 'include' => 1,
'_LT_WITH_SYSROOT' => 1, '_AC_PROG_LIBTOOL' => 1,
'AM_PROG_INSTALL_SH' => 1, 'AM_CONDITIONAL' => 1,
'AM_ENABLE_SHARED' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AC_LIBTOOL_CXX' => 1,
'AM_PROG_CC_C_O' => 1,
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
'_LT_AC_LOCK' => 1,
'LTOBSOLETE_VERSION' => 1,
'LT_PATH_NM' => 1,
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
'AM_PROG_LIBTOOL' => 1,
'AM_SET_DEPDIR' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AM_AUX_DIR_EXPAND' => 1,
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
'AC_DISABLE_STATIC' => 1,
'LT_AC_PROG_RC' => 1,
'_AM_AUTOCONF_VERSION' => 1,
'_AM_DEPENDENCIES' => 1,
'AM_DEP_TRACK' => 1,
'LTOPTIONS_VERSION' => 1,
'AM_SILENT_RULES' => 1,
'_LT_AC_LANG_CXX' => 1,
'AC_LIBTOOL_OBJDIR' => 1,
'_LT_AC_TRY_DLOPEN_SELF' => 1,
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
'_LT_AC_TAGVAR' => 1,
'LTDL_INIT' => 1,
'AC_LTDL_PREOPEN' => 1,
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
'_LT_AC_CHECK_DLFCN' => 1,
'AM_SET_LEADING_DOT' => 1,
'_LT_CC_BASENAME' => 1,
'm4_pattern_allow' => 1,
'_AM_PROG_TAR' => 1,
'_LT_DLL_DEF_P' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AC_LTDL_DLLIB' => 1,
'LT_AC_PROG_GCJ' => 1,
'AC_WITH_LTDL' => 1,
'AC_ENABLE_STATIC' => 1,
'LT_LIB_DLLOAD' => 1,
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
'_LT_AC_LANG_CXX_CONFIG' => 1,
'LT_SYS_DLOPEN_DEPLIBS' => 1,
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
'AC_LIBTOOL_CONFIG' => 1,
'AC_LTDL_OBJDIR' => 1,
'AC_LIBTOOL_COMPILER_OPTION' => 1,
'AC_LIBTOOL_F77' => 1,
'AC_PROG_LIBTOOL' => 1,
'_LT_PROG_ECHO_BACKSLASH' => 1,
'_LT_AC_LANG_RC_CONFIG' => 1,
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
'AM_SUBST_NOTMAKE' => 1,
'LT_LIB_M' => 1,
'LTVERSION_VERSION' => 1,
'AC_DEFUN' => 1,
'AM_SANITY_CHECK' => 1,
'AC_PROG_LD_GNU' => 1,
'LT_SYS_SYMBOL_USCORE' => 1,
'AC_LTDL_SYSSEARCHPATH' => 1,
'AC_LTDL_SHLIBEXT' => 1,
'_LT_COMPILER_OPTION' => 1,
'_LT_PROG_FC' => 1,
'AC_DISABLE_SHARED' => 1,
'AC_CHECK_LIBM' => 1,
'_LT_AC_LANG_GCJ_CONFIG' => 1,
'LT_PROG_RC' => 1,
'LT_SYS_MODULE_EXT' => 1,
'AM_DISABLE_STATIC' => 1,
'AU_DEFUN' => 1, 'AU_DEFUN' => 1,
'_LT_PROG_F77' => 1 'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
'LT_WITH_LTDL' => 1,
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
'AC_ENABLE_SHARED' => 1,
'LT_INIT' => 1,
'AC_LIBTOOL_GCJ' => 1,
'm4_pattern_forbid' => 1,
'AC_LIBTOOL_PICMODE' => 1,
'AC_PATH_TOOL_PREFIX' => 1,
'AC_LTDL_SHLIBPATH' => 1,
'AC_LIBTOOL_DLOPEN_SELF' => 1,
'm4_include' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_LIBTOOL_DLOPEN' => 1,
'AC_LIBTOOL_PROG_CC_C_O' => 1,
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
'AM_PROG_LD' => 1,
'LT_OUTPUT' => 1,
'LT_SYS_DLOPEN_SELF' => 1,
'AM_PROG_INSTALL_SH' => 1,
'LT_LANG' => 1
} }
], 'Autom4te::Request' ), ], 'Autom4te::Request' ),
bless( [ bless( [
@ -263,186 +263,186 @@
'configure.ac' 'configure.ac'
], ],
{ {
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
'_LT_AC_LANG_C_CONFIG' => 1,
'AM_MISSING_PROG' => 1,
'AC_WITH_LTDL' => 1,
'LT_LIB_M' => 1,
'_LT_AC_LOCK' => 1, '_LT_AC_LOCK' => 1,
'AC_LIBLTDL_INSTALLABLE' => 1,
'LT_SYS_MODULE_EXT' => 1,
'AC_LIBTOOL_COMPILER_OPTION' => 1,
'_LT_COMPILER_BOILERPLATE' => 1,
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
'AU_DEFUN' => 1,
'_LT_PROG_F77' => 1,
'AM_SANITY_CHECK' => 1,
'include' => 1,
'AM_PROG_INSTALL_SH' => 1,
'_LT_WITH_SYSROOT' => 1,
'AC_PROG_NM' => 1,
'AC_LIBTOOL_DLOPEN_SELF' => 1,
'AM_ENABLE_SHARED' => 1,
'AM_ENABLE_STATIC' => 1,
'AC_PATH_MAGIC' => 1,
'LTVERSION_VERSION' => 1,
'LT_SYS_MODULE_PATH' => 1,
'_LT_PROG_FC' => 1,
'AC_LIBTOOL_LINKER_OPTION' => 1,
'AC_LIBTOOL_OBJDIR' => 1,
'm4_include' => 1,
'AM_PROG_LD' => 1,
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
'AM_PROG_LIBTOOL' => 1,
'AC_LIBTOOL_F77' => 1,
'LT_SYS_DLOPEN_DEPLIBS' => 1,
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
'AM_DISABLE_SHARED' => 1,
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1, 'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'_LT_AC_LANG_RC_CONFIG' => 1,
'_LT_AC_SYS_COMPILER' => 1,
'_LT_AC_LANG_F77_CONFIG' => 1,
'LT_AC_PROG_EGREP' => 1,
'LT_LIB_DLLOAD' => 1,
'_LT_AC_LANG_GCJ_CONFIG' => 1,
'_LT_AC_LANG_F77' => 1,
'LTOBSOLETE_VERSION' => 1,
'LTDL_INSTALLABLE' => 1,
'_LT_PROG_ECHO_BACKSLASH' => 1,
'AM_SET_DEPDIR' => 1,
'AC_LTDL_SYMBOL_USCORE' => 1,
'AC_LIBLTDL_CONVENIENCE' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_LTDL_SHLIBPATH' => 1,
'AC_LTDL_ENABLE_INSTALL' => 1,
'_AM_CONFIG_MACRO_DIRS' => 1,
'AM_PROG_INSTALL_STRIP' => 1,
'AM_AUX_DIR_EXPAND' => 1,
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AC_LIBTOOL_PROG_CC_C_O' => 1,
'AC_LTDL_SHLIBEXT' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AM_MAKE_INCLUDE' => 1,
'AC_LTDL_SYSSEARCHPATH' => 1,
'LT_LANG' => 1,
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
'_LT_AC_SHELL_INIT' => 1,
'AC_LIBTOOL_CONFIG' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'LT_AC_PROG_SED' => 1,
'LTDL_CONVENIENCE' => 1,
'_LT_AC_FILE_LTDLL_C' => 1,
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
'AC_CHECK_LIBM' => 1,
'LT_WITH_LTDL' => 1,
'AM_MISSING_HAS_RUN' => 1,
'AM_MAINTAINER_MODE' => 1,
'AC_LIBTOOL_WIN32_DLL' => 1,
'LTOPTIONS_VERSION' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_LIBTOOL_CXX' => 1,
'LT_PATH_NM' => 1,
'LTSUGAR_VERSION' => 1,
'_LT_DLL_DEF_P' => 1,
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
'AC_CONFIG_MACRO_DIR' => 1,
'_LT_AC_LANG_CXX' => 1,
'LT_SUPPORTED_TAG' => 1,
'LT_PROG_GO' => 1,
'AC_LIBTOOL_RC' => 1,
'AC_LIBTOOL_DLOPEN' => 1,
'AM_DISABLE_STATIC' => 1,
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
'LT_OUTPUT' => 1,
'_LT_LINKER_BOILERPLATE' => 1,
'AC_ENABLE_SHARED' => 1,
'AM_PROG_CC_C_O' => 1, 'AM_PROG_CC_C_O' => 1,
'_LT_AC_LANG_CXX_CONFIG' => 1, 'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
'LT_PATH_LD' => 1, 'LT_PATH_NM' => 1,
'_LT_AC_PROG_ECHO_BACKSLASH' => 1, 'LTOBSOLETE_VERSION' => 1,
'AC_DISABLE_SHARED' => 1, 'AM_SET_DEPDIR' => 1,
'_LT_AC_LANG_GCJ' => 1, 'AM_INIT_AUTOMAKE' => 1,
'_LT_AC_TAGVAR' => 1, 'AM_PROG_LIBTOOL' => 1,
'LT_SYS_DLOPEN_SELF' => 1, 'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
'AC_LIBTOOL_SETUP' => 1, 'AM_AUX_DIR_EXPAND' => 1,
'AM_PROG_NM' => 1,
'AC_DEFUN_ONCE' => 1,
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
'_AM_AUTOCONF_VERSION' => 1,
'AC_DEFUN' => 1,
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
'AM_CONDITIONAL' => 1,
'_AM_SET_OPTIONS' => 1,
'AC_LIBTOOL_PICMODE' => 1,
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
'AC_PATH_TOOL_PREFIX' => 1,
'LT_SYS_DLSEARCH_PATH' => 1,
'm4_pattern_allow' => 1,
'_AM_DEPENDENCIES' => 1,
'AM_SUBST_NOTMAKE' => 1,
'LT_CMD_MAX_LEN' => 1,
'LT_PROG_RC' => 1,
'AC_DISABLE_STATIC' => 1, 'AC_DISABLE_STATIC' => 1,
'AC_DEPLIBS_CHECK_METHOD' => 1,
'_LTDL_SETUP' => 1,
'm4_pattern_forbid' => 1,
'_LT_AC_SYS_LIBPATH_AIX' => 1,
'AC_LIBTOOL_FC' => 1,
'_AM_PROG_TAR' => 1,
'LT_AC_PROG_GCJ' => 1,
'_AM_IF_OPTION' => 1,
'LTDL_INIT' => 1,
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
'_LT_LIBOBJ' => 1,
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AM_DEP_TRACK' => 1, 'AM_DEP_TRACK' => 1,
'_LT_COMPILER_OPTION' => 1, '_AM_DEPENDENCIES' => 1,
'AC_PROG_EGREP' => 1, 'LT_AC_PROG_RC' => 1,
'AM_RUN_LOG' => 1, '_AM_AUTOCONF_VERSION' => 1,
'_AM_MANGLE_OPTION' => 1, '_LT_AC_LANG_CXX' => 1,
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1, 'AC_LIBTOOL_OBJDIR' => 1,
'_LT_AC_PROG_CXXCPP' => 1, '_LT_AC_TRY_DLOPEN_SELF' => 1,
'AC_LTDL_DLSYM_USCORE' => 1, 'LTOPTIONS_VERSION' => 1,
'AM_SILENT_RULES' => 1,
'LTDL_INIT' => 1,
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
'_LT_AC_TAGVAR' => 1,
'AC_LTDL_PREOPEN' => 1,
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
'AM_SET_LEADING_DOT' => 1,
'_LT_AC_CHECK_DLFCN' => 1,
'_LT_DLL_DEF_P' => 1,
'_AM_PROG_TAR' => 1,
'm4_pattern_allow' => 1,
'_LT_CC_BASENAME' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AC_LTDL_DLLIB' => 1, 'AC_LTDL_DLLIB' => 1,
'LT_LIB_DLLOAD' => 1,
'_LT_AC_LANG_CXX_CONFIG' => 1,
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
'LT_AC_PROG_GCJ' => 1,
'AC_ENABLE_STATIC' => 1,
'AC_WITH_LTDL' => 1,
'AC_LIBTOOL_CONFIG' => 1,
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
'LT_SYS_DLOPEN_DEPLIBS' => 1,
'AC_LTDL_OBJDIR' => 1,
'AC_LIBTOOL_F77' => 1,
'AC_LIBTOOL_COMPILER_OPTION' => 1,
'_LT_AC_LANG_RC_CONFIG' => 1,
'_LT_PROG_ECHO_BACKSLASH' => 1,
'AC_PROG_LIBTOOL' => 1,
'AC_DEFUN' => 1,
'LTVERSION_VERSION' => 1,
'AM_SANITY_CHECK' => 1,
'AM_SUBST_NOTMAKE' => 1,
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
'LT_LIB_M' => 1,
'AC_PROG_LD_GNU' => 1,
'AC_LTDL_SHLIBEXT' => 1,
'_LT_COMPILER_OPTION' => 1,
'LT_SYS_SYMBOL_USCORE' => 1,
'AC_LTDL_SYSSEARCHPATH' => 1,
'AC_CHECK_LIBM' => 1,
'_LT_AC_LANG_GCJ_CONFIG' => 1,
'_LT_PROG_FC' => 1,
'AC_DISABLE_SHARED' => 1,
'LT_PROG_RC' => 1,
'LT_SYS_MODULE_EXT' => 1,
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
'LT_WITH_LTDL' => 1,
'AM_DISABLE_STATIC' => 1,
'AU_DEFUN' => 1,
'AC_ENABLE_SHARED' => 1,
'm4_pattern_forbid' => 1,
'AC_LIBTOOL_PICMODE' => 1,
'LT_INIT' => 1, 'LT_INIT' => 1,
'AC_LIBTOOL_GCJ' => 1, 'AC_LIBTOOL_GCJ' => 1,
'AC_PROG_LD_GNU' => 1, 'AC_LIBTOOL_DLOPEN_SELF' => 1,
'AC_PROG_LIBTOOL' => 1, 'AC_PATH_TOOL_PREFIX' => 1,
'LT_PROG_GCJ' => 1, 'AC_LTDL_SHLIBPATH' => 1,
'_LT_LINKER_OPTION' => 1, 'm4_include' => 1,
'LT_AC_PROG_RC' => 1, 'AC_LIBTOOL_DLOPEN' => 1,
'AC_LIBTOOL_POSTDEP_PREDEP' => 1, 'AC_LIBTOOL_PROG_CC_C_O' => 1,
'_AC_PROG_LIBTOOL' => 1, 'AM_AUTOMAKE_VERSION' => 1,
'_AM_SET_OPTION' => 1,
'AC_PROG_LD' => 1,
'LT_FUNC_ARGZ' => 1,
'AC_DISABLE_FAST_INSTALL' => 1,
'_LT_PROG_CXX' => 1,
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1, 'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
'_LT_PATH_TOOL_PREFIX' => 1, 'AM_PROG_LD' => 1,
'AM_SET_LEADING_DOT' => 1, 'LT_SYS_DLOPEN_SELF' => 1,
'LT_SYS_SYMBOL_USCORE' => 1, 'AM_PROG_INSTALL_SH' => 1,
'AM_SILENT_RULES' => 1, 'LT_OUTPUT' => 1,
'AC_LIB_LTDL' => 1, 'LT_LANG' => 1,
'_AM_PROG_CC_C_O' => 1, 'LT_SYS_DLSEARCH_PATH' => 1,
'_LT_AC_CHECK_DLFCN' => 1, '_LT_AC_LANG_GCJ' => 1,
'AC_ENABLE_FAST_INSTALL' => 1, 'AC_PROG_LD' => 1,
'_LT_CC_BASENAME' => 1,
'AC_LTDL_OBJDIR' => 1,
'_LT_PROG_LTMAIN' => 1,
'_m4_warn' => 1,
'AC_PROG_LD_RELOAD_FLAG' => 1,
'_LT_AC_TRY_DLOPEN_SELF' => 1,
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
'LT_FUNC_DLSYM_USCORE' => 1, 'LT_FUNC_DLSYM_USCORE' => 1,
'AC_LTDL_PREOPEN' => 1, 'AC_LIBTOOL_LINKER_OPTION' => 1,
'AC_ENABLE_STATIC' => 1 'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
'AM_RUN_LOG' => 1,
'LTSUGAR_VERSION' => 1,
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AC_LIBTOOL_SETUP' => 1,
'_LT_LINKER_BOILERPLATE' => 1,
'LT_FUNC_ARGZ' => 1,
'AM_PROG_INSTALL_STRIP' => 1,
'_AM_CONFIG_MACRO_DIRS' => 1,
'AM_PROG_NM' => 1,
'AC_LIBTOOL_FC' => 1,
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
'LT_AC_PROG_SED' => 1,
'AC_LIB_LTDL' => 1,
'AC_ENABLE_FAST_INSTALL' => 1,
'_LT_AC_LANG_C_CONFIG' => 1,
'_AM_SET_OPTIONS' => 1,
'LTDL_INSTALLABLE' => 1,
'_LT_PATH_TOOL_PREFIX' => 1,
'AC_DEPLIBS_CHECK_METHOD' => 1,
'AC_LTDL_DLSYM_USCORE' => 1,
'_LT_AC_SYS_COMPILER' => 1,
'AM_MISSING_HAS_RUN' => 1,
'LTDL_CONVENIENCE' => 1,
'_LT_COMPILER_BOILERPLATE' => 1,
'LT_AC_PROG_EGREP' => 1,
'AC_PROG_NM' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'LT_PROG_GO' => 1,
'_LT_AC_SYS_LIBPATH_AIX' => 1,
'_AM_MANGLE_OPTION' => 1,
'AM_MAKE_INCLUDE' => 1,
'AC_LIBTOOL_WIN32_DLL' => 1,
'AC_LIBTOOL_RC' => 1,
'_AM_IF_OPTION' => 1,
'_LT_WITH_SYSROOT' => 1,
'_AM_PROG_CC_C_O' => 1,
'_m4_warn' => 1,
'_LT_LIBOBJ' => 1,
'AC_LIBLTDL_INSTALLABLE' => 1,
'_LT_AC_SHELL_INIT' => 1,
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
'LT_PROG_GCJ' => 1,
'AM_MAINTAINER_MODE' => 1,
'AC_PROG_EGREP' => 1,
'LT_SUPPORTED_TAG' => 1,
'_LT_AC_FILE_LTDLL_C' => 1,
'_LT_LINKER_OPTION' => 1,
'_LT_AC_LANG_F77_CONFIG' => 1,
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
'_LT_AC_LANG_F77' => 1,
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
'_LT_PROG_CXX' => 1,
'AC_LTDL_SYMBOL_USCORE' => 1,
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
'LT_SYS_MODULE_PATH' => 1,
'AC_DISABLE_FAST_INSTALL' => 1,
'LT_PATH_LD' => 1,
'AC_PATH_MAGIC' => 1,
'AM_ENABLE_STATIC' => 1,
'LT_CMD_MAX_LEN' => 1,
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
'AM_DISABLE_SHARED' => 1,
'AC_LTDL_ENABLE_INSTALL' => 1,
'_LT_PROG_F77' => 1,
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
'AM_MISSING_PROG' => 1,
'_LT_AC_PROG_CXXCPP' => 1,
'AC_CONFIG_MACRO_DIR' => 1,
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
'AC_PROG_LD_RELOAD_FLAG' => 1,
'AC_DEFUN_ONCE' => 1,
'AC_LIBLTDL_CONVENIENCE' => 1,
'_LT_PROG_LTMAIN' => 1,
'_AM_SET_OPTION' => 1,
'_LTDL_SETUP' => 1,
'_AC_PROG_LIBTOOL' => 1,
'include' => 1,
'AC_LIBTOOL_CXX' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AM_CONDITIONAL' => 1,
'AM_ENABLE_SHARED' => 1
} }
], 'Autom4te::Request' ), ], 'Autom4te::Request' ),
bless( [ bless( [
@ -457,65 +457,65 @@
'configure.ac' 'configure.ac'
], ],
{ {
'AC_LIBSOURCE' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'include' => 1,
'AM_XGETTEXT_OPTION' => 1,
'sinclude' => 1, 'sinclude' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1, 'AC_REQUIRE_AUX_FILE' => 1,
'AC_FC_PP_SRCEXT' => 1,
'AC_PROG_LIBTOOL' => 1, 'AC_PROG_LIBTOOL' => 1,
'm4_sinclude' => 1, '_AM_COND_ELSE' => 1,
'AM_PATH_GUILE' => 1, 'AC_FC_PP_SRCEXT' => 1,
'_AM_SUBST_NOTMAKE' => 1, 'AC_CONFIG_SUBDIRS' => 1,
'AC_CANONICAL_TARGET' => 1, '_m4_warn' => 1,
'AM_PROG_CC_C_O' => 1,
'AM_MAINTAINER_MODE' => 1,
'AC_SUBST' => 1,
'LT_SUPPORTED_TAG' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AM_PROG_MKDIR_P' => 1, 'AM_PROG_MKDIR_P' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1, 'AC_DEFINE_TRACE_LITERAL' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_NLS' => 1,
'AC_CANONICAL_HOST' => 1,
'_AM_COND_ENDIF' => 1,
'AC_SUBST_TRACE' => 1,
'AM_GNU_GETTEXT' => 1,
'_AM_COND_IF' => 1,
'AM_POT_TOOLS' => 1,
'AM_PROG_F77_C_O' => 1,
'AM_PROG_FC_C_O' => 1,
'_AM_MAKEFILE_INCLUDE' => 1,
'LT_INIT' => 1,
'AC_CONFIG_FILES' => 1,
'AC_CANONICAL_BUILD' => 1,
'AM_PROG_CC_C_O' => 1,
'AC_CANONICAL_SYSTEM' => 1, 'AC_CANONICAL_SYSTEM' => 1,
'AM_AUTOMAKE_VERSION' => 1, 'AC_CONFIG_FILES' => 1,
'_AM_MAKEFILE_INCLUDE' => 1,
'AM_PROG_F77_C_O' => 1,
'AM_PROG_CXX_C_O' => 1, 'AM_PROG_CXX_C_O' => 1,
'AM_PROG_MOC' => 1, 'AC_CONFIG_AUX_DIR' => 1,
'_m4_warn' => 1, 'AM_PATH_GUILE' => 1,
'm4_pattern_allow' => 1, 'AC_CANONICAL_TARGET' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AM_MAKEFILE_INCLUDE' => 1,
'LT_SUPPORTED_TAG' => 1,
'm4_pattern_forbid' => 1,
'_AM_COND_ELSE' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AM_ENABLE_MULTILIB' => 1,
'AM_EXTRA_RECURSIVE_TARGETS' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'AM_SILENT_RULES' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_REQUIRE_AUX_FILE' => 1,
'AC_CONFIG_LINKS' => 1, 'AC_CONFIG_LINKS' => 1,
'AM_PROG_AR' => 1, '_AM_COND_IF' => 1,
'AC_FC_SRCEXT' => 1,
'AC_SUBST' => 1,
'AC_FC_FREEFORM' => 1,
'AC_INIT' => 1,
'AC_FC_PP_DEFINE' => 1, 'AC_FC_PP_DEFINE' => 1,
'AM_SILENT_RULES' => 1,
'AM_ENABLE_MULTILIB' => 1,
'AC_INIT' => 1,
'm4_pattern_forbid' => 1,
'AM_PROG_MOC' => 1,
'AC_FC_SRCEXT' => 1,
'AM_MAKEFILE_INCLUDE' => 1,
'LT_INIT' => 1,
'AC_CONFIG_HEADERS' => 1,
'm4_sinclude' => 1,
'AH_OUTPUT' => 1, 'AH_OUTPUT' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AM_POT_TOOLS' => 1,
'm4_include' => 1, 'm4_include' => 1,
'AM_MAINTAINER_MODE' => 1, 'AC_CANONICAL_BUILD' => 1,
'AM_CONDITIONAL' => 1 'm4_pattern_allow' => 1,
'AC_LIBSOURCE' => 1,
'AM_NLS' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'AM_GNU_GETTEXT' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_FC_FREEFORM' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AM_EXTRA_RECURSIVE_TARGETS' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AM_XGETTEXT_OPTION' => 1,
'AC_CANONICAL_HOST' => 1,
'AM_CONDITIONAL' => 1,
'_AM_COND_ENDIF' => 1,
'AM_PROG_FC_C_O' => 1,
'AC_SUBST_TRACE' => 1,
'include' => 1,
'AM_PROG_AR' => 1
} }
], 'Autom4te::Request' ) ], 'Autom4te::Request' )
); );

View File

@ -178,6 +178,9 @@ void breakpoint_hw_destroy(struct task *task)
void enable_scratch_hw_bp(struct task *task, struct breakpoint *bp) void enable_scratch_hw_bp(struct task *task, struct breakpoint *bp)
{ {
if (bp->deleted)
return;
if (bp->type == SW_BP) if (bp->type == SW_BP)
return; return;
@ -194,6 +197,9 @@ static void enable_hw_bp_cb(struct task *task, void *data)
void disable_scratch_hw_bp(struct task *task, struct breakpoint *bp) void disable_scratch_hw_bp(struct task *task, struct breakpoint *bp)
{ {
if (bp->deleted)
return;
if (bp->type == SW_BP) if (bp->type == SW_BP)
return; return;
@ -230,7 +236,9 @@ struct breakpoint *breakpoint_new_ext(struct task *task, arch_addr_t addr, struc
bp->addr = addr; bp->addr = addr;
bp->enabled = 0; bp->enabled = 0;
bp->locked = 0; bp->locked = 0;
bp->deleted = 0;
bp->ext = ext; bp->ext = ext;
bp->refcnt = 1;
switch(bp_type) { switch(bp_type) {
case HW_BP_SCRATCH: case HW_BP_SCRATCH:
@ -275,6 +283,9 @@ struct breakpoint *breakpoint_new(struct task *task, arch_addr_t addr, struct li
void breakpoint_enable(struct task *task, struct breakpoint *bp) void breakpoint_enable(struct task *task, struct breakpoint *bp)
{ {
if (bp->deleted)
return;
debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr); debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr);
if (!bp->enabled) { if (!bp->enabled) {
@ -295,6 +306,9 @@ void breakpoint_enable(struct task *task, struct breakpoint *bp)
void breakpoint_disable(struct task *task, struct breakpoint *bp) void breakpoint_disable(struct task *task, struct breakpoint *bp)
{ {
if (bp->deleted)
return;
debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr); debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr);
if (bp->enabled) { if (bp->enabled) {
@ -338,6 +352,9 @@ void breakpoint_delete(struct task *task, struct breakpoint *bp)
{ {
struct task *leader = task->leader; struct task *leader = task->leader;
if (bp->deleted)
return;
debug(DEBUG_FUNCTION, "pid=%d, addr=%lx", task->pid, bp->addr); debug(DEBUG_FUNCTION, "pid=%d, addr=%lx", task->pid, bp->addr);
breakpoint_disable(task, bp); breakpoint_disable(task, bp);
@ -355,9 +372,11 @@ void breakpoint_delete(struct task *task, struct breakpoint *bp)
assert(slot == HW_BP_SCRATCH_SLOT); assert(slot == HW_BP_SCRATCH_SLOT);
} }
#endif #endif
bp->deleted = 1;
dict_remove_entry(leader->breakpoints, (unsigned long)bp->addr); dict_remove_entry(leader->breakpoints, (unsigned long)bp->addr);
free(bp);
breakpoint_unref(bp);
} }
static int enable_nonlocked_bp_cb(unsigned long key, const void *value, void *data) static int enable_nonlocked_bp_cb(unsigned long key, const void *value, void *data)
@ -471,6 +490,9 @@ static int clone_single_cb(unsigned long key, const void *value, void *data)
struct library_symbol *libsym = bp->libsym ? find_symbol(new_task, bp->libsym->addr) : NULL; struct library_symbol *libsym = bp->libsym ? find_symbol(new_task, bp->libsym->addr) : NULL;
size_t ext = bp->ext; size_t ext = bp->ext;
if (bp->deleted)
return 0;
struct breakpoint *new_bp = malloc(sizeof(*new_bp) + ext); struct breakpoint *new_bp = malloc(sizeof(*new_bp) + ext);
if (!new_bp) if (!new_bp)
goto fail1; goto fail1;

View File

@ -37,8 +37,10 @@ struct breakpoint {
arch_addr_t addr; arch_addr_t addr;
unsigned int enabled:1; unsigned int enabled:1;
unsigned int locked:1; unsigned int locked:1;
unsigned int deleted:1;
unsigned int type:2; unsigned int type:2;
unsigned int ext:8; unsigned int ext:8;
unsigned int refcnt;
union { union {
unsigned char orig_value[BREAKPOINT_LENGTH]; unsigned char orig_value[BREAKPOINT_LENGTH];
#if HW_BREAKPOINTS > 0 #if HW_BREAKPOINTS > 0
@ -104,5 +106,22 @@ static inline void breakpoint_hw_destroy(struct task *task)
} }
#endif #endif
static inline struct breakpoint *breakpoint_ref(struct breakpoint *bp)
{
if (bp)
++bp->refcnt;
return bp;
}
static inline int breakpoint_unref(struct breakpoint *bp)
{
if (bp) {
if (--bp->refcnt)
return 0;
free(bp);
}
return 1;
}
#endif #endif

View File

@ -35,6 +35,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <signal.h>
#include "binfile.h" #include "binfile.h"
#include "common.h" #include "common.h"
@ -59,6 +60,7 @@ static struct rb_root pid_table;
static int first_pid; static int first_pid;
static struct memtrace_info mt_info; static struct memtrace_info mt_info;
static struct thread *thread; static struct thread *thread;
static int pipefd[2];
static unsigned long skip_nl(const char *p, unsigned long n) static unsigned long skip_nl(const char *p, unsigned long n)
{ {
@ -563,6 +565,35 @@ static int client_init(int do_trace)
return 0; return 0;
} }
static void signal_exit(int sig)
{
const char signum = sig;
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
write(pipefd[1], &signum, 1);
}
static int scan_process(struct process *process)
{
if (options.auto_scan) {
process_leaks_scan(process, SCAN_ALL);
client_wait_op(MT_SCAN);
}
else
process_dump_sortby(process);
return 0;
}
static int signal_func(void)
{
fprintf(stderr, "terminating...\n");
client_iterate_processes(scan_process);
exit(0);
}
int client_start(void) int client_start(void)
{ {
if (client_init(0) < 0) if (client_init(0) < 0)
@ -591,10 +622,28 @@ int client_start(void)
ioevent_add_input(client_fd, client_func); ioevent_add_input(client_fd, client_func);
if (options.interactive) {
readline_init(); readline_init();
while(ioevent_watch(-1) != -1) while(ioevent_watch(-1) != -1)
; ;
}
else {
if (pipe(pipefd) == -1) {
fprintf(stderr, "could not create pipe (%s)", strerror(errno));
return -1;
}
ioevent_add_input(pipefd[0], signal_func);
signal(SIGINT, signal_exit); /* Detach task_es when interrupted */
signal(SIGTERM, signal_exit); /* ... or killed */
while(client_fd != -1) {
if (ioevent_watch(-1) == -1)
break;
}
}
return 0; return 0;
} }

View File

@ -1084,20 +1084,8 @@ void *process_scan(struct process *process, void *leaks, uint32_t payload_len)
dump_printf("leaks total: %lu\n", process->leaks); dump_printf("leaks total: %lu\n", process->leaks);
dump_flush(); dump_flush();
if (!options.interactive && (process->status == MT_PROCESS_EXITING || process->status == MT_PROCESS_DETACH)) { if (!options.interactive)
if (options.sort_by == OPT_SORT_BYTES_LEAKED) process_dump_sortby(process);
_process_dump(process, sort_bytes_leaked, skip_zero_leaks, options.output);
else
_process_dump(process, sort_leaks, skip_zero_leaks, options.output);
if (process->status == MT_PROCESS_EXITING) {
process_set_status(process, MT_PROCESS_EXIT);
client_send_msg(process, MT_EXIT, NULL, 0);
}
else
client_send_msg(process, MT_DETACH, NULL, 0);
}
return leaks; return leaks;
} }
@ -1327,35 +1315,8 @@ struct process *process_new(pid_t pid, unsigned int swap_endian, unsigned int tr
} }
void process_exit(struct process *process) void process_dump_sortby(struct process *process)
{ {
process_set_status(process, MT_PROCESS_EXIT);
if (options.client || (!options.client && !options.verbose))
fprintf(options.output, "+++ process %d exited +++\n", process->pid);
if (!options.interactive)
_process_dump(process, sort_allocations, skip_zero_allocations, options.output);
}
void process_about_exit(struct process *process)
{
process_set_status(process, MT_PROCESS_EXITING);
if (options.auto_scan)
process_leaks_scan(process, SCAN_ALL);
}
void process_detach(struct process *process)
{
process_set_status(process, MT_PROCESS_DETACH);
if (!options.interactive) {
if (options.auto_scan) {
process_leaks_scan(process, SCAN_ALL);
return;
}
else {
switch(options.sort_by) { switch(options.sort_by) {
case OPT_SORT_AVERAGE: case OPT_SORT_AVERAGE:
_process_dump(process, sort_average, skip_zero_allocations, options.output); _process_dump(process, sort_average, skip_zero_allocations, options.output);
@ -1377,8 +1338,38 @@ void process_detach(struct process *process)
break; break;
} }
} }
void process_exit(struct process *process)
{
process_set_status(process, MT_PROCESS_EXIT);
if (options.client || (!options.client && !options.verbose))
fprintf(stderr, "+++ process %d exited +++\n", process->pid);
if (!options.interactive)
process_dump_sortby(process);
} }
void process_about_exit(struct process *process)
{
process_set_status(process, MT_PROCESS_EXITING);
if (options.auto_scan)
process_leaks_scan(process, SCAN_ALL);
client_send_msg(process, MT_ABOUT_EXIT, NULL, 0);
}
void process_detach(struct process *process)
{
process_set_status(process, MT_PROCESS_DETACH);
if (options.auto_scan)
process_leaks_scan(process, SCAN_ALL);
else
if (!options.interactive)
process_dump_sortby(process);
client_send_msg(process, MT_DETACH, NULL, 0); client_send_msg(process, MT_DETACH, NULL, 0);
} }

View File

@ -101,6 +101,7 @@ void process_detach(struct process *process);
unsigned long process_leaks_scan(struct process *process, int mode); unsigned long process_leaks_scan(struct process *process, int mode);
void process_dump_sortby(struct process *process);
void process_dump_sort_average(struct process *process, const char *outfile); void process_dump_sort_average(struct process *process, const char *outfile);
void process_dump_sort_usage(struct process *process, const char *outfile); void process_dump_sort_usage(struct process *process, const char *outfile);
void process_dump_sort_leaks(struct process *process, const char *outfile); void process_dump_sort_leaks(struct process *process, const char *outfile);

View File

@ -676,6 +676,8 @@ static int do_reset(struct cmd_opt *cmd, int argc, const char *argv[])
if (!process) if (!process)
return -1; return -1;
process->attached = 1;
process_reset_allocations(process); process_reset_allocations(process);
return 0; return 0;
@ -829,9 +831,6 @@ static int readline_func(void)
void readline_init(void) void readline_init(void)
{ {
if (!options.interactive)
return;
rl_terminal_name = getenv("TERM"); rl_terminal_name = getenv("TERM");
rl_instream = stdin; rl_instream = stdin;
rl_outstream = stderr; rl_outstream = stderr;

View File

@ -46,8 +46,7 @@ void _debug(int level, const char *file, const char *function, int line, const c
abort(); abort();
va_end(args); va_end(args);
fprintf(options.output, "DEBUG: %s():%s@%d - %s\n", function, file, line, buf); fprintf(stderr, "DEBUG: %s():%s@%d - %s\n", function, file, line, buf);
fflush(options.output);
} }
#endif #endif

28
event.c
View File

@ -110,7 +110,7 @@ static void show_clone(struct task *task, enum event_type type)
str = "?"; str = "?";
break; break;
} }
fprintf(options.output, "+++ process pid=%d %s (newpid=%d) +++\n", task->pid, str, task->event.e_un.newpid); fprintf(stderr, "+++ process pid=%d %s (newpid=%d) +++\n", task->pid, str, task->event.e_un.newpid);
} }
static struct task *handle_clone(struct task *task, enum event_type type) static struct task *handle_clone(struct task *task, enum event_type type)
@ -167,7 +167,7 @@ static struct task *handle_signal(struct task *task)
static void show_exit(struct task *task) static void show_exit(struct task *task)
{ {
if (options.verbose) if (options.verbose)
fprintf(options.output, "+++ process pid=%d exited (status=%d) +++\n", task->pid, task->event.e_un.ret_val); fprintf(stderr, "+++ process pid=%d exited (status=%d) +++\n", task->pid, task->event.e_un.ret_val);
} }
@ -175,7 +175,7 @@ static struct task *handle_about_exit(struct task *task)
{ {
if (task->leader == task) if (task->leader == task)
report_about_exit(task); report_about_exit(task);
else
continue_task(task, 0); continue_task(task, 0);
return task; return task;
@ -198,7 +198,7 @@ static struct task *handle_exit(struct task *task)
static struct task *handle_exit_signal(struct task *task) static struct task *handle_exit_signal(struct task *task)
{ {
if (options.verbose) if (options.verbose)
fprintf(options.output, "+++ process pid=%d killed by signal %s (%d) +++\n", task->pid, strsignal(task->event.e_un.signum), task->event.e_un.signum); fprintf(stderr, "+++ process pid=%d killed by signal %s (%d) +++\n", task->pid, strsignal(task->event.e_un.signum), task->event.e_un.signum);
if (task->leader == task) { if (task->leader == task) {
report_exit(task); report_exit(task);
@ -223,7 +223,7 @@ static struct task *handle_exec(struct task *task)
} }
if (options.verbose) if (options.verbose)
fprintf(options.output, "+++ process pid=%d exec (%s) +++\n", task->pid, library_execname(task)); fprintf(stderr, "+++ process pid=%d exec (%s) +++\n", task->pid, library_execname(task));
continue_task(task, 0); continue_task(task, 0);
return task; return task;
@ -253,15 +253,26 @@ static struct task *handle_breakpoint(struct task *task)
debug(DEBUG_FUNCTION, "pid=%d, addr=%#lx", task->pid, bp->addr); debug(DEBUG_FUNCTION, "pid=%d, addr=%#lx", task->pid, bp->addr);
if (bp->deleted) {
struct breakpoint *nbp = breakpoint_find(task, bp->addr);
if (!nbp)
nbp = bp;
skip_breakpoint(task, nbp);
goto end;
}
if (task->skip_bp == bp) { if (task->skip_bp == bp) {
breakpoint_unref(task->skip_bp);
task->skip_bp = NULL; task->skip_bp = NULL;
skip_breakpoint(task, bp); skip_breakpoint(task, bp);
return task; goto end;
} }
if (breakpoint_on_hit(task, bp)) { if (breakpoint_on_hit(task, bp)) {
continue_task(task, 0); continue_task(task, 0);
return task; goto end;
} }
if (bp->libsym && !task->breakpoint) { if (bp->libsym && !task->breakpoint) {
@ -286,6 +297,9 @@ static struct task *handle_breakpoint(struct task *task)
if (task->stopped) if (task->stopped)
skip_breakpoint(task, bp); skip_breakpoint(task, bp);
end:
breakpoint_unref(bp);
return task; return task;
} }

View File

@ -240,27 +240,6 @@ void library_add(struct task *leader, struct library *lib)
report_add_map(leader, lib); report_add_map(leader, lib);
} }
void cb_remove_breakpoint_for_symbol(struct library_symbol *libsym, void *data)
{
struct task *task = data;
arch_addr_t addr = libsym->addr;
struct breakpoint *bp = breakpoint_find(task, addr);
if (bp)
breakpoint_delete(task, bp);
}
void library_remove(struct task *leader, struct library *lib)
{
debug(DEBUG_PROCESS, "%s@%#lx to pid=%d", lib->filename, lib->base, leader->pid);
library_each_symbol(lib, cb_remove_breakpoint_for_symbol, leader);
list_del(&lib->list);
report_del_map(leader, lib);
}
void library_clear_all(struct task *leader) void library_clear_all(struct task *leader)
{ {
library_delete_list(leader, &leader->libraries_list); library_delete_list(leader, &leader->libraries_list);

4
main.c
View File

@ -58,7 +58,7 @@ void mtrace_request_exit(void)
return; return;
if (options.verbose) if (options.verbose)
fprintf(options.output, "+++ request exit +++\n"); fprintf(stderr, "+++ request exit +++\n");
do_exit = 1; do_exit = 1;
wait_event_wakeup(); wait_event_wakeup();
@ -112,7 +112,7 @@ static void mtrace_init(char **cmd)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
if (options.verbose) if (options.verbose)
fprintf(options.output, "+++ process pid=%d created (%s) +++\n", task->pid, library_execname(task)); fprintf(stderr, "+++ process pid=%d created (%s) +++\n", task->pid, library_execname(task));
} }
for(opt_p_tmp = options.opt_p; opt_p_tmp; opt_p_tmp = opt_p_tmp->next) for(opt_p_tmp = options.opt_p; opt_p_tmp; opt_p_tmp = opt_p_tmp->next)

View File

@ -88,6 +88,7 @@ static void usage(void)
" -i, --interactive interactive client mode\n" " -i, --interactive interactive client mode\n"
" -k, --kill abort mtrace on unexpected error conditon\n" " -k, --kill abort mtrace on unexpected error conditon\n"
" -l, --listen listen on socket path or address in server mode\n" " -l, --listen listen on socket path or address in server mode\n"
" -n, --nocpp disable trace of c++ allocation operators (faster for libstdc++)\n"
" -o, --output=FILE write the trace output to file with given name\n" " -o, --output=FILE write the trace output to file with given name\n"
" -p, --pid=PID attach to the process with the process ID pid (may be repeated)\n" " -p, --pid=PID attach to the process with the process ID pid (may be repeated)\n"
" -P, --port=PORT socket port (default: " STR(DEFAULT_PORT) ")\n" " -P, --port=PORT socket port (default: " STR(DEFAULT_PORT) ")\n"
@ -263,6 +264,7 @@ char **process_options(int argc, char **argv)
options.sort_by = -1; options.sort_by = -1;
options.debug = 0; options.debug = 0;
options.kill = 0; options.kill = 0;
options.nocpp = 0;
for(;;) { for(;;) {
int c; int c;
@ -281,6 +283,7 @@ char **process_options(int argc, char **argv)
{ "interactive", 0, 0, 'i' }, { "interactive", 0, 0, 'i' },
{ "kill", 0, 0, 'k' }, { "kill", 0, 0, 'k' },
{ "listen", 1, 0, 'l' }, { "listen", 1, 0, 'l' },
{ "nocpp", 1, 0, 'n' },
{ "output", 1, 0, 'o' }, { "output", 1, 0, 'o' },
{ "pid", 1, 0, 'p' }, { "pid", 1, 0, 'p' },
{ "port", 1, 0, 'P' }, { "port", 1, 0, 'P' },
@ -293,7 +296,7 @@ char **process_options(int argc, char **argv)
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
c = getopt_long(argc, argv, c = getopt_long(argc, argv,
"+aefhiksVvw" "+aefhiknsVvw"
"b:c:C:D:F:l:o:p:P:u:d:S:", "b:c:C:D:F:l:o:p:P:u:d:S:",
long_options, long_options,
&option_index); &option_index);
@ -373,6 +376,9 @@ char **process_options(int argc, char **argv)
case 'o': case 'o':
output = optarg; output = optarg;
break; break;
case 'n':
options.nocpp = 1;
break;
case 'p': case 'p':
{ {
struct opt_p_t *tmp = malloc(sizeof(*tmp)); struct opt_p_t *tmp = malloc(sizeof(*tmp));
@ -482,7 +488,11 @@ char **process_options(int argc, char **argv)
fprintf(stderr, "%s: client mode does not require -p nor executable\n", progname); fprintf(stderr, "%s: client mode does not require -p nor executable\n", progname);
err_usage(); err_usage();
} }
else
if (options.client && options.nocpp) {
fprintf(stderr, "%s: client mode does not require -n\n", progname);
err_usage();
}
if (options.client && options.server) { if (options.client && options.server) {
fprintf(stderr, "%s: choose between client and server mode\n", progname); fprintf(stderr, "%s: choose between client and server mode\n", progname);

View File

@ -77,6 +77,7 @@ struct options_t {
struct opt_b_t *opt_b; /* binary search path(s) */ struct opt_b_t *opt_b; /* binary search path(s) */
int sort_by; /* sort dump in non interative and non server mode */ int sort_by; /* sort dump in non interative and non server mode */
int debug; /* debug */ int debug; /* debug */
int nocpp; /* disable trace of c++ allocation operators */
}; };
char **process_options(int argc, char **argv); char **process_options(int argc, char **argv);

View File

@ -343,6 +343,9 @@ const struct function *flist_matches_symbol(const char *sym_name)
unsigned int i; unsigned int i;
for(i = 0; i < ARRAY_SIZE(flist); ++i) { for(i = 0; i < ARRAY_SIZE(flist); ++i) {
if (options.nocpp && flist[i].name[0] == '_')
continue;
if (!strcmp(sym_name, flist[i].name)) if (!strcmp(sym_name, flist[i].name))
return &flist[i]; return &flist[i];
} }

View File

@ -25,9 +25,6 @@
#include "forward.h" #include "forward.h"
#define REPORT_ENTER 1
#define REPORT_LEAVE 2
struct function { struct function {
/* symbol name */ /* symbol name */
const char *name; const char *name;

View File

@ -64,10 +64,10 @@ static void stop_trace(struct task *leader)
list_for_each(it, &leader->task_list) { list_for_each(it, &leader->task_list) {
struct task *task = container_of(it, struct task, task_list); struct task *task = container_of(it, struct task, task_list);
task->breakpoint = NULL; task_reset_bp(task);
} }
leader->breakpoint = NULL; task_reset_bp(leader);
} }
static void start_trace(struct task *leader) static void start_trace(struct task *leader)
@ -149,7 +149,7 @@ int server_handle_command(void)
if (ret != sizeof(cmd)) { if (ret != sizeof(cmd)) {
if (ret > 0) { if (ret > 0) {
if (!options.verbose) if (options.verbose)
fprintf(stderr, "cmd read wrong size %d\n", ret); fprintf(stderr, "cmd read wrong size %d\n", ret);
} }
server_close(); server_close();
@ -200,8 +200,8 @@ int server_handle_command(void)
case MT_DETACH: case MT_DETACH:
detach_proc(task); detach_proc(task);
break; break;
case MT_EXIT: case MT_ABOUT_EXIT:
remove_proc(task); continue_task(task, 0);
break; break;
default: default:
break; break;

View File

@ -251,6 +251,7 @@ static void process_event(struct task *task, int status)
for(i = 0; i < HW_BREAKPOINTS; ++i) { for(i = 0; i < HW_BREAKPOINTS; ++i) {
if (task->hw_bp[i] && task->hw_bp[i]->addr == ip) { if (task->hw_bp[i] && task->hw_bp[i]->addr == ip) {
/* todo: check if this was really a hw bp */
bp = task->hw_bp[i]; bp = task->hw_bp[i];
break; break;
} }
@ -276,9 +277,8 @@ static void process_event(struct task *task, int status)
if (!bp->enabled) if (!bp->enabled)
return; return;
#endif #endif
task->event.type = EVENT_BREAKPOINT; task->event.type = EVENT_BREAKPOINT;
task->event.e_un.breakpoint = bp; task->event.e_un.breakpoint = breakpoint_ref(bp);
debug(DEBUG_EVENT, "BREAKPOINT: pid=%d, addr=%#lx", task->pid, task->event.e_un.breakpoint->addr); debug(DEBUG_EVENT, "BREAKPOINT: pid=%d, addr=%#lx", task->pid, task->event.e_un.breakpoint->addr);

64
task.c
View File

@ -174,39 +174,52 @@ static int task_init(struct task *task, int attached)
return 0; return 0;
} }
static void leader_cleanup(struct task *task) static int leader_cleanup(struct task *leader)
{ {
if (!task->leader) if (!leader)
return; return 0;
task->leader->threads--; if (--leader->threads)
return 0;
if (task->leader != task) library_clear_all(leader);
return; breakpoint_clear_all(leader);
backtrace_destroy(leader);
if (task->breakpoint) { return 1;
breakpoint_delete(task, task->breakpoint);
task->breakpoint = NULL;
} }
library_clear_all(task); static void leader_release(struct task *leader)
breakpoint_clear_all(task); {
backtrace_destroy(task); if (!leader_cleanup(leader))
return;
list_del(&task->leader_list); list_del(&leader->leader_list);
free(leader);
} }
static void task_destroy(struct task *task) static void task_destroy(struct task *task)
{ {
struct task *leader = task->leader;
if (task->deleted)
return;
task->deleted = 1;
arch_task_destroy(task); arch_task_destroy(task);
os_task_destroy(task); os_task_destroy(task);
detach_task(task); detach_task(task);
leader_cleanup(task);
list_del(&task->task_list);
rb_erase(&task->pid_node, &pid_tree); rb_erase(&task->pid_node, &pid_tree);
if (leader != task) {
list_del(&task->task_list);
free(task); free(task);
} }
leader_release(leader);
}
struct task *task_new(pid_t pid, int traced) struct task *task_new(pid_t pid, int traced)
{ {
struct task *task = malloc(sizeof(*task)); struct task *task = malloc(sizeof(*task));
@ -361,10 +374,16 @@ int task_fork(struct task *task, struct task *newtask)
newtask->libsym = task->libsym; newtask->libsym = task->libsym;
newtask->context = task->context; newtask->context = task->context;
newtask->breakpoint = task->breakpoint;
if (task->breakpoint) if (task->breakpoint)
newtask->breakpoint = breakpoint_find(newtask, newtask->breakpoint->addr); newtask->breakpoint = breakpoint_find(newtask, newtask->breakpoint->addr);
else
newtask->breakpoint = NULL;
if (task->skip_bp)
newtask->skip_bp = breakpoint_ref(breakpoint_find(newtask, newtask->skip_bp->addr));
else
newtask->skip_bp = NULL;
if (arch_task_clone(newtask, task) < 0) if (arch_task_clone(newtask, task) < 0)
goto fail; goto fail;
@ -380,6 +399,14 @@ fail:
return -1; return -1;
} }
void task_reset_bp(struct task *task)
{
breakpoint_unref(task->skip_bp);
task->breakpoint = NULL;
task->skip_bp = NULL;
}
static struct task *open_one_pid(pid_t pid) static struct task *open_one_pid(pid_t pid)
{ {
struct task *task; struct task *task;
@ -405,7 +432,7 @@ fail1:
static void show_attached(struct task *task, void *data) static void show_attached(struct task *task, void *data)
{ {
fprintf(options.output, "+++ process pid=%d attached (%s) +++\n", task->pid, library_execname(task->leader)); fprintf(stderr, "+++ process pid=%d attached (%s) +++\n", task->pid, library_execname(task->leader));
} }
@ -532,8 +559,7 @@ void remove_proc(struct task *leader)
assert(leader->leader == leader); assert(leader->leader == leader);
breakpoint_disable_all(leader); breakpoint_disable_all(leader);
each_task(leader, &remove_task_cb, leader); each_task(leader, &remove_task_cb, NULL);
remove_task(leader);
} }
int task_list_empty(void) int task_list_empty(void)

4
task.h
View File

@ -47,6 +47,7 @@ struct task {
unsigned int was_stopped:1; unsigned int was_stopped:1;
unsigned int is_64bit:1; unsigned int is_64bit:1;
unsigned int attached:1; unsigned int attached:1;
unsigned int deleted:1;
/* Dictionary of breakpoints */ /* Dictionary of breakpoints */
struct dict *breakpoints; struct dict *breakpoints;
@ -115,6 +116,9 @@ int task_clone(struct task *task, struct task *newtask);
/* Fork the contents of a task */ /* Fork the contents of a task */
int task_fork(struct task *task, struct task *newtask); int task_fork(struct task *task, struct task *newtask);
/* reset all breakpoints for task */
void task_reset_bp(struct task *task);
/* get first process of leader list */ /* get first process of leader list */
struct task *get_first_process(void); struct task *get_first_process(void);

16
trace.c
View File

@ -55,12 +55,14 @@ int skip_breakpoint(struct task *task, struct breakpoint *bp)
ret = do_singlestep(task); ret = do_singlestep(task);
breakpoint_enable(task, bp); breakpoint_enable(task, bp);
if (ret) { if (ret) {
if (ret == 1) if (ret == 1) {
task->skip_bp = bp; breakpoint_unref(task->skip_bp);
task->skip_bp = breakpoint_ref(bp);
}
return ret; return ret;
} }
} }
continue_task(task, 0); continue_task(task, 0);
return 0; return 0;
} }
@ -69,8 +71,13 @@ void detach_task(struct task *task)
{ {
int sig = 0; int sig = 0;
task_reset_bp(task);
if (task->event.type == EVENT_SIGNAL) if (task->event.type == EVENT_SIGNAL)
sig = task->event.e_un.signum; sig = task->event.e_un.signum;
else
if (task->event.type == EVENT_BREAKPOINT)
breakpoint_unref(task->event.e_un.breakpoint);
remove_event(task); remove_event(task);
breakpoint_hw_destroy(task); breakpoint_hw_destroy(task);
@ -79,7 +86,7 @@ void detach_task(struct task *task)
static void detach_cb(struct task *task, void *data) static void detach_cb(struct task *task, void *data)
{ {
detach_task(task); remove_task(task);
} }
void detach_proc(struct task *leader) void detach_proc(struct task *leader)
@ -88,6 +95,5 @@ void detach_proc(struct task *leader)
breakpoint_disable_all(leader); breakpoint_disable_all(leader);
each_task(leader, &detach_cb, NULL); each_task(leader, &detach_cb, NULL);
remove_task(leader);
} }