Commit f9b58c51 authored by 's avatar

Re-organize the way to produce stacktrace.

Since we introduced the API to set signal handler and print a
stacktrace, we should avoid glibc's backtrace, which may call malloc.
Basically, we choose the way to produce a stacktrace as same as
perftools.

Also, I removed GetStackFrames, which is not used and not implemented
with glibc.


git-svn-id: https://google-glog.googlecode.com/svn/trunk@16 eb4d4688-79bd-11dd-afb4-1d65580434c0
parent 62a67b25
......@@ -40,6 +40,9 @@ dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
## The libraries (.so's) you want to install
lib_LTLIBRARIES =
# The libraries libglog depends on.
COMMON_LIBS=$(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS)
## unittests you want to run when people type 'make check'.
## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
......@@ -57,7 +60,7 @@ logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_unittest.cc
logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
logging_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_unittest_LDADD = libglog.la $(COMMON_LIBS)
check_SCRIPTS += logging_striplog_test_sh
noinst_SCRIPTS += src/logging_striplog_test.sh
......@@ -82,63 +85,63 @@ logging_striptest0_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_striptest_main.cc
logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS)
logging_striptest0_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_striptest0_LDADD = libglog.la $(COMMON_LIBS)
TEST_BINARIES += logging_striptest2
logging_striptest2_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_striptest2.cc
logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS)
logging_striptest2_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_striptest2_LDADD = libglog.la $(COMMON_LIBS)
TEST_BINARIES += logging_striptest10
logging_striptest10_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_striptest10.cc
logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS)
logging_striptest10_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_striptest10_LDADD = libglog.la $(COMMON_LIBS)
TESTS += demangle_unittest
demangle_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/demangle_unittest.cc
demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
demangle_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
demangle_unittest_LDADD = libglog.la $(COMMON_LIBS)
TESTS += stacktrace_unittest
stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/stacktrace_unittest.cc
stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
stacktrace_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS)
TESTS += symbolize_unittest
symbolize_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/symbolize_unittest.cc
symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
symbolize_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
TESTS += stacktrace_framesizes_unittest
stacktrace_framesizes_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/stacktrace_framesizes_unittest.cc
stacktrace_framesizes_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
stacktrace_framesizes_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
stacktrace_framesizes_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS)
TESTS += stl_logging_unittest
stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/stl_logging_unittest.cc
stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
stl_logging_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS)
TEST_BINARIES += signalhandler_unittest
signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/signalhandler_unittest.cc
signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
signalhandler_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS)
TESTS += utilities_unittest
utilities_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/utilities_unittest.cc
utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
utilities_unittest_LDADD = libglog.la $(COMMON_LIBS)
## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
......@@ -147,7 +150,7 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \
src/utilities.cc src/utilities.h \
src/demangle.cc src/demangle.h \
src/stacktrace.cc src/stacktrace.h \
src/stacktrace.h \
src/stacktrace_generic-inl.h \
src/stacktrace_libunwind-inl.h \
src/stacktrace_powerpc-inl.h \
......@@ -160,7 +163,7 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \
libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) -DNDEBUG
libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS)
libglog_la_LIBADD = $(PTHREAD_LIBS)
libglog_la_LIBADD = $(COMMON_LIBS)
## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
......
......@@ -45,8 +45,7 @@ host_triplet = @host@
@ENABLE_FRAME_POINTERS_FALSE@@X86_64_TRUE@am__append_3 = -DNO_FRAME_POINTER
TESTS = logging_unittest$(EXEEXT) demangle_unittest$(EXEEXT) \
stacktrace_unittest$(EXEEXT) symbolize_unittest$(EXEEXT) \
stacktrace_framesizes_unittest$(EXEEXT) \
stl_logging_unittest$(EXEEXT)
stl_logging_unittest$(EXEEXT) utilities_unittest$(EXEEXT)
noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
subdir = .
DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \
......@@ -87,29 +86,28 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libglog_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
libglog_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
am__objects_1 =
am_libglog_la_OBJECTS = $(am__objects_1) libglog_la-logging.lo \
libglog_la-raw_logging.lo libglog_la-vlog_is_on.lo \
libglog_la-utilities.lo libglog_la-demangle.lo \
libglog_la-stacktrace.lo libglog_la-symbolize.lo \
libglog_la-signalhandler.lo
libglog_la-symbolize.lo libglog_la-signalhandler.lo
libglog_la_OBJECTS = $(am_libglog_la_OBJECTS)
libglog_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libglog_la_CXXFLAGS) \
$(CXXFLAGS) $(libglog_la_LDFLAGS) $(LDFLAGS) -o $@
am__EXEEXT_1 = logging_unittest$(EXEEXT) demangle_unittest$(EXEEXT) \
stacktrace_unittest$(EXEEXT) symbolize_unittest$(EXEEXT) \
stacktrace_framesizes_unittest$(EXEEXT) \
stl_logging_unittest$(EXEEXT)
stl_logging_unittest$(EXEEXT) utilities_unittest$(EXEEXT)
am__EXEEXT_2 = logging_striptest0$(EXEEXT) logging_striptest2$(EXEEXT) \
logging_striptest10$(EXEEXT) signalhandler_unittest$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
am_demangle_unittest_OBJECTS = $(am__objects_1) \
demangle_unittest-demangle_unittest.$(OBJEXT)
demangle_unittest_OBJECTS = $(am_demangle_unittest_OBJECTS)
demangle_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
demangle_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
demangle_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(demangle_unittest_CXXFLAGS) $(CXXFLAGS) \
......@@ -117,8 +115,7 @@ demangle_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_logging_striptest0_OBJECTS = $(am__objects_1) \
logging_striptest0-logging_striptest_main.$(OBJEXT)
logging_striptest0_OBJECTS = $(am_logging_striptest0_OBJECTS)
logging_striptest0_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
logging_striptest0_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
logging_striptest0_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(logging_striptest0_CXXFLAGS) $(CXXFLAGS) \
......@@ -126,8 +123,7 @@ logging_striptest0_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_logging_striptest10_OBJECTS = $(am__objects_1) \
logging_striptest10-logging_striptest10.$(OBJEXT)
logging_striptest10_OBJECTS = $(am_logging_striptest10_OBJECTS)
logging_striptest10_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
logging_striptest10_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
logging_striptest10_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(logging_striptest10_CXXFLAGS) $(CXXFLAGS) \
......@@ -135,8 +131,7 @@ logging_striptest10_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_logging_striptest2_OBJECTS = $(am__objects_1) \
logging_striptest2-logging_striptest2.$(OBJEXT)
logging_striptest2_OBJECTS = $(am_logging_striptest2_OBJECTS)
logging_striptest2_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
logging_striptest2_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
logging_striptest2_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(logging_striptest2_CXXFLAGS) $(CXXFLAGS) \
......@@ -144,8 +139,7 @@ logging_striptest2_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_logging_unittest_OBJECTS = $(am__objects_1) \
logging_unittest-logging_unittest.$(OBJEXT)
logging_unittest_OBJECTS = $(am_logging_unittest_OBJECTS)
logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(logging_unittest_CXXFLAGS) $(CXXFLAGS) \
......@@ -153,27 +147,15 @@ logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_signalhandler_unittest_OBJECTS = $(am__objects_1) \
signalhandler_unittest-signalhandler_unittest.$(OBJEXT)
signalhandler_unittest_OBJECTS = $(am_signalhandler_unittest_OBJECTS)
signalhandler_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
signalhandler_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
signalhandler_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) \
$(signalhandler_unittest_LDFLAGS) $(LDFLAGS) -o $@
am_stacktrace_framesizes_unittest_OBJECTS = $(am__objects_1) \
stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.$(OBJEXT)
stacktrace_framesizes_unittest_OBJECTS = \
$(am_stacktrace_framesizes_unittest_OBJECTS)
stacktrace_framesizes_unittest_DEPENDENCIES = libglog.la \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
stacktrace_framesizes_unittest_LINK = $(LIBTOOL) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(stacktrace_framesizes_unittest_CXXFLAGS) $(CXXFLAGS) \
$(stacktrace_framesizes_unittest_LDFLAGS) $(LDFLAGS) -o $@
am_stacktrace_unittest_OBJECTS = $(am__objects_1) \
stacktrace_unittest-stacktrace_unittest.$(OBJEXT)
stacktrace_unittest_OBJECTS = $(am_stacktrace_unittest_OBJECTS)
stacktrace_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
stacktrace_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
stacktrace_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) \
......@@ -181,8 +163,7 @@ stacktrace_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_stl_logging_unittest_OBJECTS = $(am__objects_1) \
stl_logging_unittest-stl_logging_unittest.$(OBJEXT)
stl_logging_unittest_OBJECTS = $(am_stl_logging_unittest_OBJECTS)
stl_logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
stl_logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
stl_logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(stl_logging_unittest_CXXFLAGS) $(CXXFLAGS) \
......@@ -190,12 +171,19 @@ stl_logging_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
am_symbolize_unittest_OBJECTS = $(am__objects_1) \
symbolize_unittest-symbolize_unittest.$(OBJEXT)
symbolize_unittest_OBJECTS = $(am_symbolize_unittest_OBJECTS)
symbolize_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
symbolize_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
symbolize_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) \
$(symbolize_unittest_LDFLAGS) $(LDFLAGS) -o $@
am_utilities_unittest_OBJECTS = $(am__objects_1) \
utilities_unittest-utilities_unittest.$(OBJEXT)
utilities_unittest_OBJECTS = $(am_utilities_unittest_OBJECTS)
utilities_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2)
utilities_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(utilities_unittest_CXXFLAGS) $(CXXFLAGS) \
$(utilities_unittest_LDFLAGS) $(LDFLAGS) -o $@
SCRIPTS = $(noinst_SCRIPTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
......@@ -222,16 +210,14 @@ SOURCES = $(libglog_la_SOURCES) $(demangle_unittest_SOURCES) \
$(logging_striptest0_SOURCES) $(logging_striptest10_SOURCES) \
$(logging_striptest2_SOURCES) $(logging_unittest_SOURCES) \
$(signalhandler_unittest_SOURCES) \
$(stacktrace_framesizes_unittest_SOURCES) \
$(stacktrace_unittest_SOURCES) $(stl_logging_unittest_SOURCES) \
$(symbolize_unittest_SOURCES)
$(symbolize_unittest_SOURCES) $(utilities_unittest_SOURCES)
DIST_SOURCES = $(libglog_la_SOURCES) $(demangle_unittest_SOURCES) \
$(logging_striptest0_SOURCES) $(logging_striptest10_SOURCES) \
$(logging_striptest2_SOURCES) $(logging_unittest_SOURCES) \
$(signalhandler_unittest_SOURCES) \
$(stacktrace_framesizes_unittest_SOURCES) \
$(stacktrace_unittest_SOURCES) $(stl_logging_unittest_SOURCES) \
$(symbolize_unittest_SOURCES)
$(symbolize_unittest_SOURCES) $(utilities_unittest_SOURCES)
dist_docDATA_INSTALL = $(INSTALL_DATA)
DATA = $(dist_doc_DATA)
glogincludeHEADERS_INSTALL = $(INSTALL_HEADER)
......@@ -310,6 +296,7 @@ SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
UNWIND_LIBS = @UNWIND_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
......@@ -392,6 +379,9 @@ dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
doc/designstyle.css doc/glog.html
lib_LTLIBRARIES = libglog.la
# The libraries libglog depends on.
COMMON_LIBS = $(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS)
TESTS_ENVIRONMENT =
check_SCRIPTS = logging_striplog_test_sh demangle_unittest_sh \
signalhandler_unittest_sh
......@@ -406,66 +396,66 @@ logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
logging_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_unittest_LDADD = libglog.la $(COMMON_LIBS)
logging_striptest0_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_striptest_main.cc
logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS)
logging_striptest0_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_striptest0_LDADD = libglog.la $(COMMON_LIBS)
logging_striptest2_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_striptest2.cc
logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS)
logging_striptest2_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_striptest2_LDADD = libglog.la $(COMMON_LIBS)
logging_striptest10_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging_striptest10.cc
logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS)
logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS)
logging_striptest10_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
logging_striptest10_LDADD = libglog.la $(COMMON_LIBS)
demangle_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/demangle_unittest.cc
demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
demangle_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
demangle_unittest_LDADD = libglog.la $(COMMON_LIBS)
stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/stacktrace_unittest.cc
stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
stacktrace_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS)
symbolize_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/symbolize_unittest.cc
symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
symbolize_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
stacktrace_framesizes_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/stacktrace_framesizes_unittest.cc
stacktrace_framesizes_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
stacktrace_framesizes_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
stacktrace_framesizes_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS)
stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/stl_logging_unittest.cc
stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
stl_logging_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS)
signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/signalhandler_unittest.cc
signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
signalhandler_unittest_LDADD = libglog.la $(PTHREAD_LIBS) $(GFLAGS_LIBS)
signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS)
utilities_unittest_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/utilities_unittest.cc
utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
utilities_unittest_LDADD = libglog.la $(COMMON_LIBS)
libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \
src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \
src/utilities.cc src/utilities.h \
src/demangle.cc src/demangle.h \
src/stacktrace.cc src/stacktrace.h \
src/stacktrace.h \
src/stacktrace_generic-inl.h \
src/stacktrace_libunwind-inl.h \
src/stacktrace_powerpc-inl.h \
......@@ -478,7 +468,7 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) src/config.h \
libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) -DNDEBUG
libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS)
libglog_la_LIBADD = $(PTHREAD_LIBS)
libglog_la_LIBADD = $(COMMON_LIBS)
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
$(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt
......@@ -598,9 +588,6 @@ logging_unittest$(EXEEXT): $(logging_unittest_OBJECTS) $(logging_unittest_DEPEND
signalhandler_unittest$(EXEEXT): $(signalhandler_unittest_OBJECTS) $(signalhandler_unittest_DEPENDENCIES)
@rm -f signalhandler_unittest$(EXEEXT)
$(signalhandler_unittest_LINK) $(signalhandler_unittest_OBJECTS) $(signalhandler_unittest_LDADD) $(LIBS)
stacktrace_framesizes_unittest$(EXEEXT): $(stacktrace_framesizes_unittest_OBJECTS) $(stacktrace_framesizes_unittest_DEPENDENCIES)
@rm -f stacktrace_framesizes_unittest$(EXEEXT)
$(stacktrace_framesizes_unittest_LINK) $(stacktrace_framesizes_unittest_OBJECTS) $(stacktrace_framesizes_unittest_LDADD) $(LIBS)
stacktrace_unittest$(EXEEXT): $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_DEPENDENCIES)
@rm -f stacktrace_unittest$(EXEEXT)
$(stacktrace_unittest_LINK) $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_LDADD) $(LIBS)
......@@ -610,6 +597,9 @@ stl_logging_unittest$(EXEEXT): $(stl_logging_unittest_OBJECTS) $(stl_logging_uni
symbolize_unittest$(EXEEXT): $(symbolize_unittest_OBJECTS) $(symbolize_unittest_DEPENDENCIES)
@rm -f symbolize_unittest$(EXEEXT)
$(symbolize_unittest_LINK) $(symbolize_unittest_OBJECTS) $(symbolize_unittest_LDADD) $(LIBS)
utilities_unittest$(EXEEXT): $(utilities_unittest_OBJECTS) $(utilities_unittest_DEPENDENCIES)
@rm -f utilities_unittest$(EXEEXT)
$(utilities_unittest_LINK) $(utilities_unittest_OBJECTS) $(utilities_unittest_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
......@@ -622,7 +612,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-logging.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-raw_logging.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-signalhandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-stacktrace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-symbolize.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-utilities.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglog_la-vlog_is_on.Plo@am__quote@
......@@ -631,10 +620,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging_striptest2-logging_striptest2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging_unittest-logging_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbolize_unittest-symbolize_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilities_unittest-utilities_unittest.Po@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
......@@ -692,13 +681,6 @@ libglog_la-demangle.lo: src/demangle.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o libglog_la-demangle.lo `test -f 'src/demangle.cc' || echo '$(srcdir)/'`src/demangle.cc
libglog_la-stacktrace.lo: src/stacktrace.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT libglog_la-stacktrace.lo -MD -MP -MF $(DEPDIR)/libglog_la-stacktrace.Tpo -c -o libglog_la-stacktrace.lo `test -f 'src/stacktrace.cc' || echo '$(srcdir)/'`src/stacktrace.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libglog_la-stacktrace.Tpo $(DEPDIR)/libglog_la-stacktrace.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/stacktrace.cc' object='libglog_la-stacktrace.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o libglog_la-stacktrace.lo `test -f 'src/stacktrace.cc' || echo '$(srcdir)/'`src/stacktrace.cc
libglog_la-symbolize.lo: src/symbolize.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT libglog_la-symbolize.lo -MD -MP -MF $(DEPDIR)/libglog_la-symbolize.Tpo -c -o libglog_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libglog_la-symbolize.Tpo $(DEPDIR)/libglog_la-symbolize.Plo
......@@ -797,20 +779,6 @@ signalhandler_unittest-signalhandler_unittest.obj: src/signalhandler_unittest.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o signalhandler_unittest-signalhandler_unittest.obj `if test -f 'src/signalhandler_unittest.cc'; then $(CYGPATH_W) 'src/signalhandler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/signalhandler_unittest.cc'; fi`
stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.o: src/stacktrace_framesizes_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_framesizes_unittest_CXXFLAGS) $(CXXFLAGS) -MT stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.o -MD -MP -MF $(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Tpo -c -o stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.o `test -f 'src/stacktrace_framesizes_unittest.cc' || echo '$(srcdir)/'`src/stacktrace_framesizes_unittest.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Tpo $(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/stacktrace_framesizes_unittest.cc' object='stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_framesizes_unittest_CXXFLAGS) $(CXXFLAGS) -c -o stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.o `test -f 'src/stacktrace_framesizes_unittest.cc' || echo '$(srcdir)/'`src/stacktrace_framesizes_unittest.cc
stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.obj: src/stacktrace_framesizes_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_framesizes_unittest_CXXFLAGS) $(CXXFLAGS) -MT stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.obj -MD -MP -MF $(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Tpo -c -o stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.obj `if test -f 'src/stacktrace_framesizes_unittest.cc'; then $(CYGPATH_W) 'src/stacktrace_framesizes_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/stacktrace_framesizes_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Tpo $(DEPDIR)/stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/stacktrace_framesizes_unittest.cc' object='stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_framesizes_unittest_CXXFLAGS) $(CXXFLAGS) -c -o stacktrace_framesizes_unittest-stacktrace_framesizes_unittest.obj `if test -f 'src/stacktrace_framesizes_unittest.cc'; then $(CYGPATH_W) 'src/stacktrace_framesizes_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/stacktrace_framesizes_unittest.cc'; fi`
stacktrace_unittest-stacktrace_unittest.o: src/stacktrace_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) -MT stacktrace_unittest-stacktrace_unittest.o -MD -MP -MF $(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Tpo -c -o stacktrace_unittest-stacktrace_unittest.o `test -f 'src/stacktrace_unittest.cc' || echo '$(srcdir)/'`src/stacktrace_unittest.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Tpo $(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Po
......@@ -853,6 +821,20 @@ symbolize_unittest-symbolize_unittest.obj: src/symbolize_unittest.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) -c -o symbolize_unittest-symbolize_unittest.obj `if test -f 'src/symbolize_unittest.cc'; then $(CYGPATH_W) 'src/symbolize_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/symbolize_unittest.cc'; fi`
utilities_unittest-utilities_unittest.o: src/utilities_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -MT utilities_unittest-utilities_unittest.o -MD -MP -MF $(DEPDIR)/utilities_unittest-utilities_unittest.Tpo -c -o utilities_unittest-utilities_unittest.o `test -f 'src/utilities_unittest.cc' || echo '$(srcdir)/'`src/utilities_unittest.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/utilities_unittest-utilities_unittest.Tpo $(DEPDIR)/utilities_unittest-utilities_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/utilities_unittest.cc' object='utilities_unittest-utilities_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -c -o utilities_unittest-utilities_unittest.o `test -f 'src/utilities_unittest.cc' || echo '$(srcdir)/'`src/utilities_unittest.cc
utilities_unittest-utilities_unittest.obj: src/utilities_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -MT utilities_unittest-utilities_unittest.obj -MD -MP -MF $(DEPDIR)/utilities_unittest-utilities_unittest.Tpo -c -o utilities_unittest-utilities_unittest.obj `if test -f 'src/utilities_unittest.cc'; then $(CYGPATH_W) 'src/utilities_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/utilities_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/utilities_unittest-utilities_unittest.Tpo $(DEPDIR)/utilities_unittest-utilities_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/utilities_unittest.cc' object='utilities_unittest-utilities_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -c -o utilities_unittest-utilities_unittest.obj `if test -f 'src/utilities_unittest.cc'; then $(CYGPATH_W) 'src/utilities_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/utilities_unittest.cc'; fi`
mostlyclean-libtool:
-rm -f *.lo
......
......@@ -884,6 +884,7 @@ acx_pthread_config
PTHREAD_CC
PTHREAD_LIBS
PTHREAD_CFLAGS
UNWIND_LIBS
ac_google_start_namespace
ac_google_end_namespace
ac_google_namespace
......@@ -5062,7 +5063,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 5065 "configure"' > conftest.$ac_ext
echo '#line 5066 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -7417,11 +7418,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7420: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7421: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7424: \$? = $ac_status" >&5
echo "$as_me:7425: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -7707,11 +7708,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7710: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7711: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7714: \$? = $ac_status" >&5
echo "$as_me:7715: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -7811,11 +7812,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7814: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7815: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7818: \$? = $ac_status" >&5
echo "$as_me:7819: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -10188,7 +10189,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10191 "configure"
#line 10192 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -10288,7 +10289,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10291 "configure"
#line 10292 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -12689,11 +12690,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:12692: $lt_compile\"" >&5)
(eval echo "\"\$as_me:12693: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:12696: \$? = $ac_status" >&5
echo "$as_me:12697: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -12793,11 +12794,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:12796: $lt_compile\"" >&5)
(eval echo "\"\$as_me:12797: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:12800: \$? = $ac_status" >&5
echo "$as_me:12801: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -14391,11 +14392,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14394: $lt_compile\"" >&5)
(eval echo "\"\$as_me:14395: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:14398: \$? = $ac_status" >&5
echo "$as_me:14399: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -14495,11 +14496,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14498: $lt_compile\"" >&5)
(eval echo "\"\$as_me:14499: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:14502: \$? = $ac_status" >&5
echo "$as_me:14503: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -16715,11 +16716,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16718: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16719: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:16722: \$? = $ac_status" >&5
echo "$as_me:16723: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -17005,11 +17006,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17008: $lt_compile\"" >&5)
(eval echo "\"\$as_me:17009: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:17012: \$? = $ac_status" >&5
echo "$as_me:17013: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -17109,11 +17110,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17112: $lt_compile\"" >&5)
(eval echo "\"\$as_me:17113: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:17116: \$? = $ac_status" >&5
echo "$as_me:17117: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -20680,7 +20681,6 @@ fi
done
# For backtrace with glibc.
# TODO(hamaji): Support other platforms using libgcc.
for ac_header in execinfo.h
do
......@@ -20826,6 +20826,154 @@ fi
done
# For backtrace with libunwind.
for ac_header in libunwind.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
else
# Is the header compilable?
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6; }
# Is the header present?
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6; }
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
## ------------------------------------ ##
## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
ac_cv_have_libunwind_h=1
else
ac_cv_have_libunwind_h=0
fi
done
for ac_header in ucontext.h
do
......@@ -22744,6 +22892,87 @@ else
GFLAGS_LIBS=
fi
# We want to link in libunwind if it exists
UNWIND_LIBS=
# Unfortunately, we need to check the header file in addition to the
# lib file to check if libunwind is available since libunwind-0.98
# doesn't install all necessary header files.
if test x"$ac_cv_have_libunwind_h" = x"1"; then
{ echo "$as_me:$LINENO: checking for backtrace in -lunwind" >&5
echo $ECHO_N "checking for backtrace in -lunwind... $ECHO_C" >&6; }
if test "${ac_cv_lib_unwind_backtrace+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lunwind $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char backtrace ();
int
main ()
{
return backtrace ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
ac_cv_lib_unwind_backtrace=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_unwind_backtrace=no
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_unwind_backtrace" >&5
echo "${ECHO_T}$ac_cv_lib_unwind_backtrace" >&6; }
if test $ac_cv_lib_unwind_backtrace = yes; then
UNWIND_LIBS=-lunwind
fi
fi
if test x"$UNWIND_LIBS" != x""; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_LIB_UNWIND 1
_ACEOF
fi
# We'd like to use read/write locks in several places in the code.
# See if our pthreads support extends to that. Note: for linux, it
# does as long as you define _XOPEN_SOURCE appropriately.
......@@ -24052,6 +24281,7 @@ acx_pthread_config!$acx_pthread_config$ac_delim
PTHREAD_CC!$PTHREAD_CC$ac_delim
PTHREAD_LIBS!$PTHREAD_LIBS$ac_delim
PTHREAD_CFLAGS!$PTHREAD_CFLAGS$ac_delim
UNWIND_LIBS!$UNWIND_LIBS$ac_delim
ac_google_start_namespace!$ac_google_start_namespace$ac_delim
ac_google_end_namespace!$ac_google_end_namespace$ac_delim
ac_google_namespace!$ac_google_namespace$ac_delim
......@@ -24071,7 +24301,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 35; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 36; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
......
......@@ -31,8 +31,9 @@ AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0)
AC_CHECK_HEADERS(syscall.h)
AC_CHECK_HEADERS(sys/syscall.h)
# For backtrace with glibc.
# TODO(hamaji): Support other platforms using libgcc.
AC_CHECK_HEADERS(execinfo.h)
# For backtrace with libunwind.
AC_CHECK_HEADERS(libunwind.h, ac_cv_have_libunwind_h=1, ac_cv_have_libunwind_h=0)
AC_CHECK_HEADERS(ucontext.h)
AC_CHECK_SIZEOF(void *)
......@@ -92,6 +93,19 @@ else
GFLAGS_LIBS=
fi
# We want to link in libunwind if it exists
UNWIND_LIBS=
# Unfortunately, we need to check the header file in addition to the
# lib file to check if libunwind is available since libunwind-0.98
# doesn't install all necessary header files.
if test x"$ac_cv_have_libunwind_h" = x"1"; then
AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind)
fi
AC_SUBST(UNWIND_LIBS)
if test x"$UNWIND_LIBS" != x""; then
AC_DEFINE(HAVE_LIB_UNWIND, 1, [define if you have libunwind])
fi
# We'd like to use read/write locks in several places in the code.
# See if our pthreads support extends to that. Note: for linux, it
# does as long as you define _XOPEN_SOURCE appropriately.
......
......@@ -15,9 +15,15 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <libunwind.h> header file. */
#undef HAVE_LIBUNWIND_H
/* define if you have google gflags library */
#undef HAVE_LIB_GFLAGS
/* define if you have libunwind */
#undef HAVE_LIB_UNWIND
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
......
......@@ -22,30 +22,6 @@ _START_GOOGLE_NAMESPACE_
namespace {
// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
// defined, we try the CPU specific logics (we only support x86 and
// x86_64 for now) first, then use a naive implementation, which has a
// race condition.
template<typename T>
inline T* sync_val_compare_and_swap(T** ptr, T* oldval, T* newval) {
#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
return __sync_val_compare_and_swap(ptr, oldval, newval);
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
T* ret;
__asm__ __volatile__("lock; cmpxchg %1, (%2);"
:"=a"(ret)
:"r"(newval), "r"(ptr), "a"(oldval)
:"memory", "cc");
return ret;
#else
T* ret = *ptr;
if (ret == oldval) {
*ptr = newval;
}
return ret;
#endif
}
// We'll install the failure signal handler for these signals. We could
// use strsignal() to get signal names, but we don't use it to avoid
// introducing yet another #ifdef complication.
......@@ -262,9 +238,10 @@ void FailureSignalHandler(int signal_number,
// old value (value returned from __sync_val_compare_and_swap) is
// different from the original value (in this case NULL).
pthread_t* old_thread_id_pointer =
sync_val_compare_and_swap(&g_entered_thread_id_pointer,
static_cast<pthread_t*>(NULL),
&my_thread_id);
glog_internal_namespace_::sync_val_compare_and_swap(
&g_entered_thread_id_pointer,
static_cast<pthread_t*>(NULL),
&my_thread_id);
if (old_thread_id_pointer != NULL) {
// We've already entered the signal handler. What should we do?
if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
......
......@@ -27,7 +27,7 @@ void WriteToStdout(const char* data, int size) {
}
int main(int argc, char **argv) {
#ifdef HAVE_STACKTRACE
#if defined(HAVE_STACKTRACE) && defined(HAVE_SYMBOLIZE)
InitGoogleLogging(argv[0]);
InstallFailureSignalHandler();
const std::string command = argc > 1 ? argv[1] : "none";
......
......@@ -35,6 +35,13 @@ if [ x`$BINARY` != 'xOK' ]; then
exit 0
fi
# The PC cannot be obtained in signal handlers on PowerPC correctly.
# We just skip the test for PowerPC.
if [ x`uname -p` = x"powerpc" ]; then
echo "PASS (We don't test the signal handler on PowerPC.)"
exit 0
fi
# Test for a case the program kills itself by SIGSEGV.
$BINARY segv 2> signalhandler.out1
for pattern in SIGSEGV 0xdead main "Aborted at [0-9]"; do
......
......@@ -11,40 +11,6 @@
_START_GOOGLE_NAMESPACE_
// Skips the most recent "skip_count" stack frames (also skips the
// frame generated for the "GetStackFrames" routine itself), and then
// records the pc values for up to the next "max_depth" frames in
// "pcs", and the corresponding stack frame sizes in "sizes". Returns
// the number of values recorded in "pcs"/"sizes".
//
// Example:
// main() { foo(); }
// foo() { bar(); }
// bar() {
// void* pcs[10];
// int sizes[10];
// int depth = GetStackFrames(pcs, sizes, 10, 1);
// }
//
// The GetStackFrames call will skip the frame for "bar". It will
// return 2 and will produce pc values that map to the following
// procedures:
// pcs[0] foo
// pcs[1] main
// (Actually, there may be a few more entries after "main" to account for
// startup procedures.)
// And corresponding stack frame sizes will also be recorded:
// sizes[0] 16
// sizes[1] 16
// (Stack frame sizes of 16 above are just for illustration purposes.)
// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
// be identified.
//
// This routine may return fewer stack frame entries than are
// available. Also note that "pcs" and "sizes" must both be non-NULL.
extern int GetStackFrames(void** pcs, int* sizes, int max_depth,
int skip_count);
// This is similar to the GetStackFrames routine, except that it returns
// the stack trace only, and not the stack frame sizes as well.
// Example:
......
// Copyright 2007 Google Inc. All Rights Reserved.
// Author: Raksit Ashok
//
// Unit test for the GetStackFrames function in stacktrace.cc.
#include <stdio.h>
#include "glog/logging.h"
#include "base/commandlineflags.h"
#include "stacktrace.h"
#include "config.h"
#include "utilities.h"
using std::min;
using namespace GOOGLE_NAMESPACE;
#ifdef HAVE_STACKTRACE
// Obtain a backtrace of the stack frame sizes, verify that they look sane.
//-----------------------------------------------------------------------//
int CheckFrameSizesLeaf(int32* i); // 8KB frame size.
int CheckFrameSizes2(int32* i); // 4KB
int CheckFrameSizes1(int32* i); // 2KB
int CheckFrameSizes(int32* i); // 1KB
//-----------------------------------------------------------------------//
// The expected frame-sizes in the backtrace.
const int BACKTRACE_STEPS = 4;
int expected_frame_sizes[BACKTRACE_STEPS] = {
1 << 13,
1 << 12,
1 << 11,
1 << 10,
};
//-----------------------------------------------------------------------//
void CheckFrameSizeIsOk(int actual_frame_size, int ref_frame_size) {
// Assume upto 512 bytes of miscellaneous stuff in CheckFrameSizes* frames.
const int misc_frame_size = 512;
CHECK_GE(actual_frame_size, ref_frame_size);
CHECK_LE(actual_frame_size, ref_frame_size + misc_frame_size);
}
//-----------------------------------------------------------------------//
int ATTRIBUTE_NOINLINE CheckFrameSizesLeaf(int32 *i) {
const int DEPTH = 10;
void* pcs[DEPTH];
int frame_sizes[DEPTH];
int size;
int32 j[2048]; // 8KB.
for (int k = 0; k < 2048; k++) j[k] = k + i[k % 1024];
for (int depth = 0; depth < DEPTH; depth++) {
size = GetStackFrames(pcs, frame_sizes, depth, 0);
printf("--- GetStackFrames(..., %d, 0) = %d\n", depth, size);
CHECK_LE(size, depth);
CHECK_GE(size, min(depth, BACKTRACE_STEPS));
for (int k = 0; k < size; k++) {
if (k < BACKTRACE_STEPS)
// GetStackFrames doesn't work correctly if we are using glibc's backtrace.
#ifndef HAVE_EXECINFO_H
CheckFrameSizeIsOk(frame_sizes[k], expected_frame_sizes[k]);
#endif
printf("frame_sizes[%d] = %d\n", k, frame_sizes[k]);
}
}
int sum = 0;
for (int k = 0; k < 2048; k++) sum += j[k];
return sum;
}
//-----------------------------------------------------------------------//
/* Dummy functions to make the frame-size backtrace more interesting. */
int ATTRIBUTE_NOINLINE CheckFrameSizes2(int32* i) {
int32 j[1024]; // 4KB.
for (int k = 0; k < 1024; k++) j[k] = k + i[k % 512];
return CheckFrameSizesLeaf(j) + j[512];
}
int ATTRIBUTE_NOINLINE CheckFrameSizes1(int32* i) {
int32 j[512]; // 2KB.
for (int k = 0; k < 512; k++) j[k] = k + i[k % 256];
return CheckFrameSizes2(j) + j[256];
}
int ATTRIBUTE_NOINLINE CheckFrameSizes(int32* i) {
int32 j[256]; // 1KB.
for (int k = 0; k < 256; k++) j[k] = k + i[k];
return CheckFrameSizes1(j) + j[128];
}
//-----------------------------------------------------------------------//
int main(int argc, char ** argv) {
FLAGS_logtostderr = true;
InitGoogleLogging(argv[0]);
int32 i[256]; // 1KB.
for (int j = 0; j < 256; j++) i[j] = j;
int ret = CheckFrameSizes(i);
printf("CheckFrameSizes returned: %d\n", ret);
printf("PASS\n");
return 0;
}
#else
int main() {
printf("PASS (no stacktrace support)\n");
return 0;
}
#endif // HAVE_STACKTRACE
......@@ -30,52 +30,4 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
return result_count;
}
// If you change this function, also change GetStackTrace above:
//
// This GetStackFrames routine shares a lot of code with GetStackTrace
// above. This code could have been refactored into a common routine,
// and then both GetStackTrace/GetStackFrames could call that routine.
// There are two problems with that:
//
// (1) The performance of the refactored-code suffers substantially - the
// refactored needs to be able to record the stack trace when called
// from GetStackTrace, and both the stack trace and stack frame sizes,
// when called from GetStackFrames - this introduces enough new
// conditionals that GetStackTrace performance can degrade by as much
// as 50%.
//
// (2) Whether the refactored routine gets inlined into GetStackTrace and
// GetStackFrames depends on the compiler, and we can't guarantee the
// behavior either-way, even with "__attribute__ ((always_inline))"
// or "__attribute__ ((noinline))". But we need this guarantee or the
// frame counts may be off by one.
//
// Both (1) and (2) can be addressed without this code duplication, by
// clever use of template functions, and by defining GetStackTrace and
// GetStackFrames as macros that expand to these template functions.
// However, this approach comes with its own set of problems - namely,
// macros and preprocessor trouble - for example, if GetStackTrace
// and/or GetStackFrames is ever defined as a member functions in some
// class, we are in trouble.
int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
static const int kStackLength = 64;
void * stack[kStackLength];
int size;
size = backtrace(stack, kStackLength);
skip_count++; // we want to skip the current frame as well
int result_count = size - skip_count;
if (result_count < 0)
result_count = 0;
if (result_count > max_depth)
result_count = max_depth;
for (int i = 0; i < result_count; i++)
pcs[i] = stack[i + skip_count];
// No implementation for finding out the stack frame sizes yet.
memset(sizes, 0, sizeof(*sizes) * result_count);
return result_count;
}
_END_GOOGLE_NAMESPACE_
......@@ -5,23 +5,25 @@
//
// Produce stack trace using libunwind
#include "utilities.h"
extern "C" {
#define UNW_LOCAL_ONLY
#include <libunwind.h>
}
#include "base/stacktrace.h"
#include "base/raw_logging.h"
#include "base/spinlock.h"
#include "glog/raw_logging.h"
#include "stacktrace.h"
_START_GOOGLE_NAMESPACE_
// Sometimes, we can try to get a stack trace from within a stack
// trace, because libunwind can call mmap/sbrk (maybe indirectly via
// malloc), and that mmap gets trapped and causes a stack-trace
// request. If were to try to honor that recursive request, we'd end
// up with infinite recursion or deadlock. Luckily, it's safe to
// ignore those subsequent traces. In such cases, we return 0 to
// indicate the situation.
static SpinLock libunwind_lock(SpinLock::LINKER_INITIALIZED);
// trace, because libunwind can call mmap (maybe indirectly via an
// internal mmap based memory allocator), and that mmap gets trapped
// and causes a stack-trace request. If were to try to honor that
// recursive request, we'd end up with infinite recursion or deadlock.
// Luckily, it's safe to gnore those subsequent traces. In such cases,
// we return 0 to indicate the situation.
static bool g_now_entering = false;
// If you change this function, also change GetStackFrames below.
int GetStackTrace(void** result, int max_depth, int skip_count) {
......@@ -30,7 +32,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
unw_cursor_t cursor;
unw_context_t uc;
if (!libunwind_lock.TryLock()) {
if (sync_val_compare_and_swap(&g_now_entering, false, true)) {
return 0;
}
......@@ -52,75 +54,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
break;
}
libunwind_lock.Unlock();
return n;
}
// If you change this function, also change GetStackTrace above:
//
// This GetStackFrames routine shares a lot of code with GetStackTrace
// above. This code could have been refactored into a common routine,
// and then both GetStackTrace/GetStackFrames could call that routine.
// There are two problems with that:
//
// (1) The performance of the refactored-code suffers substantially - the
// refactored needs to be able to record the stack trace when called
// from GetStackTrace, and both the stack trace and stack frame sizes,
// when called from GetStackFrames - this introduces enough new
// conditionals that GetStackTrace performance can degrade by as much
// as 50%.
//
// (2) Whether the refactored routine gets inlined into GetStackTrace and
// GetStackFrames depends on the compiler, and we can't guarantee the
// behavior either-way, even with "__attribute__ ((always_inline))"
// or "__attribute__ ((noinline))". But we need this guarantee or the
// frame counts may be off by one.
//
// Both (1) and (2) can be addressed without this code duplication, by
// clever use of template functions, and by defining GetStackTrace and
// GetStackFrames as macros that expand to these template functions.
// However, this approach comes with its own set of problems - namely,
// macros and preprocessor trouble - for example, if GetStackTrace
// and/or GetStackFrames is ever defined as a member functions in some
// class, we are in trouble.
int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
void *ip;
int n = 0;
unw_cursor_t cursor;
unw_context_t uc;
unw_word_t sp = 0, next_sp = 0;
if (!libunwind_lock.TryLock()) {
return 0;
}
unw_getcontext(&uc);
RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
skip_count++; // Do not include the "GetStackFrames" frame
while (skip_count--) {
if (unw_step(&cursor) <= 0 ||
unw_get_reg(&cursor, UNW_REG_SP, &next_sp) < 0) {
goto out;
}
}
while (n < max_depth) {
sp = next_sp;
if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0)
break;
if (unw_step(&cursor) <= 0 ||
unw_get_reg(&cursor, UNW_REG_SP, &next_sp)) {
// We couldn't step any further (possibly because we reached _start).
// Provide the last good PC we've got, and get out.
sizes[n] = 0;
pcs[n++] = ip;
break;
}
sizes[n] = next_sp - sp;
pcs[n++] = ip;
}
out:
libunwind_lock.Unlock();
g_now_entering = false;
return n;
}
......
......@@ -101,82 +101,4 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
return n;
}
// If you change this function, also change GetStackTrace above:
//
// This GetStackFrames routine shares a lot of code with GetStackTrace
// above. This code could have been refactored into a common routine,
// and then both GetStackTrace/GetStackFrames could call that routine.
// There are two problems with that:
//
// (1) The performance of the refactored-code suffers substantially - the
// refactored needs to be able to record the stack trace when called
// from GetStackTrace, and both the stack trace and stack frame sizes,
// when called from GetStackFrames - this introduces enough new
// conditionals that GetStackTrace performance can degrade by as much
// as 50%.
//
// (2) Whether the refactored routine gets inlined into GetStackTrace and
// GetStackFrames depends on the compiler, and we can't guarantee the
// behavior either-way, even with "__attribute__ ((always_inline))"
// or "__attribute__ ((noinline))". But we need this guarantee or the
// frame counts may be off by one.
//
// Both (1) and (2) can be addressed without this code duplication, by
// clever use of template functions, and by defining GetStackTrace and
// GetStackFrames as macros that expand to these template functions.
// However, this approach comes with its own set of problems - namely,
// macros and preprocessor trouble - for example, if GetStackTrace
// and/or GetStackFrames is ever defined as a member functions in some
// class, we are in trouble.
int GetStackFrames(void** pcs, int *sizes, int max_depth, int skip_count) {
void **sp;
#ifdef __APPLE__
__asm__ volatile ("mr %0,r1" : "=r" (sp));
#else
__asm__ volatile ("mr %0,1" : "=r" (sp));
#endif
StacktracePowerPCDummyFunction();
// Note we do *not* increment skip_count here for the SYSV ABI. If
// we did, the list of stack frames wouldn't properly match up with
// the list of return addresses. Note this means the top pc entry
// is probably bogus for linux/ppc (and other SYSV-ABI systems).
int n = 0;
while (sp && n < max_depth) {
// The GetStackFrames routine is called when we are in some
// informational context (the failure signal handler for example).
// Use the non-strict unwinding rules to produce a stack trace
// that is as complete as possible (even if it contains a few bogus
// entries in some rare cases).
void **next_sp = NextStackFrame<false>(sp);
if (skip_count > 0) {
skip_count--;
} else {
#if defined(_CALL_AIX) || defined(_CALL_DARWIN)
pcs[n++] = *(sp+2);
#elif defined(_CALL_SYSV)
pcs[n++] = *(sp+1);
#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))
// This check is in case the compiler doesn't define _CALL_AIX/etc.
pcs[n++] = *(sp+2);
#elif defined(__linux)
// This check is in case the compiler doesn't define _CALL_SYSV.
pcs[n++] = *(sp+1);
#else
#error Need to specify the PPC ABI for your archiecture.
#endif
if (next_sp > sp) {
sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
} else {
// A frame-size of 0 is used to indicate unknown frame size.
sizes[n] = 0;
}
n++;
}
sp = next_sp;
}
return n;
}
_END_GOOGLE_NAMESPACE_
......@@ -93,6 +93,9 @@ void CheckStackTraceLeaf(void) {
CheckRetAddrIsInFunction(stack[i], expected_stack[i]);
printf("OK\n");
}
// Check if the second stacktrace returns the same size.
CHECK_EQ(size, GetStackTrace(stack, STACK_LEN, 0));
}
//-----------------------------------------------------------------------//
......
......@@ -110,88 +110,4 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
return n;
}
// If you change this function, also change GetStackTrace above:
//
// This GetStackFrames routine shares a lot of code with GetStackTrace
// above. This code could have been refactored into a common routine,
// and then both GetStackTrace/GetStackFrames could call that routine.
// There are two problems with that:
//
// (1) The performance of the refactored-code suffers substantially - the
// refactored needs to be able to record the stack trace when called
// from GetStackTrace, and both the stack trace and stack frame sizes,
// when called from GetStackFrames - this introduces enough new
// conditionals that GetStackTrace performance can degrade by as much
// as 50%.
//
// (2) Whether the refactored routine gets inlined into GetStackTrace and
// GetStackFrames depends on the compiler, and we can't guarantee the
// behavior either-way, even with "__attribute__ ((always_inline))"
// or "__attribute__ ((noinline))". But we need this guarantee or the
// frame counts may be off by one.
//
// Both (1) and (2) can be addressed without this code duplication, by
// clever use of template functions, and by defining GetStackTrace and
// GetStackFrames as macros that expand to these template functions.
// However, this approach comes with its own set of problems - namely,
// macros and preprocessor trouble - for example, if GetStackTrace
// and/or GetStackFrames is ever defined as a member functions in some
// class, we are in trouble.
int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
void **sp;
#ifdef __i386__
// Stack frame format:
// sp[0] pointer to previous frame
// sp[1] caller address
// sp[2] first argument
// ...
sp = (void **)&pcs - 2;
#endif
#ifdef __x86_64__
// __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8
unsigned long rbp;
// Move the value of the register %rbp into the local variable rbp.
// We need 'volatile' to prevent this instruction from getting moved
// around during optimization to before function prologue is done.
// An alternative way to achieve this
// would be (before this __asm__ instruction) to call Noop() defined as
// static void Noop() __attribute__ ((noinline)); // prevent inlining
// static void Noop() { asm(""); } // prevent optimizing-away
__asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
// Arguments are passed in registers on x86-64, so we can't just
// offset from &pcs
sp = (void **) rbp;
#endif
int n = 0;
while (sp && n < max_depth) {
if (*(sp+1) == (void *)0) {
// In 64-bit code, we often see a frame that
// points to itself and has a return address of 0.
break;
}
// The GetStackFrames routine is called when we are in some
// informational context (the failure signal handler for example).
// Use the non-strict unwinding rules to produce a stack trace
// that is as complete as possible (even if it contains a few bogus
// entries in some rare cases).
void **next_sp = NextStackFrame<false>(sp);
if (skip_count > 0) {
skip_count--;
} else {
pcs[n] = *(sp+1);
if (next_sp > sp) {
sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
} else {
// A frame-size of 0 is used to indicate unknown frame size.
sizes[n] = 0;
}
n++;
}
sp = next_sp;
}
return n;
}
_END_GOOGLE_NAMESPACE_
......@@ -76,52 +76,4 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
return targ.count;
}
// If you change this function, also change GetStackTrace above:
//
// This GetStackFrames routine shares a lot of code with GetStackTrace
// above. This code could have been refactored into a common routine,
// and then both GetStackTrace/GetStackFrames could call that routine.
// There are two problems with that:
//
// (1) The performance of the refactored-code suffers substantially - the
// refactored needs to be able to record the stack trace when called
// from GetStackTrace, and both the stack trace and stack frame sizes,
// when called from GetStackFrames - this introduces enough new
// conditionals that GetStackTrace performance can degrade by as much
// as 50%.
//
// (2) Whether the refactored routine gets inlined into GetStackTrace and
// GetStackFrames depends on the compiler, and we can't guarantee the
// behavior either-way, even with "__attribute__ ((always_inline))"
// or "__attribute__ ((noinline))". But we need this guarantee or the
// frame counts may be off by one.
//
// Both (1) and (2) can be addressed without this code duplication, by
// clever use of template functions, and by defining GetStackTrace and
// GetStackFrames as macros that expand to these template functions.
// However, this approach comes with its own set of problems - namely,
// macros and preprocessor trouble - for example, if GetStackTrace
// and/or GetStackFrames is ever defined as a member functions in some
// class, we are in trouble.
int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
if (!ready_to_run)
return 0;
trace_arg_t targ;
skip_count += 1; // Do not include the "GetStackFrames" frame
targ.result = pcs;
targ.max_depth = max_depth;
targ.skip_count = skip_count;
targ.count = 0;
_Unwind_Backtrace(GetOneFrame, &targ);
// No implementation for finding out the stack frame sizes yet.
memset(sizes, 0, sizeof(*sizes) * targ.count);
return targ.count;
}
_END_GOOGLE_NAMESPACE_
......@@ -3,6 +3,8 @@
//
// Unit tests for functions in symbolize.cc.
#include "utilities.h"
#include <signal.h>
#include <iostream>
......@@ -10,7 +12,6 @@
#include "symbolize.h"
#include "googletest.h"
#include "config.h"
#include "utilities.h"
using namespace std;
using namespace GOOGLE_NAMESPACE;
......@@ -307,19 +308,17 @@ void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
int main(int argc, char **argv) {
FLAGS_logtostderr = true;
InitGoogleLogging(argv[0]);
#ifdef HAVE_SYMBOLIZE
// We don't want to get affected by the callback interface, that may be
// used to install some callback function at InitGoogle() time.
InstallSymbolizeCallback(NULL);
// Symbolize() now only supports ELF binaries.
// The test makes sense only if __ELF__ is defined.
#ifndef __ELF__
return 0;
#else
TestWithPCInsideInlineFunction();
TestWithPCInsideNonInlineFunction();
TestWithReturnAddress();
return RUN_ALL_TESTS();
#else
return 0;
#endif
}
......
// Copyright 2008 Google Inc. All Rights Reserved.
// Author: hamaji@google.com (Shinichiro Hamaji)
#include "utilities.h"
#include <signal.h>
......@@ -105,7 +108,8 @@ static void DumpStackTraceAndExit() {
abort();
}
#endif
#endif // HAVE_STACKTRACE
namespace glog_internal_namespace_ {
......@@ -179,3 +183,8 @@ void InitGoogleLogging(const char* argv0) {
}
_END_GOOGLE_NAMESPACE_
// Make an implementation of stacktrace compiled.
#ifdef STACKTRACE_H
# include STACKTRACE_H
#endif
// Copyright 2008 Google Inc. All Rights Reserved.
// Author: hamaji@google.com (Shinichiro Hamaji)
//
// Define utilties for glog internal usage.
#ifndef UTILITIES_H__
......@@ -40,13 +43,48 @@
#include "config.h"
#include "glog/logging.h"
#if defined(HAVE_EXECINFO_H)
# define HAVE_STACKTRACE
#elif defined(STACKTRACE_WITH_FRAME_POINTER)
// There are three different ways we can try to get the stack trace:
//
// 1) The libunwind library. This is still in development, and as a
// separate library adds a new dependency, but doesn't need a frame
// pointer. It also doesn't call malloc.
//
// 2) Our hand-coded stack-unwinder. This depends on a certain stack
// layout, which is used by gcc (and those systems using a
// gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
// It uses the frame pointer to do its work.
//
// 3) The gdb unwinder -- also the one used by the c++ exception code.
// It's obviously well-tested, but has a fatal flaw: it can call
// malloc() from the unwinder. This is a problem because we're
// trying to use the unwinder to instrument malloc().
//
// Note: if you add a new implementation here, make sure it works
// correctly when GetStackTrace() is called with max_depth == 0.
// Some code may do that.
#if defined(HAVE_LIB_UNWIND)
# define STACKTRACE_H "stacktrace_libunwind-inl.h"
#elif !defined(NO_FRAME_POINTER)
# if defined(__i386__) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_x86-inl.h"
# elif defined(__x86_64__) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_x86_64-inl.h"
# elif ((__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_powerpc-inl.h"
# endif
#endif
#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H)
# define STACKTRACE_H "stacktrace_generic-inl.h"
#endif
#if defined(STACKTRACE_H)
# define HAVE_STACKTRACE
#endif
#if defined(__ELF__) // defined by gcc on Linux
// defined by gcc
#if defined(__ELF__) && defined(OS_LINUX)
# define HAVE_SYMBOLIZE
#elif defined(OS_MACOSX) && defined(HAVE_DLADDR)
// Use dladdr to symbolize.
......@@ -78,7 +116,36 @@ int32 GetMainThreadPid();
const std::string& MyUserName();
// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
// defined, we try the CPU specific logics (we only support x86 and
// x86_64 for now) first, then use a naive implementation, which has a
// race condition.
template<typename T>
inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
return __sync_val_compare_and_swap(ptr, oldval, newval);
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
T ret;
__asm__ __volatile__("lock; cmpxchg %1, (%2);"
:"=a"(ret)
// GCC may produces %sil or %dil for
// constraint "r", but some of apple's gas
// dosn't know the 8 bit registers.
// We use "q" to avoid these registers.
:"q"(newval), "q"(ptr), "a"(oldval)
:"memory", "cc");
return ret;
#else
T ret = *ptr;
if (ret == oldval) {
*ptr = newval;
}
return ret;
#endif
}
} // namespace glog_internal_namespace_
_END_GOOGLE_NAMESPACE_
using namespace GOOGLE_NAMESPACE::glog_internal_namespace_;
......
// Copyright 2008 Google Inc. All Rights Reserved.
// Author: hamaji@google.com (Shinichiro Hamaji)
#include "utilities.h"
#include "googletest.h"
#include "glog/logging.h"
using namespace GOOGLE_NAMESPACE;
TEST(sync_val_compare_and_swap, utilities) {
bool now_entering = false;
EXPECT_FALSE(sync_val_compare_and_swap(&now_entering, false, true));
EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true));
EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true));
}
int main(int argc, char **argv) {
InitGoogleLogging(argv[0]);
CHECK_EQ(RUN_ALL_TESTS(), 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment