summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcsilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2011-02-05 00:19:37 +0000
committercsilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2011-02-05 00:19:37 +0000
commit7375b4f3cb3ab4471d0016017be5e18ba5451c5f (patch)
tree78fdfa7a26eb797f4321503e4cc291f9cb652d0b
parent3d77cbf7d569a7c7f0ce39a83f6c98da1718f1c4 (diff)
downloadgperftools-7375b4f3cb3ab4471d0016017be5e18ba5451c5f.tar.gz
Fri Feb 04 15:54:31 2011 Google Inc. <opensource@google.com>
* google-perftools: version 1.7 release * Reduce page map key size under x86_64 by 4.4MB (rus) * Remove a flaky malloc-extension test (fdabek) * Improve the performance of PageHeap::New (ond..., csilvers) * Improve sampling_test with no-inline additions/etc (fdabek) * 16-byte align debug allocs (jyasskin) * Change FillProcSelfMaps to detect out-of-buffer-space (csilvers) * Document the need for sampling to use GetHeapSample (csilvers) * Try to read TSC frequency from tsc_freq_khs (adurbin) * Do better at figuring out if tests are running under gdb (ppluzhnikov) * Improve spinlock contention performance (ruemmler) * Better internal-function list for pprof's /contention (ruemmler) * Speed up GoogleOnce (m3b) * Limit number of incoming/outgoing edges in pprof (sanjay) * Add pprof --evince to go along with --gv (csilvers) * Document the various ways to get heap-profiling information (csilvers) * Separate out synchronization profiling routines (ruemmler) * Improve malloc-stats output to be more understandable (csilvers) * Add support for census profiler in pporf (nabeelmian) * Document how pprof's /symbol must support GET requests (csilvers) * Improve acx_pthread.m4 (ssuomi, liujisi) * Speed up pprof's ExtractSymbols (csilvers) * Ignore some known-leaky (java) libraries in the heap checker (davidyu) * Make kHideMask use all 64 bits in tests (ppluzhnikov) * Clean up pprof input-file handling (csilvers) * BUGFIX: Don't crash if __environ is NULL (csilvers) * BUGFIX: Fix totally broken debugallocation tests (csilvers) * BUGFIX: Fix up fake_VDSO handling for unittest (ppluzhnikov) * BUGFIX: Suppress all large allocs when report threshold is 0 (lexie) * BUGFIX: mmap2 on i386 takes an off_t, not off64_t (csilvers) * PORTING: Add missing PERFTOOLS_DLL_DECL (csilvers) * PORTING: Add stddef.h to make newer gcc's happy (csilvers) * PORTING: Document some tricks for working under OS X (csilvers) * PORTING: Don't try to check valgrind for windows (csilvers) * PORTING: Make array-size a var to compile under clang (chandlerc) * PORTING: No longer hook _aligned_malloc and _aligned_free (csilvers) * PORTING: Quiet some gcc warnings (csilvers) * PORTING: Replace %PRIxPTR with %p to be more portable (csilvers) * PORTING: Support systems that capitalize /proc weirdly (sanek) * PORTING: Treat arm3 the same as arm5t in cycletimer (csilvers) * PORTING: Update windows logging to not allocate memory (csilvers) * PORTING: avoid double-patching newer windows DLLs (roger.orr) * PORTING: get dynamic_annotations.c to work on windows (csilvers) * Add pkg-config .pc files for the 5 libraries we produce (csilvers) * Added proper libtool versioning, so this lib will be 0.1.0 (csilvers) * Moved from autoconf 2.64 to 2.65 git-svn-id: http://gperftools.googlecode.com/svn/trunk@102 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
-rw-r--r--ChangeLog51
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in4
-rw-r--r--NEWS33
-rw-r--r--README2
-rwxr-xr-xconfigure137
-rw-r--r--configure.ac8
-rw-r--r--m4/acx_pthread.m434
-rw-r--r--packages/deb/changelog6
-rw-r--r--src/base/cycleclock.h39
-rw-r--r--src/base/dynamic_annotations.c1
-rw-r--r--src/base/logging.h1
-rw-r--r--src/base/stl_allocator.h1
-rw-r--r--src/base/vdso_support.cc1
-rw-r--r--src/debugallocation.cc26
-rw-r--r--src/heap-checker.cc62
-rw-r--r--src/page_heap.cc20
-rw-r--r--src/page_heap.h2
-rwxr-xr-xsrc/pprof59
-rw-r--r--src/symbolize.h1
-rw-r--r--src/system-alloc.cc1
-rw-r--r--src/tests/debugallocation_test.cc18
-rwxr-xr-xsrc/tests/debugallocation_test.sh33
-rw-r--r--src/tests/malloc_extension_test.cc24
-rw-r--r--src/windows/port.h5
25 files changed, 390 insertions, 181 deletions
diff --git a/ChangeLog b/ChangeLog
index 8cb20e1..ee43193 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,53 @@
-Thu Aug 5 12:48:03 PDT 2010
+Fri Feb 04 15:54:31 2011 Google Inc. <opensource@google.com>
+
+ * google-perftools: version 1.7 release
+ * Reduce page map key size under x86_64 by 4.4MB (rus)
+ * Remove a flaky malloc-extension test (fdabek)
+ * Improve the performance of PageHeap::New (ond..., csilvers)
+ * Improve sampling_test with no-inline additions/etc (fdabek)
+ * 16-byte align debug allocs (jyasskin)
+ * Change FillProcSelfMaps to detect out-of-buffer-space (csilvers)
+ * Document the need for sampling to use GetHeapSample (csilvers)
+ * Try to read TSC frequency from tsc_freq_khs (adurbin)
+ * Do better at figuring out if tests are running under gdb (ppluzhnikov)
+ * Improve spinlock contention performance (ruemmler)
+ * Better internal-function list for pprof's /contention (ruemmler)
+ * Speed up GoogleOnce (m3b)
+ * Limit number of incoming/outgoing edges in pprof (sanjay)
+ * Add pprof --evince to go along with --gv (csilvers)
+ * Document the various ways to get heap-profiling information (csilvers)
+ * Separate out synchronization profiling routines (ruemmler)
+ * Improve malloc-stats output to be more understandable (csilvers)
+ * Add support for census profiler in pporf (nabeelmian)
+ * Document how pprof's /symbol must support GET requests (csilvers)
+ * Improve acx_pthread.m4 (ssuomi, liujisi)
+ * Speed up pprof's ExtractSymbols (csilvers)
+ * Ignore some known-leaky (java) libraries in the heap checker (davidyu)
+ * Make kHideMask use all 64 bits in tests (ppluzhnikov)
+ * Clean up pprof input-file handling (csilvers)
+ * BUGFIX: Don't crash if __environ is NULL (csilvers)
+ * BUGFIX: Fix totally broken debugallocation tests (csilvers)
+ * BUGFIX: Fix up fake_VDSO handling for unittest (ppluzhnikov)
+ * BUGFIX: Suppress all large allocs when report threshold is 0 (lexie)
+ * BUGFIX: mmap2 on i386 takes an off_t, not off64_t (csilvers)
+ * PORTING: Add missing PERFTOOLS_DLL_DECL (csilvers)
+ * PORTING: Add stddef.h to make newer gcc's happy (csilvers)
+ * PORTING: Document some tricks for working under OS X (csilvers)
+ * PORTING: Don't try to check valgrind for windows (csilvers)
+ * PORTING: Make array-size a var to compile under clang (chandlerc)
+ * PORTING: No longer hook _aligned_malloc and _aligned_free (csilvers)
+ * PORTING: Quiet some gcc warnings (csilvers)
+ * PORTING: Replace %PRIxPTR with %p to be more portable (csilvers)
+ * PORTING: Support systems that capitalize /proc weirdly (sanek)
+ * PORTING: Treat arm3 the same as arm5t in cycletimer (csilvers)
+ * PORTING: Update windows logging to not allocate memory (csilvers)
+ * PORTING: avoid double-patching newer windows DLLs (roger.orr)
+ * PORTING: get dynamic_annotations.c to work on windows (csilvers)
+ * Add pkg-config .pc files for the 5 libraries we produce (csilvers)
+ * Added proper libtool versioning, so this lib will be 0.1.0 (csilvers)
+ * Moved from autoconf 2.64 to 2.65
+
+Thu Aug 5 12:48:03 PDT 2010 Google Inc. <opensource@google.com>
* google-perftools: version 1.6 release
* Add tc_malloc_usable_size for compatibility with glibc (csilvers)
diff --git a/Makefile.am b/Makefile.am
index 2ac1445..e18e9ae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -729,7 +729,7 @@ noinst_PROGRAMS += debugallocation_test
debugallocation_test_SOURCES = src/tests/debugallocation_test.cc
debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
debugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-debugallocation_test_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
+debugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
endif WITH_DEBUGALLOC
diff --git a/Makefile.in b/Makefile.in
index 2a929c6..693230b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -790,7 +790,7 @@ am__debugallocation_test_SOURCES_DIST = \
@WITH_DEBUGALLOC_TRUE@am_debugallocation_test_OBJECTS = debugallocation_test-debugallocation_test.$(OBJEXT)
debugallocation_test_OBJECTS = $(am_debugallocation_test_OBJECTS)
@WITH_DEBUGALLOC_TRUE@debugallocation_test_DEPENDENCIES = \
-@WITH_DEBUGALLOC_TRUE@ libtcmalloc_minimal_debug.la \
+@WITH_DEBUGALLOC_TRUE@ libtcmalloc_debug.la \
@WITH_DEBUGALLOC_TRUE@ $(am__DEPENDENCIES_1)
am__debugallocation_test_sh_SOURCES_DIST = \
src/tests/debugallocation_test.sh
@@ -2135,7 +2135,7 @@ thread_dealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@WITH_DEBUGALLOC_TRUE@debugallocation_test_SOURCES = src/tests/debugallocation_test.cc
@WITH_DEBUGALLOC_TRUE@debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
@WITH_DEBUGALLOC_TRUE@debugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-@WITH_DEBUGALLOC_TRUE@debugallocation_test_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
+@WITH_DEBUGALLOC_TRUE@debugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)
diff --git a/NEWS b/NEWS
index ebc1049..741e1f8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,35 @@
+== 04 February 2011 ==
+
+I've just released perftools 1.7
+
+I apologize for the delay since the last release; so many great new
+patches and bugfixes kept coming in (and are still coming in; I also
+apologize to those folks who have to slip until the next release). I
+picked this arbitrary time to make a cut.
+
+Among the many new features in this release is a multi-megabyte
+reduction in the amount of tcmalloc overhead uder x86_64, improved
+performance in the case of contention, and many many bugfixes,
+especially architecture-specific bugfixes. See the
+[http://google-perftools.googlecode.com/svn/tags/perftools-1.7/ChangeLog ChangeLog]
+for full details.
+
+One architecture-specific change of note is added comments in the
+[http://google-perftools.googlecode.com/svn/tags/perftools-1.7/README README]
+for using tcmalloc under OS X. I'm trying to get my head around the
+exact behavior of the OS X linker, and hope to have more improvements
+for the next release, but I hope these notes help folks who have been
+having trouble with tcmalloc on OS X.
+
+*Windows users*: I've heard reports that some unittests fail on
+Windows when compiled with MSVC 10 in Release mode. All tests pass in
+Debug mode. I've not heard of any problems with earlier versions of
+MSVC. I don't know if this is a problem with the runtime patching (so
+the static patching discussed in README_windows.txt will still work),
+a problem with perftools more generally, or a bug in MSVC 10. Anyone
+with windows expertise that can debug this, I'd be glad to hear from!
+
+
=== 5 August 2010 ===
I've just released perftools 1.6
@@ -37,6 +69,7 @@ mimic the windows function of the same name. Full details are in the
[http://google-perftools.googlecode.com/svn/tags/perftools-1.5/ChangeLog
ChangeLog].
+
=== 11 September 2009 ===
I've just released perftools 1.4
diff --git a/README b/README
index 4b2b2ab..8ec6788 100644
--- a/README
+++ b/README
@@ -276,4 +276,4 @@ new threads, or is otherwise likely to cause a call to
pthread_mutex_lock!
---
-22 May 2009
+11 January 2011
diff --git a/configure b/configure
index b91c4ca..0a54ed7 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for google-perftools 1.6.
+# Generated by GNU Autoconf 2.65 for google-perftools 1.7.
#
# Report bugs to <opensource@google.com>.
#
@@ -701,8 +701,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='google-perftools'
PACKAGE_TARNAME='google-perftools'
-PACKAGE_VERSION='1.6'
-PACKAGE_STRING='google-perftools 1.6'
+PACKAGE_VERSION='1.7'
+PACKAGE_STRING='google-perftools 1.7'
PACKAGE_BUGREPORT='opensource@google.com'
PACKAGE_URL=''
@@ -1468,7 +1468,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures google-perftools 1.6 to adapt to many kinds of systems.
+\`configure' configures google-perftools 1.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1539,7 +1539,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of google-perftools 1.6:";;
+ short | recursive ) echo "Configuration of google-perftools 1.7:";;
esac
cat <<\_ACEOF
@@ -1649,7 +1649,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-google-perftools configure 1.6
+google-perftools configure 1.7
generated by GNU Autoconf 2.65
Copyright (C) 2009 Free Software Foundation, Inc.
@@ -2234,7 +2234,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by google-perftools $as_me 1.6, which was
+It was created by google-perftools $as_me 1.7, which was
generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
@@ -2584,8 +2584,10 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-TCMALLOC_SO_VERSION=0:1:0
-PROFILER_SO_VERSION=0:1:0
+# Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+TCMALLOC_SO_VERSION=1:0:1
+PROFILER_SO_VERSION=1:0:1
@@ -2977,7 +2979,7 @@ fi
# Define the identity of the package.
PACKAGE='google-perftools'
- VERSION='1.6'
+ VERSION='1.7'
cat >>confdefs.h <<_ACEOF
@@ -5579,13 +5581,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:5582: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:5584: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:5585: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:5587: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:5588: output\"" >&5)
+ (eval echo "\"\$as_me:5590: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -6791,7 +6793,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6794 "configure"' > conftest.$ac_ext
+ echo '#line 6796 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -8664,11 +8666,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:8667: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8669: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8671: \$? = $ac_status" >&5
+ echo "$as_me:8673: \$? = $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.
@@ -9003,11 +9005,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:9006: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:9008: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:9010: \$? = $ac_status" >&5
+ echo "$as_me:9012: \$? = $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.
@@ -9108,11 +9110,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:9111: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:9113: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:9115: \$? = $ac_status" >&5
+ echo "$as_me:9117: \$? = $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
@@ -9163,11 +9165,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:9166: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:9168: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:9170: \$? = $ac_status" >&5
+ echo "$as_me:9172: \$? = $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
@@ -11547,7 +11549,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11550 "configure"
+#line 11552 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11643,7 +11645,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11646 "configure"
+#line 11648 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13599,11 +13601,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:13602: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13604: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13606: \$? = $ac_status" >&5
+ echo "$as_me:13608: \$? = $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.
@@ -13698,11 +13700,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:13701: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13703: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13705: \$? = $ac_status" >&5
+ echo "$as_me:13707: \$? = $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
@@ -13750,11 +13752,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:13753: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13755: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13757: \$? = $ac_status" >&5
+ echo "$as_me:13759: \$? = $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
@@ -16628,6 +16630,77 @@ $as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shar
acx_pthread_ok=no
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether what we have so far is sufficient with -nostdlib" >&5
+$as_echo_n "checking whether what we have so far is sufficient with -nostdlib... " >&6; }
+ CFLAGS="-nostdlib $CFLAGS"
+ # we need c with nostdlib
+ LIBS="$LIBS -lc"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ done=yes
+else
+ done=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread saves the day" >&5
+$as_echo_n "checking whether -lpthread saves the day... " >&6; }
+ LIBS="-lpthread $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ done=yes
+else
+ done=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&2;}
+ fi
+ fi
+
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
@@ -17498,7 +17571,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by google-perftools $as_me 1.6, which was
+This file was extended by google-perftools $as_me 1.7, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -17564,7 +17637,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-google-perftools config.status 1.6
+google-perftools config.status 1.7
configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index b74cda8..43ae558 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,9 +4,11 @@
# make sure we're interpreted by some minimal autoconf
AC_PREREQ(2.57)
-AC_INIT(google-perftools, 1.6, opensource@google.com)
-TCMALLOC_SO_VERSION=0:1:0
-PROFILER_SO_VERSION=0:1:0
+AC_INIT(google-perftools, 1.7, opensource@google.com)
+# Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+TCMALLOC_SO_VERSION=1:0:1
+PROFILER_SO_VERSION=1:0:1
AC_SUBST(TCMALLOC_SO_VERSION)
AC_SUBST(PROFILER_SO_VERSION)
diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4
index 2cf20de..89d42c7 100644
--- a/m4/acx_pthread.m4
+++ b/m4/acx_pthread.m4
@@ -340,6 +340,40 @@ if test "x$acx_pthread_ok" = xyes; then
acx_pthread_ok=no
fi
+ AC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib])
+ CFLAGS="-nostdlib $CFLAGS"
+ # we need c with nostdlib
+ LIBS="$LIBS -lc"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes],[done=no])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether -lpthread saves the day])
+ LIBS="-lpthread $LIBS"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes],[done=no])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib])
+ fi
+ fi
+
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
diff --git a/packages/deb/changelog b/packages/deb/changelog
index 579ebf0..e9fd548 100644
--- a/packages/deb/changelog
+++ b/packages/deb/changelog
@@ -1,3 +1,9 @@
+google-perftools (1.7-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Fri, 04 Feb 2011 15:54:31 -0800
+
google-perftools (1.6-1) unstable; urgency=low
* New upstream release.
diff --git a/src/base/cycleclock.h b/src/base/cycleclock.h
index b114170..02cddf3 100644
--- a/src/base/cycleclock.h
+++ b/src/base/cycleclock.h
@@ -47,29 +47,29 @@
#include "base/basictypes.h" // make sure we get the def for int64
#if defined(__MACH__) && defined(__APPLE__)
-#include <mach/mach_time.h>
-#elif defined(__ARM_ARCH_5T__)
-#include <sys/time.h>
+# include <mach/mach_time.h>
+#elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_3__)
+# include <sys/time.h>
#endif
// NOTE: only i386 and x86_64 have been well tested.
// PPC, sparc, alpha, and ia64 are based on
// http://peter.kuscsik.com/wordpress/?p=14
-// with modifications by m3b. cf
+// with modifications by m3b. See also
// https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h
struct CycleClock {
// This should return the number of cycles since power-on. Thread-safe.
static inline int64 Now() {
#if defined(__MACH__) && defined(__APPLE__)
- // this goes at the top because we need ALL Macs, regardless
- // of architecture, to return the number of "mach time units"
- // that have passes since startup. See sysinfo.cc where
- // InitializeSystemInfo() sets the supposed cpu clock frequency of macs
- // to the number of mach time units per second, not actual
+ // this goes at the top because we need ALL Macs, regardless of
+ // architecture, to return the number of "mach time units" that
+ // have passed since startup. See sysinfo.cc where
+ // InitializeSystemInfo() sets the supposed cpu clock frequency of
+ // macs to the number of mach time units per second, not actual
// CPU clock frequency (which can change in the face of CPU
- // frequency scaling). also note that when the Mac sleeps,
- // this counter pauses; it does not continue counting, nor resets
- // to zero.
+ // frequency scaling). Also note that when the Mac sleeps, this
+ // counter pauses; it does not continue counting, nor does it
+ // reset to zero.
return mach_absolute_time();
#elif defined(__i386__)
int64 ret;
@@ -88,10 +88,6 @@ struct CycleClock {
tbl &= -static_cast<int64>(tbu0 == tbu1);
// high 32 bits in tbu1; low 32 bits in tbl (tbu0 is garbage)
return (tbu1 << 32) | tbl;
-#elif defined(__ARM_ARCH_5T__)
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return static_cast<uint64>(tv.tv_sec) * 1000000 + tv.tv_usec;
#elif defined(__sparc__)
int64 tick;
asm(".byte 0x83, 0x41, 0x00, 0x00");
@@ -103,6 +99,17 @@ struct CycleClock {
return itc;
#elif defined(_MSC_VER) && defined(_M_IX86)
_asm rdtsc
+
+// If none of the above cases trigger, we use a solution based on
+// a system call (gettimeofday or similar). We do these in order
+// from fastest to slowest. We do not have an '#else' catch-all
+// case here that just calls gettimeofday(); that system call is
+// slow, and this function is expected to be fast, so we don't want
+// to use it without an explicit decision that it's the only way.
+#elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_3__)
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return static_cast<uint64>(tv.tv_sec) * 1000000 + tv.tv_usec;
#else
// We could define __alpha here as well, but it only has a 32-bit
// timer (good for like 4 seconds), which isn't very useful.
diff --git a/src/base/dynamic_annotations.c b/src/base/dynamic_annotations.c
index 0746540..1005f90 100644
--- a/src/base/dynamic_annotations.c
+++ b/src/base/dynamic_annotations.c
@@ -35,6 +35,7 @@
# error "This file should be built as pure C to avoid name mangling"
#endif
+#include "config.h"
#include <stdlib.h>
#include <string.h>
diff --git a/src/base/logging.h b/src/base/logging.h
index fe25acf..5c3e546 100644
--- a/src/base/logging.h
+++ b/src/base/logging.h
@@ -233,6 +233,7 @@ inline void LOG_IF(int lvl, bool cond, const char* pat, ...) {
// Like other "raw" routines, these functions are best effort, and
// thus don't return error codes (except RawOpenForWriting()).
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
+#define NOMINMAX // @#!$& windows
#include <windows.h>
typedef HANDLE RawFD;
const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;
diff --git a/src/base/stl_allocator.h b/src/base/stl_allocator.h
index 7b0b8ca..d9d2983 100644
--- a/src/base/stl_allocator.h
+++ b/src/base/stl_allocator.h
@@ -37,6 +37,7 @@
#include <config.h>
+#include <stddef.h> // for ptrdiff_t
#include <limits>
#include "base/basictypes.h"
diff --git a/src/base/vdso_support.cc b/src/base/vdso_support.cc
index 4543fab..09288a5 100644
--- a/src/base/vdso_support.cc
+++ b/src/base/vdso_support.cc
@@ -40,6 +40,7 @@
#ifdef HAVE_VDSO_SUPPORT // defined in vdso_support.h
#include <fcntl.h>
+#include <stddef.h> // for ptrdiff_t
#include "base/atomicops.h" // for MemoryBarrier
#include "base/linux_syscall_support.h"
diff --git a/src/debugallocation.cc b/src/debugallocation.cc
index c83ba5a..d149ec4 100644
--- a/src/debugallocation.cc
+++ b/src/debugallocation.cc
@@ -668,24 +668,24 @@ class MallocBlock {
reinterpret_cast<void*>(
PRINTABLE_PTHREAD(queue_entry.deleter_threadid)));
- SymbolTable symbolization_table;
- const int num_symbols = queue_entry.num_deleter_pcs; // short alias name
- for (int i = 0; i < num_symbols; i++) {
+ // We don't want to allocate or deallocate memory here, so we use
+ // placement-new. It's ok that we don't destroy this, since we're
+ // just going to error-exit below anyway. Union is for alignment.
+ union { void* alignment; char buf[sizeof(SymbolTable)]; } tablebuf;
+ SymbolTable* symbolization_table = new (tablebuf.buf) SymbolTable;
+ for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
// Symbolizes the previous address of pc because pc may be in the
// next function. This may happen when the function ends with
// a call to a function annotated noreturn (e.g. CHECK).
- char* pc =
- reinterpret_cast<char*>(queue_entry.deleter_pcs[i]) - 1;
- symbolization_table.Add(pc);
+ char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
+ symbolization_table->Add(pc - 1);
}
if (FLAGS_symbolize_stacktrace)
- symbolization_table.Symbolize();
- for (int i = 0; i < num_symbols; i++) {
- char *pc =
- reinterpret_cast<char*>(queue_entry.deleter_pcs[i]) - 1;
- TracePrintf(STDERR_FILENO, " @ %"PRIxPTR" %s\n",
- reinterpret_cast<uintptr_t>(pc),
- symbolization_table.GetSymbol(pc));
+ symbolization_table->Symbolize();
+ for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
+ char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
+ TracePrintf(STDERR_FILENO, " @ %p %s\n",
+ pc, symbolization_table->GetSymbol(pc - 1));
}
} else {
RAW_LOG(ERROR,
diff --git a/src/heap-checker.cc b/src/heap-checker.cc
index 3f042ea..bfb1cd3 100644
--- a/src/heap-checker.cc
+++ b/src/heap-checker.cc
@@ -109,11 +109,7 @@ using std::char_traits;
// If current process is being ptrace()d, 'TracerPid' in /proc/self/status
// will be non-zero.
static bool IsDebuggerAttached(void) { // only works under linux, probably
- // Since we could be called from FailureSignalHandler, avoid stdio
- // which could have been corrupted.
- // Limit stack usage as well. Currently, TracerPid is at max offset 76
- // (depending on length of argv[0]) into /proc/self/status.
- char buf[100];
+ char buf[256]; // TracerPid comes relatively earlier in status output
int fd = open("/proc/self/status", O_RDONLY);
if (fd == -1) {
return false; // Can't tell for sure.
@@ -189,12 +185,6 @@ DEFINE_bool(heap_check_test_pointer_alignment,
// use 1 if any alignment is ok.
// heap_check_test_pointer_alignment flag guides if we try the value of 1.
// The larger it can be, the lesser is the chance of missing real leaks.
-//
-// sizeof(void)* is correct. However gold (the new linker) has a bug where it
-// sometimes places global pointers on 4-byte boundaries, even when pointers
-// are 8 bytes long. While we are fixing the linker, degrade to 4-byte
-// alignment on all targets. http://b/1226481
-//
static const size_t kPointerSourceAlignment = sizeof(void*);
DEFINE_int32(heap_check_pointer_source_alignment,
EnvToInt("HEAP_CHECK_POINTER_SOURCE_ALIGNMENT",
@@ -1874,9 +1864,6 @@ void HeapCleaner::RunHeapCleanups() {
if (!FLAGS_heap_check_after_destructors) DoMainHeapCheck();
}
-// defined below
-static int GetCommandLineFrom(const char* file, char* cmdline, int size);
-
static bool internal_init_start_has_run = false;
// Called exactly once, before main() (but hopefully just before).
@@ -2242,53 +2229,6 @@ void HeapLeakChecker::TurnItselfOffLocked() {
RAW_CHECK(!heap_checker_on, "");
}
-// Read in the command line from 'file' into 'cmdline' and return the size read
-// 'size' is the space available in 'cmdline'.
-// We need this because we don't yet have argv/argc.
-// CAVEAT: 'file' (some /proc/*/cmdline) usually contains the command line
-// already truncated (to 4K on Linux).
-// Arguments in cmdline will be '\0'-terminated,
-// the first one will be the binary's name.
-static int GetCommandLineFrom(const char* file, char* cmdline, int size) {
- // This routine is only used to check if we're running under gdb, so
- // it's ok if this #if fails and the routine is a no-op.
- //
- // This function is called before memory allocation hooks are set up
- // so we must not have any memory allocations in it. We use syscall
- // versions of open/read/close here because we don't trust the non-syscall
- // versions: they might 'accidentally' cause a memory allocation.
- // Here's a real-life problem scenario we had:
- // 1) A program LD_PRELOADed a library called list_file_used.a
- // 2) list_file_used intercepted open/read/close and called dlsym()
- // 3) dlsym() called pthread_setspecific() which called malloc().
- // This malloced memory is 'hidden' from the heap-checker. By
- // definition, this thread-local data is live, and everything it points
- // to is live (not a memory leak) as well. But because this memory
- // was hidden from the heap-checker, everything it points to was
- // taken to be orphaned, and therefore, a memory leak.
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
- // Use a win32 call to get the command line.
- const char* command_line = ::GetCommandLine();
- strncpy(cmdline, command_line, size);
- cmdline[size - 1] = '\0';
- return strlen(cmdline);
-#elif defined(HAVE_SYS_SYSCALL_H)
- int fd = syscall(SYS_open, file, O_RDONLY);
- int result = 0;
- if (fd >= 0) {
- ssize_t r;
- while ((r = syscall(SYS_read, fd, cmdline + result, size)) > 0) {
- result += r;
- size -= r;
- }
- syscall(SYS_close, fd);
- }
- return result;
-#else
- return 0;
-#endif
-}
-
extern bool heap_leak_checker_bcad_variable; // in heap-checker-bcad.cc
static bool has_called_before_constructors = false;
diff --git a/src/page_heap.cc b/src/page_heap.cc
index c92e16b..2e02444 100644
--- a/src/page_heap.cc
+++ b/src/page_heap.cc
@@ -61,7 +61,7 @@ PageHeap::PageHeap()
}
}
-Span* PageHeap::New(Length n) {
+Span* PageHeap::SearchFreeAndLargeLists(Length n) {
ASSERT(Check());
ASSERT(n > 0);
@@ -79,19 +79,25 @@ Span* PageHeap::New(Length n) {
ASSERT(ll->next->location == Span::ON_RETURNED_FREELIST);
return Carve(ll->next, n);
}
- // Still no luck, so keep looking in larger classes.
}
+ // No luck in free lists, our last chance is in a larger class.
+ return AllocLarge(n); // May be NULL
+}
- Span* result = AllocLarge(n);
- if (result != NULL) return result;
+Span* PageHeap::New(Length n) {
+ ASSERT(Check());
+ ASSERT(n > 0);
+
+ Span* result = SearchFreeAndLargeLists(n);
+ if (result != NULL)
+ return result;
- // Grow the heap and try again
+ // Grow the heap and try again.
if (!GrowHeap(n)) {
ASSERT(Check());
return NULL;
}
-
- return AllocLarge(n);
+ return SearchFreeAndLargeLists(n);
}
Span* PageHeap::AllocLarge(Length n) {
diff --git a/src/page_heap.h b/src/page_heap.h
index 545bdda..50ecb36 100644
--- a/src/page_heap.h
+++ b/src/page_heap.h
@@ -215,6 +215,8 @@ class PERFTOOLS_DLL_DECL PageHeap {
// Statistics on system, free, and unmapped bytes
Stats stats_;
+ Span* SearchFreeAndLargeLists(Length n);
+
bool GrowHeap(Length n);
// REQUIRES: span->length >= n
diff --git a/src/pprof b/src/pprof
index 1cb4a05..280ddcc 100755
--- a/src/pprof
+++ b/src/pprof
@@ -72,7 +72,7 @@ use strict;
use warnings;
use Getopt::Long;
-my $PPROF_VERSION = "1.5";
+my $PPROF_VERSION = "1.7";
# These are the object tools we use which can come from a
# user-specified location using --tools, from the PPROF_TOOLS
@@ -211,6 +211,7 @@ Call-graph Options:
--nodecount=<n> Show at most so many nodes [default=80]
--nodefraction=<f> Hide nodes below <f>*total [default=.005]
--edgefraction=<f> Hide edges below <f>*total [default=.001]
+ --maxdegree=<n> Max incoming/outgoing edges per node [default=8]
--focus=<regexp> Focus on nodes matching <regexp>
--ignore=<regexp> Ignore nodes matching <regexp>
--scale=<n> Set GV scaling [default=0]
@@ -319,6 +320,7 @@ sub Init() {
$main::opt_nodecount = 80;
$main::opt_nodefraction = 0.005;
$main::opt_edgefraction = 0.001;
+ $main::opt_maxdegree = 8;
$main::opt_focus = '';
$main::opt_ignore = '';
$main::opt_scale = 0;
@@ -388,6 +390,7 @@ sub Init() {
"nodecount=i" => \$main::opt_nodecount,
"nodefraction=f" => \$main::opt_nodefraction,
"edgefraction=f" => \$main::opt_edgefraction,
+ "maxdegree=i" => \$main::opt_maxdegree,
"focus=s" => \$main::opt_focus,
"ignore=s" => \$main::opt_ignore,
"scale=i" => \$main::opt_scale,
@@ -1814,12 +1817,38 @@ sub PrintDot {
}
}
- # Print edges
- foreach my $e (keys(%edge)) {
+ # Print edges (process in order of decreasing counts)
+ my %indegree = (); # Number of incoming edges added per node so far
+ my %outdegree = (); # Number of outgoing edges added per node so far
+ foreach my $e (sort { $edge{$b} <=> $edge{$a} } keys(%edge)) {
my @x = split(/\001/, $e);
$n = $edge{$e};
- if (abs($n) > $edgelimit) {
+ # Initialize degree of kept incoming and outgoing edges if necessary
+ my $src = $x[0];
+ my $dst = $x[1];
+ if (!exists($outdegree{$src})) { $outdegree{$src} = 0; }
+ if (!exists($indegree{$dst})) { $indegree{$dst} = 0; }
+
+ my $keep;
+ if ($indegree{$dst} == 0) {
+ # Keep edge if needed for reachability
+ $keep = 1;
+ } elsif (abs($n) <= $edgelimit) {
+ # Drop if we are below --edgefraction
+ $keep = 0;
+ } elsif ($outdegree{$src} >= $main::opt_maxdegree ||
+ $indegree{$dst} >= $main::opt_maxdegree) {
+ # Keep limited number of in/out edges per node
+ $keep = 0;
+ } else {
+ $keep = 1;
+ }
+
+ if ($keep) {
+ $outdegree{$src}++;
+ $indegree{$dst}++;
+
# Compute line width based on edge count
my $fraction = abs($local_total ? (3 * ($n / $local_total)) : 0);
if ($fraction > 1) { $fraction = 1; }
@@ -2157,6 +2186,19 @@ function handleMouseUp(evt) {
EOF
}
+# Return a small number that identifies the argument.
+# Multiple calls with the same argument will return the same number.
+# Calls with different arguments will return different numbers.
+sub ShortIdFor {
+ my $key = shift;
+ my $id = $main::uniqueid{$key};
+ if (!defined($id)) {
+ $id = keys(%main::uniqueid) + 1;
+ $main::uniqueid{$key} = $id;
+ }
+ return $id;
+}
+
# Translate a stack of addresses into a stack of symbols
sub TranslateStack {
my $symbols = shift;
@@ -2194,6 +2236,15 @@ sub TranslateStack {
if ($j > 2) {
$func = "$func (inline)";
}
+
+ # Do not merge nodes corresponding to Callback::Run since that
+ # causes confusing cycles in dot display. Instead, we synthesize
+ # a unique name for this frame per caller.
+ if ($func =~ m/Callback.*::Run$/) {
+ my $caller = ($i > 0) ? $addrs[$i-1] : 0;
+ $func = "Run#" . ShortIdFor($caller);
+ }
+
if ($main::opt_addresses) {
push(@result, "$a $func $fileline");
} elsif ($main::opt_lines) {
diff --git a/src/symbolize.h b/src/symbolize.h
index 1ab4ed6..12c976b 100644
--- a/src/symbolize.h
+++ b/src/symbolize.h
@@ -37,6 +37,7 @@
#ifdef HAVE_STDINT_H
#include <stdint.h> // for uintptr_t
#endif
+#include <stddef.h> // for NULL
#include <map>
using std::map;
diff --git a/src/system-alloc.cc b/src/system-alloc.cc
index e589469..f28fa22 100644
--- a/src/system-alloc.cc
+++ b/src/system-alloc.cc
@@ -31,6 +31,7 @@
// Author: Sanjay Ghemawat
#include <config.h>
+#include <stddef.h> // for NULL
#if defined HAVE_STDINT_H
#include <stdint.h>
#elif defined HAVE_INTTYPES_H
diff --git a/src/tests/debugallocation_test.cc b/src/tests/debugallocation_test.cc
index f10e2dc..dd5af13 100644
--- a/src/tests/debugallocation_test.cc
+++ b/src/tests/debugallocation_test.cc
@@ -213,6 +213,17 @@ TEST(DebugAllocationTest, DanglingWriteAtExitTest) {
*x = old_x_value; // restore x so that the test can exit successfully.
}
+TEST(DebugAllocationTest, StackTraceWithDanglingWriteAtExitTest) {
+ int *x = new int;
+ delete x;
+ int old_x_value = *x;
+ *x = 1;
+ // verify that we also get a stack trace when we have a dangling write.
+ // The " @ " is part of the stack trace output.
+ IF_DEBUG_EXPECT_DEATH(exit(0), " @ .* main");
+ *x = old_x_value; // restore x so that the test can exit successfully.
+}
+
static size_t CurrentlyAllocatedBytes() {
size_t value;
CHECK(MallocExtension::instance()->GetNumericProperty(
@@ -264,16 +275,11 @@ TEST(DebugAllocationTest, HugeAlloc) {
// compiler as too large for the allocation.
size_t kTooBig = ~static_cast<size_t>(0);
void* a = NULL;
- char* b = NULL;
#ifndef NDEBUG
a = malloc(kTooBig);
EXPECT_EQ(NULL, a);
- b = NULL;
- IF_DEBUG_EXPECT_DEATH(b = new char[kTooBig],
- "Unable to allocate.*new\\[\\] failed\\.");
- EXPECT_EQ(NULL, b);
// kAlsoTooBig is small enough not to get caught by debugallocation's check,
// but will still fall through to tcmalloc's check. This must also be
@@ -282,8 +288,6 @@ TEST(DebugAllocationTest, HugeAlloc) {
a = malloc(kAlsoTooBig);
EXPECT_EQ(NULL, a);
- IF_DEBUG_EXPECT_DEATH(b = new char[kAlsoTooBig], "Unable to allocate.*new failed");
- EXPECT_EQ(NULL, b);
#endif
}
diff --git a/src/tests/debugallocation_test.sh b/src/tests/debugallocation_test.sh
index 2568d54..5d9bd8b 100755
--- a/src/tests/debugallocation_test.sh
+++ b/src/tests/debugallocation_test.sh
@@ -52,21 +52,38 @@ num_failures=0
# Increments num_failures if the death test does not succeed.
OneDeathTest() {
"$DEBUGALLOCATION_TEST" "$1" 2>&1 | {
- read regex_line
- regex=`expr "$regex_line" : "Expected regex:\(.*\)"`
- test -z "$regex" && echo "done" # no regex line, not a death-case
- grep "$regex" >/dev/null 2>&1 # pass the rest of the lines through grep
- } || num_failures=`expr $num_failures + 1`
+ regex_line='dummy'
+ # Normally the regex_line is the first line of output, but not
+ # always (if tcmalloc itself does any logging to stderr).
+ while test -n "$regex_line"; do
+ read regex_line
+ regex=`expr "$regex_line" : "Expected regex:\(.*\)"`
+ test -n "$regex" && break # found the regex line
+ done
+ test -z "$regex" && echo "done" || grep "$regex" 2>&1
+ }
}
death_test_num=0 # which death test to run
-while test -z `OneDeathTest "$death_test_num"`; do
- echo "Done with death test $death_test_num"
+while /bin/true; do
+ echo -n "Running death test $death_test_num..."
+ output="`OneDeathTest $death_test_num`"
+ case $output in
+ # Empty string means grep didn't find anything.
+ "") echo "FAILED"; num_failures=`expr $num_failures + 1`;;
+ "done"*) echo "done with death tests"; break;;
+ # Any other string means grep found something, like it ought to.
+ *) echo "OK";;
+ esac
death_test_num=`expr $death_test_num + 1`
done
# Test the non-death parts of the test too
-if ! "$DEBUGALLOCATION_TEST"; then
+echo -n "Running non-death tests..."
+if "$DEBUGALLOCATION_TEST"; then
+ echo "OK"
+else
+ echo "FAILED"
num_failures=`expr $num_failures + 1`
fi
diff --git a/src/tests/malloc_extension_test.cc b/src/tests/malloc_extension_test.cc
index 60f4919..0bd85ad 100644
--- a/src/tests/malloc_extension_test.cc
+++ b/src/tests/malloc_extension_test.cc
@@ -72,30 +72,6 @@ int main(int argc, char** argv) {
ASSERT_LE(MallocExtension_GetAllocatedSize(a), 5000);
ASSERT_GE(MallocExtension_GetEstimatedAllocatedSize(1000), 1000);
- // test invariant: size of freelist = heap_size - allocated_bytes
- free(malloc(32000));
- size_t heap_size = 0;
- size_t allocated = 0;
- ASSERT_TRUE(MallocExtension::instance()->GetNumericProperty(
- "generic.current_allocated_bytes", &allocated));
- ASSERT_TRUE(MallocExtension::instance()->GetNumericProperty(
- "generic.heap_size", &heap_size));
- vector<MallocExtension::FreeListInfo> info;
- MallocExtension::instance()->GetFreeListSizes(&info);
-
- ASSERT_GE(info.size(), 0);
- int64 free_bytes = 0;
- for (vector<MallocExtension::FreeListInfo>::const_iterator it = info.begin();
- it != info.end();
- ++it) {
- free_bytes += it->total_bytes_free;
- }
-
- // don't expect an exact equality since the calls to query the heap
- // themselves free and allocate memory
- size_t error = abs((heap_size - allocated) - free_bytes);
- ASSERT_LT(error, 0.15 * heap_size);
-
free(a);
printf("DONE\n");
diff --git a/src/windows/port.h b/src/windows/port.h
index 81a68e6..ff6b714 100644
--- a/src/windows/port.h
+++ b/src/windows/port.h
@@ -277,7 +277,10 @@ enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
#define O_RDONLY _O_RDONLY
#endif
-extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
+#ifdef __cplusplus
+extern "C"
+#endif
+PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
// ----------------------------------- SYSTEM/PROCESS
typedef int pid_t;