|
From: Carlo W. <li...@us...> - 2001-12-30 04:18:06
|
CVSROOT : /cvsroot/libcw
Module : src
Commit time: 2001-11-30 04:18:01 UTC
Modified files:
libcwd/INSTALL libcwd/Makefile.am libcwd/NEWS libcwd/README
libcwd/acinclude.m4 libcwd/bfd.cc libcwd/configure.in
libcwd/debug.cc libcwd/debugmalloc.cc libcwd/demangle.cc
libcwd/demangle3.cc libcwd/elf32.cc libcwd/libcwd.spec.in
libcwd/maintMakefile.in libcwd/strerrno.cc libcwd/type_info.cc
libcwd/example-project/.cvsignore
libcwd/example-project/Makefile.am
libcwd/example-project/configure.in
libcwd/example-project/debug.cc
libcwd/example-project/macrotest.cc
libcwd/example-project/program.cc libcwd/example-project/sys.h
libcwd/include/Makefile.am libcwd/include/sys.ho.in
libcwd/include/libcw/Makefile.am libcwd/include/libcw/bfd.h
libcwd/include/libcw/buf2str.h libcwd/include/libcw/char2str.h
libcwd/include/libcw/cwprint.h libcwd/include/libcw/debug.h
libcwd/include/libcw/debug_config.ho.in
libcwd/include/libcw/debugmalloc.h
libcwd/include/libcw/demangle.h
libcwd/include/libcw/lockable_auto_ptr.h
libcwd/include/libcw/strerrno.h libcwd/include/libcw/sysd.ho.in
libcwd/include/libcw/type_info.h libcwd/tests/.cvsignore
libcwd/tests/Makefile.am libcwd/tests/dout_alloc.cc
libcwd/tests/hello_world.cc libcwd/tests/hello_world_debug.h
libcwd/tests/initbug.cc libcwd/tests/syslog.cc
libcwd/tests/syslog_debug.h libcwd/testsuite/Makefile.in
libcwd/testsuite/module.cc
libcwd/testsuite/libcwd.tst/alloctag.cc
libcwd/testsuite/libcwd.tst/alloctag.re
libcwd/testsuite/libcwd.tst/bfd.cc
libcwd/testsuite/libcwd.tst/bfd.re
libcwd/testsuite/libcwd.tst/cf.cc
libcwd/testsuite/libcwd.tst/continued.cc
libcwd/testsuite/libcwd.tst/dc.cc
libcwd/testsuite/libcwd.tst/debug.h
libcwd/testsuite/libcwd.tst/demangler.cc
libcwd/testsuite/libcwd.tst/demangler.re
libcwd/testsuite/libcwd.tst/dlopen.cc
libcwd/testsuite/libcwd.tst/dlopen.re
libcwd/testsuite/libcwd.tst/do.cc
libcwd/testsuite/libcwd.tst/do.re
libcwd/testsuite/libcwd.tst/flush.cc
libcwd/testsuite/libcwd.tst/leak.cc
libcwd/testsuite/libcwd.tst/leak.re
libcwd/testsuite/libcwd.tst/lockable_auto_ptr.cc
libcwd/testsuite/libcwd.tst/magic.cc
libcwd/testsuite/libcwd.tst/marker.cc
libcwd/testsuite/libcwd.tst/test.exp
libcwd/testsuite/libcwd.tst/test_delete.cc
libcwd/testsuite/libcwd.tst/test_delete.re
libcwd/testsuite/libcwd.tst/type_info.cc libcwd/utils/Makefile.am
libcwd/utils/buf2str.cc libcwd/utils/char2str.cc
libcwd/utils/exec_prog.cc
Added files:
libcwd/threading.cc libcwd/documentation/.cvsignore
libcwd/documentation/Makefile libcwd/documentation/README
libcwd/documentation/alloc_intro.dox
libcwd/documentation/allocated_memory_overview.dox
libcwd/documentation/control_flags.dox
libcwd/documentation/custom-debug.h.dox
libcwd/documentation/custom_do.dox
libcwd/documentation/deallocation_pointer_validation.dox
libcwd/documentation/debug_channels.dox
libcwd/documentation/debug_object.dox
libcwd/documentation/definitions.m4
libcwd/documentation/destination.dox
libcwd/documentation/downloading.dox
libcwd/documentation/doxygen.config
libcwd/documentation/fatal_output.dox
libcwd/documentation/finding.dox
libcwd/documentation/formatting.dox
libcwd/documentation/html.footer libcwd/documentation/html.header
libcwd/documentation/invisible.dox
libcwd/documentation/location.dox
libcwd/documentation/locations.dox libcwd/documentation/magic.dox
libcwd/documentation/mainpage.dox
libcwd/documentation/memory_leak_checking.dox
libcwd/documentation/modules.dox
libcwd/documentation/namespaces.dox
libcwd/documentation/nested.dox
libcwd/documentation/preparation.dox
libcwd/documentation/reference.dox
libcwd/documentation/special.dox
libcwd/documentation/symbols_intro.dox
libcwd/documentation/type_info.dox
libcwd/documentation/why_macro.dox
libcwd/documentation/writing_intro.dox
libcwd/documentation/doxygen-examples/markers.cc
libcwd/documentation/external/.cvsignore
libcwd/documentation/images/libcw_magic.png
libcwd/documentation/images/libcwd_logo.png
libcwd/documentation/images/toc.png
libcwd/documentation/images/wink.gif
libcwd/documentation/images/buttons/lr_index.png
libcwd/documentation/images/buttons/lr_next.png
libcwd/documentation/images/buttons/lr_prev.png
libcwd/documentation/images/lines/cat.png
libcwd/documentation/images/lines/caterpil.png
libcwd/documentation/images/lines/ghost.png
libcwd/documentation/images/lines/hippo.png
libcwd/documentation/images/lines/mouse.png
libcwd/documentation/images/lines/owl.png
libcwd/documentation/images/lines/snail.png
libcwd/documentation/scripts/break_out_of_frame.js
libcwd/documentation/scripts/detect_browser.js
libcwd/documentation/scripts/load_style_sheets.js
libcwd/documentation/styles/.cvsignore
libcwd/documentation/styles/Makefile
libcwd/documentation/styles/defines.h
libcwd/documentation/styles/doxygen.css
libcwd/documentation/styles/main.css
libcwd/documentation/styles/test.m4
libcwd/documentation/styles/tutorial.css
libcwd/documentation/styles/ie/.cvsignore
libcwd/documentation/styles/konqueror/.cvsignore
libcwd/documentation/styles/mozilla/.cvsignore
libcwd/documentation/styles/netscape4/.cvsignore
libcwd/documentation/styles/netscape6/.cvsignore
libcwd/documentation/tutorial/.cvsignore
libcwd/documentation/tutorial/Makefile
libcwd/documentation/tutorial/channel.cc
libcwd/documentation/tutorial/faq.m4
libcwd/documentation/tutorial/hello_world.cc
libcwd/documentation/tutorial/index.m4
libcwd/documentation/tutorial/intro.m4
libcwd/documentation/tutorial/log_file.cc
libcwd/documentation/tutorial/moo.awk
libcwd/documentation/tutorial/tut1.m4
libcwd/documentation/tutorial/tut2.m4
libcwd/documentation/tutorial/tut3.m4
libcwd/documentation/tutorial/tut4.m4
libcwd/documentation/tutorial/tut5.in
libcwd/documentation/tutorial/tut6.m4
libcwd/documentation/tutorial/tut7.in
libcwd/documentation/tutorial/examples7/.cvsignore
libcwd/documentation/tutorial/examples7/debug.h
libcwd/documentation/tutorial/examples7/sys.h
libcwd/example-project/acconfig.h
libcwd/example-project/debug.h.maintainer
libcwd/include/cwd_debug.h libcwd/include/elf32.h
libcwd/include/exec_prog.h libcwd/include/ios_base_Init.h
libcwd/include/private_debug_stack.inl
libcwd/include/libcw/class_alloc.h
libcwd/include/libcw/class_channel.h
libcwd/include/libcw/class_channel.inl
libcwd/include/libcw/class_channel_set.h
libcwd/include/libcw/class_channel_set.inl
libcwd/include/libcw/class_continued_channel.h
libcwd/include/libcw/class_continued_channel.inl
libcwd/include/libcw/class_debug.h
libcwd/include/libcw/class_debug.inl
libcwd/include/libcw/class_debug_string.h
libcwd/include/libcw/class_debug_string.inl
libcwd/include/libcw/class_fatal_channel.h
libcwd/include/libcw/class_fatal_channel.inl
libcwd/include/libcw/class_location.h
libcwd/include/libcw/class_location.inl
libcwd/include/libcw/class_marker.h
libcwd/include/libcw/control_flag.h
libcwd/include/libcw/core_dump.h
libcwd/include/libcw/enum_memblk_types.h
libcwd/include/libcw/macro_AllocTag.h
libcwd/include/libcw/macro_ForAllDebugChannels.h
libcwd/include/libcw/macro_ForAllDebugObjects.h
libcwd/include/libcw/macro_Libcwd_macros.h
libcwd/include/libcw/max_label_len.h
libcwd/include/libcw/pc_mangled_function_name.h
libcwd/include/libcw/private_TSD.h
libcwd/include/libcw/private_allocator.h
libcwd/include/libcw/private_assert.h
libcwd/include/libcw/private_debug_stack.h
libcwd/include/libcw/private_internal_string.h
libcwd/include/libcw/private_internal_stringstream.h
libcwd/include/libcw/private_internal_vector.h
libcwd/include/libcw/private_set_alloc_checking.h
libcwd/include/libcw/private_threading.h
libcwd/tests/allocator.cc libcwd/tests/stabs.cc
libcwd/tests/threads.cc libcwd/tests/threads2.cc
libcwd/tests/threads3.cc libcwd/tests/threads4.cc
libcwd/tests/threads_debug.h libcwd/testsuite/libcwd.tst/sys.h
Removed files:
libcwd/README.nodebug.h libcwd/cwprint.cc
libcwd/debugdebugcheckpoint.cc
libcwd/no_alloc_checking_stringstream.cc
libcwd/example-project/debug.h
libcwd/example-project/maintMakefile.in
libcwd/include/libcw/bcd2str.h
libcwd/include/libcw/debugdebugcheckpoint.h
libcwd/include/libcw/elf32.h libcwd/include/libcw/exec_prog.h
libcwd/include/libcw/iomanip.h
libcwd/include/libcw/no_alloc_checking_stringstream.h
libcwd/include/libcw/perf.h libcwd/testsuite/libcwd.tst/undef.cc
libcwd/testsuite/libcwd.tst/undef.re libcwd/utils/bcd2str.cc
libcwd/utils/perf.cc
Log message:
Merge from branch-threading.
---------------------- diff included ----------------------
Index: src/libcwd/INSTALL
diff -u src/libcwd/INSTALL:1.21 src/libcwd/INSTALL:1.22
--- src/libcwd/INSTALL:1.21 Sat Sep 22 22:01:08 2001
+++ src/libcwd/INSTALL Sat Dec 29 20:17:46 2001
@@ -3,6 +3,7 @@
./configure --prefix=/usr
make
+su
make install
If that doesn't work, mail me: li...@al...
@@ -14,101 +15,109 @@
Check if you have all GNU tools/libraries/packages that libcwd depends on:
- Primary site:
- ftp://ftp.gnu.org/gnu/
+Primary site:
+ftp://ftp.gnu.org/gnu/
- List of mirrors:
- http://www.gnu.org/order/ftp.html
+List of mirrors:
+http://www.gnu.org/order/ftp.html
- Packages/versions needed
- ------------------------
+Packages/versions needed
+------------------------
- i) The GNU compiler, version 2.95.1 or higher.
-
- Location: gnu/gcc/
- Current version: 3.0
-
- Alternatively you can install only
- ia) gnu/gcc/gcc-core-<version>.tar.gz and
- ib) gnu/gcc/gcc-g++-<version>.tar.gz
-
- Note: It is very unlikely that you want to install
- the source tree of gcc/g++. Please try to upgrade your
- compiler the usual way if needed.
- If you are using rpm's then you will need to
- install/upgrade the following:
- gcc (2.95.1 or higher),
- gcc-c++ (of same version),
- libstdc++ (of same version) and
- cpp (of same version).
- Check your installation on RedHat with:
- rpm -qa | egrep '(gcc|libstdc|cpp)'
-
- Note: If you don't use rpm's but are using tar balls,
- then you do NOT need to download gnu/libstdc++/* because
- gcc-2.95 and higher comes with libstdc++ included.
- The gnu/libstdc++/ directory on GNU ftp sites are
- for older compilers or to be used as source drop-in
- when you compile g++ (replacing the normal stdc++ with
- an alpha version). You also don't need libg++.
- Don't delete those libraries if you have them though
- since existing binaries might need to link with them.
-
- libcwd-0.99.15 was tested with gcc-2.95.x, gcc-2.96-97 (RedHat),
- gcc-3.0 and gcc-3.0.1.
-
- Packages needed to run the testsuite
- ------------------------------------
-
- If you want to run the testsuite then you will have to install
- dejagnu-1.4.1 which can be downloaded from ftp://ftp.gnu.org/gnu/dejagnu/,
- or your local GNU mirror. However, this version still contains a bug
- and you'll have to apply the following patch: edit /usr/share/dejagnu/target.exp
- line 275 and remove the newline at the end (so that the word "text" on line
- 276 is added at the end of line 275:
- regsub -all ".*: warning: -f(pic|PIC) ignored for target .*" $text "" text
-
- Alternatively, you can get dejagnu directly from the cvs repository
- at http://www.gnu.org/software/dejagnu/ where this bug already has been
- fixed (as it will be in any version *after* 1.4.1).
-
- You will also need expect-5.32.2 (and tcl/tk 8.3.3?). At least, expect 5.31.2
- is known to hang.
-
- Packages/versions needed as maintainer or when using CVS
- --------------------------------------------------------
-
- If you want to generate maintainer files (and you need that when
- you get this package via CVS) then you also need to have the
- following tools:
-
- iii) GNU make
- iv) GNU m4
- v) GNU which version 2.x
- vi) autoconf version 2.13 (2.52 seems to have problems)
- vii) automake version 1.4pl1 or higher
- viii) libtool version 1.4 or higher
+i) The GNU compiler, version 2.95.1 or higher.
+
+ Location: gnu/gcc/
+ Current version: 3.0.2
+
+Alternatively you can install only
+ia) gnu/gcc/gcc-core-<version>.tar.gz and
+ib) gnu/gcc/gcc-g++-<version>.tar.gz
+
+Note: It is very unlikely that you want to install
+the source tree of gcc/g++. Please try to upgrade your
+compiler the usual way if needed.
+If you are using rpm's then you will need to
+install/upgrade the following:
+ gcc (2.95.1 or higher),
+ gcc-c++ (of same version),
+ libstdc++ (of same version) and
+ cpp (of same version).
+Check your installation on RedHat with:
+ rpm -qa | egrep '(gcc|libstdc|cpp)'
+
+Note: If you don't use rpm's but are using tar balls,
+then you do NOT need to download gnu/libstdc++/* because
+gcc-2.95 and higher comes with libstdc++ included.
+The gnu/libstdc++/ directory on GNU ftp sites are
+for older compilers or to be used as source drop-in
+when you compile g++ (replacing the normal stdc++ with
+an alpha version). You also don't need libg++.
+Don't delete those libraries if you have them though
+since existing binaries might need to link with them.
+
+libcwd-0.99.16 was tested with gcc-2.95.x, gcc-2.96-97 (RedHat)
+and gcc-3.0.x.
+
+Packages needed to run the testsuite
+------------------------------------
+
+ii) If you want to run the testsuite then you will have to install
+dejagnu-1.4.1 which can be downloaded from ftp://ftp.gnu.org/gnu/dejagnu/,
+or your local GNU mirror. However, this version still contains a bug
+and you'll have to apply the following patch: edit /usr/share/dejagnu/target.exp
+line 275 and remove the newline at the end (so that the word "text" on line
+276 is added at the end of line 275:
+regsub -all ".*: warning: -f(pic|PIC) ignored for target .*" $text "" text
+
+Alternatively, you can get dejagnu directly from the cvs repository
+at http://www.gnu.org/software/dejagnu/ where this bug already has been
+fixed (as it will be in any version *after* 1.4.1).
+
+You will also need expect-5.32.2 (and tcl/tk 8.3.3?). At least, expect 5.31.2
+is known to hang.
+
+Packages/versions needed as maintainer or when using CVS
+--------------------------------------------------------
+
+If you want to generate maintainer files (and you need that when you
+get this package via CVS; in that case you also need to configure using
+--enable-maintainer-mode) then you also need to have the following tools:
+
+iii) GNU make
+iv) GNU m4
+v) GNU which version 2.x
+vi) autoconf version 2.13 (2.52 seems to have problems)
+vii) automake version 1.4pl1 or higher
+viii) libtool version 1.4 or higher
+
+Each of those can be downloaded from your local GNU site.
+
+Moreover, in order to generate the documentation, you need to
+have the following installed:
+
+ix) GNU grep version 2.4.2 is known to work.
+x) doxygen version 1.2.12 or higher (http://www.doxygen.org/)
+xi) graphviz http://www.research.att.com/sw/tools/graphviz/
- Each of those can be downloaded from your local GNU site.
Hackers info
============
-=i=-
-`configure' has a few interesting options. You can list them by issuing:
+'configure' has a few interesting options. You can list them by issuing:
./configure --help
There is no reason to use libcwd's feature options (--disable-libcwd-alloc,
--disable-libcwd-magic, --disable-libcwd-marker and --disable-libcwd-location).
-Actually, I forgot why they are there :). You can read more about what
-they do in Chapter 4 "Debugging compile options" here:
-http://libcw.sourceforge.net/templates/index.html?debugging
-If you want to change Makefile.am files and the-like then you'll need to
+Actually, I forgot why they are there :). You can read more about the
+configuration options and what they do in include/libcw/debug_config.h.
+
+If you want to change Makefile.am files and the like then you'll need to
use --enable-maintainer-mode. If you enable maintainer-mode then you
-will need GNU make, other make won't work (you also need a lot of other
-extra tools installed on your system).
+will need GNU make, other make won't work (you also need a LOT of other
+extra tools installed on your system, only for the brave thus).
-=ii=-
@@ -124,7 +133,7 @@
-=iii=-
If you don't have an ELF32 system and therefore need to link with libbfd, then you
-can configure using --enable-libcwd-bfd. If libiberty.a or libbfd.so are in an
+can configure using --enable-libcwd-libbfd. If libiberty.a or libbfd.so are in an
unusual directory, then you will have to set LDFLAGS prior to running ./configure:
LDFLAGS="-L/usr/gnu/lib" CPPFLAGS="-I/usr/gnu/include" ./configure
@@ -132,15 +141,15 @@
Please note that the libbfd that comes with binutils-2.11.x is not compatible
with the libiberty that comes with with gcc-2.95.x.
--=iii=-
+-=iv=-
-You can install libcwd in a `staging' directory by issuing
+You can install libcwd in a 'staging' directory by issuing
make DESTDIR=/tmp/staging install
this can come in handy when you want to build an rpm for instance.
--=iv=-
+-=v=-
The Makefile has the following targets:
@@ -150,22 +159,29 @@
make clean
make distclean
-If you feel brave you might even want to try
+If you configured with --enable-maintainer-mode then the following
+targets exist as well:
-make dist
-make maintainer-clean
+make dist // Create tar ball
+make maintainer-clean // Erase everything that was generated somehow
+make check // Run test suite
+make tar // Create tar ball
+make rpm // Create rpms
+make ChangeLog // Generate ChangeLog from cvs database
+make CC="gcc-3.0.2" CXX="g++-3.0.2" reconfig // Switch compilers keeping the same configuration
+make full-check // Iterate over all configurations and all compiler versions
-well, ... heh. Look in the Makefile for more targets ;)
+It is not garanteed that these work on another machine than mine however.
--=v=-
+-=vi=-
Finally, you can also build libcwd in a different directory than the source
tree is in:
-tar xzf libcwd-0.99.15.tar.gz
+tar xzf libcwd-0.99.16.tar.gz
mkdir libcwd-objdir
cd libcwd-objdir
-../libcwd-0.99.15/configure --prefix=/usr
+../libcwd-0.99.16/configure --prefix=/usr
make
su
make install
Index: src/libcwd/Makefile.am
diff -u src/libcwd/Makefile.am:1.34 src/libcwd/Makefile.am:1.35
--- src/libcwd/Makefile.am:1.34 Thu Dec 27 21:25:27 2001
+++ src/libcwd/Makefile.am Sat Dec 29 20:17:46 2001
@@ -4,8 +4,8 @@
SUBDIRS = include utils . tests testsuite
-BUILT_SOURCES =@MAINTAINER_MODE_TRUE@ libcwd.lsm libcwd.spec nodebug.h
-EXTRA_DIST = LICENSE.QPL README.FreeBSD README.openbsd README.nodebug.h debian $(BUILT_SOURCES)
+BUILT_SOURCES =@MAINTAINER_MODE_TRUE@ libcwd.lsm libcwd.spec
+EXTRA_DIST = LICENSE.QPL README.FreeBSD README.openbsd nodebug.h $(BUILT_SOURCES)
DISTCLEANFILES = libcwd-@VERSION@.tar.gz
VERSIONINFO=@VERSIONINFO@
@@ -18,17 +18,15 @@
lib_LTLIBRARIES = libcwd.la
libcwd_la_SOURCES = \
+ threading.cc \
elf32.cc \
bfd.cc \
debug.cc \
- debugdebugcheckpoint.cc \
debugmalloc.cc \
demangle.cc \
demangle3.cc \
- cwprint.cc \
strerrno.cc \
- type_info.cc \
- no_alloc_checking_stringstream.cc
+ type_info.cc
libcwd_la_LDFLAGS = -version-info $(VERSIONINFO)
@@ -36,12 +34,20 @@
# --------------- Maintainer's Section
-dist-hook:
+dist-hook: example-project/debug.h documentation
+ cp -pr $(srcdir)/documentation $(distdir)/documentation
+ find $(distdir)/documentation -name CVS -print | xargs rm -rf
mkdir $(distdir)/example-project
for i in `grep '^/' $(srcdir)/example-project/CVS/Entries | cut -d/ -f2`; do \
cp -p $(srcdir)/example-project/$$i $(distdir)/example-project; \
done
+ rm $(distdir)/example-project/debug.h.maintainer $(distdir)/example-project/macrotest.cc
+ cp -p $(srcdir)/example-project/debug.h $(distdir)/example-project
chmod +x $(distdir)/install-sh
+ mkdir $(distdir)/debian
+ for i in `grep '^/' $(srcdir)/debian/CVS/Entries | cut -d/ -f2`; do \
+ cp -p $(srcdir)/debian/$$i $(distdir)/debian; \
+ done
distclean-local:
rm -rf rpm
Index: src/libcwd/NEWS
diff -u src/libcwd/NEWS:1.61 src/libcwd/NEWS:1.62
--- src/libcwd/NEWS:1.61 Thu Dec 27 21:25:27 2001
+++ src/libcwd/NEWS Sat Dec 29 20:17:46 2001
@@ -1,7 +1,13 @@
-libcwd-0.99.15
+libcwd-0.99.16
- libcwd now works with (single threaded) qt applications. A few major
- bugs have been fixed.
+ libcwd is now thread-safe.
+
+ The source file line number lookup was improved for optimized code with
+ inlined functions (-O).
+
+ New configuration option --disable-libcwd-debug-output was added to
+ allow the use of the testsuite together with --enable-libcwd-debug.
+ (You shouldn't use either unless you are hacking libcwd itself).
Miscellaneous:
- The configuration option --disable-libcwd-location is fixed.
@@ -9,6 +15,70 @@
API changes:
+ IMPORTANT: Debug channels have globally been renamed to Debug
+ selectors. The word 'channel' had too much association with output
+ destinations (streams).
+
+ IMPORTANT: 'channel_ct const' -> 'selector_ct'.
+ Debug selectors (previously channels) should no longer be declared
+ constant. Declarations like
+ libcw::debug::channel_ct const my_channel("FOO");
+ will have to be changed to
+ libcw::debug::selector_ct my_channel("FOO");
+
+ `long memblks()' has been renamed to `unsigned long mem_blocks()'.
+
+ In debug_ct, set_margin, get_margin, set_marker and get_marker are
+ a bit slow for heavy swapping of the margin and marker (std::string
+ is 'slow'); therefore (using internal allocations, which is not
+ possible with std::string (see bug fixes below)) public access
+ to members debug_ct::margin and debug_ct::marker is now granted,
+ providing the following methods of the returned object: size(),
+ c_str() (the terminating zero is already there, this just returns
+ an internal pointer), reserve(), capacity(), append(), prepend()
+ and assign() - all with meanings borrowed from std::string.
+ For example, when capacity() returns a value larger or equal to
+ the length of a string that would result from a call to append(),
+ then calling append is garanteed not to invalidate the pointer
+ returned by c_str(). The default capacity can be set with `reserve'.
+ append/prepend/assign accept both a std::string reference or a
+ char*/size_t pair.
+ Finally, the following methods are added to debug_ct directly:
+ `push_margin', `pop_margin', `push_marker' and `pop_marker'.
+ These functions can be used to quickly store and restore the
+ respective formatting strings.
+
+ A debug function for internal use (by the maintainers):
+ `debugdebugcheckpoint()' has been removed. If you need a user
+ function to be called every Dout() then can define your own Dout
+ macro's, that makes more sense then recompiling libcwd.
+
+ CWASSERT was renamed to LIBCWD_ASSERT; Note that all macros that start
+ with LIBCWD_ should NOT be used by the user, they are for internal use
+ by libcwd.
+
+ Bug fixes:
+
+ When using .stabs, each first line of code after a source file scope change
+ as a result of an inlined function resulted in a location lookup failure
+ ("No line number").
+
+ The default std::allocator implementation uses static pointers to keep
+ a private free list, allocating memory with malloc() in large chunks.
+ The sharing of this memory pool with all STL containers, including
+ std::string and std::stringstreams - and even the buffers of std::cout
+ and std::cerr - caused `internal' allocations being mixed with `userspace'
+ allocations and thus an incorrect error detection.
+ Libcwd now uses its own allocators, with their own memory pool, for
+ variables that need internal allocations.
+
+libcwd-0.99.15
+
+ libcwd now works with (single threaded) qt applications. A few major
+ bugs have been fixed.
+
+ API changes:
+
You now MUST use CWDEBUG, defining DEBUG will no longer work; it was
incompatible with qt-2.2.4.
@@ -39,18 +109,10 @@
On systems where a 'char' is unsigned, the line number lookup of DWARF
failed.
-
- Some systems (I had this on a powerpc-unknown-linux-gnu) and/or with
- old binutils produce incorrect .stabs N_FUN entries, causing the line
- number lookup of stabs to fail. Libcwd now detects this and then uses
- an alternative way to determining the start of a function (as a result
- libcwd now succeeds where libbfd fails).
-
- Added a workaround for a bug in libtools so that executables in the
- tests/ directory no longer can accidently link with an old installed
- version of libcwd.
- Several fixes in the build system (all related to the testsuite).
+ Systems with old binutils produce incorrect .stabs entries, causing
+ the line number lookup of stabs to fail. Libcwd now detects this and
+ then aborts.
libcwd-0.99.13
Index: src/libcwd/README
diff -u src/libcwd/README:1.8 src/libcwd/README:1.9
--- src/libcwd/README:1.8 Mon Jul 30 21:10:04 2001
+++ src/libcwd/README Sat Dec 29 20:17:46 2001
@@ -37,44 +37,6 @@
2) Support for memory allocation debugging.
-Documentation
--------------
-
-You can find extensive documentation online at
-http://libcw.sourceforge.net/debugging/. There you will find
-a reference manual, a tutorial and many examples.
-
-It is highly recommended that you download and install the html
-files locally for greater speed. At the moment you can only
-download the documentation by using `cvs':
-
-Install cvs (after all, you are a developer) and issue the
-following command once:
-
-cvs -d:pserver:ano...@cv...:/cvsroot/libcw login
-
-When prompted for a password for anonymous, simply press the
-Enter key. Next download the documentation with the following
-commandline:
-
-cvs -z3 -d:pserver:ano...@cv...:/cvsroot/libcw co www
-
-At any later time you can update the documentation by changing
-directory into the www directory and issuing:
-
-cvs update -d
-
-A European mirror has been setup in Amsterdam (the Netherlands) at
-http://www.alinoe.com/. This is my home PC (cable, 128cps) and
-therefore only contains the front page, using www.xs4all.nl
-(my other provider) for all the rest of the pages and images.
-Feel free to try this when sourceforge is too slow.
-
-Note that the documentation includes documentation of libcw
-(without a `d' at the end), libcw is not released to the public
-yet. You can ignore everything not in the debugging/ directory.
-
-
Anonymous CVS Access
--------------------
Index: src/libcwd/README.nodebug.h
diff -u src/libcwd/README.nodebug.h:1.1 src/libcwd/README.nodebug.h:removed
--- src/libcwd/README.nodebug.h:1.1 Wed Jul 25 19:10:39 2001
+++ src/libcwd/README.nodebug.h Sat Dec 29 20:18:01 2001
@@ -1,7 +0,0 @@
-In order to make it possible that others compile your application without
-having libcwd installed, the file nodebug.h must be part of the distribution
-of your application and should be included instead of <libcw/debug.h>
-when CWDEBUG is not defined.
-
-For an example of how to do this, see the example-project directory.
-
Index: src/libcwd/acinclude.m4
diff -u src/libcwd/acinclude.m4:1.43 src/libcwd/acinclude.m4:1.44
--- src/libcwd/acinclude.m4:1.43 Thu Dec 27 21:25:27 2001
+++ src/libcwd/acinclude.m4 Sat Dec 29 20:17:46 2001
@@ -161,12 +161,11 @@
dnl CW_DEFINE_TYPE(NEWTYPE, OLDTYPE)
dnl
-dnl Add `typedef OLDTYPE NEWTYPE' to the output variable CW_TYPEDEFS
+dnl Add `typedef OLDTYPE NEWTYPE;' to the output variable CW_TYPEDEFS
dnl
AC_DEFUN(CW_DEFINE_TYPE,
[AC_REQUIRE([CW_DEFINE_TYPE_INITIALIZATION])
-CW_TYPEDEFS="$CW_TYPEDEFS\\
-typedef $2 $1;"
+CW_TYPEDEFS="typedef $2 $1; $CW_TYPEDEFS"
])
dnl CW_TYPE_EXTRACT_FROM(FUNCTION, INIT, ARGUMENTS, ARGUMENT)
@@ -334,6 +333,7 @@
AC_DEFUN(CW_MALLOC_OVERHEAD,
[AC_CACHE_CHECK(malloc overhead in bytes, cw_cv_system_mallocoverhead,
[CW_TRY_RUN([#include <cstddef>
+#include <cstdlib>
bool bulk_alloc(size_t malloc_overhead_attempt, size_t size)
{
@@ -377,12 +377,17 @@
AC_DEFUN(CW_NEED_WORD_ALIGNMENT,
[AC_CACHE_CHECK(if machine needs word alignment, cw_cv_system_needwordalignment,
[CW_TRY_RUN([#include <cstddef>
+#include <cstdlib>
int main(void)
{
size_t* p = reinterpret_cast<size_t*>((char*)malloc(5) + 1);
*p = 0x12345678;
+#ifdef __alpha__ // Works, but still should use alignment.
+ exit(-1);
+#else
exit ((((unsigned long)p & 1UL) && *p == 0x12345678) ? 0 : -1);
+#endif
}],
cw_cv_system_needwordalignment=no,
cw_cv_system_needwordalignment=yes,
@@ -816,9 +821,7 @@
dnl CW_SETUP_RPM_DIRS
dnl Set up rpm directory when on linux and in maintainer-mode
AC_DEFUN(CW_SETUP_RPM_DIRS,
-[SPECCHANGELOG=spec.changelog
-if test "$USE_MAINTAINER_MODE" = yes; then
- AC_SUBST_FILE(SPECCHANGELOG)
+[if test "$USE_MAINTAINER_MODE" = yes; then
LSMFILE="$PACKAGE.lsm"
AC_SUBST(LSMFILE)
SPECFILE="$PACKAGE.spec"
@@ -886,7 +889,13 @@
AC_DEFUN(CW_DO_OPTIONS, [dnl
dnl Choose warning options to use
if test "$USE_MAINTAINER_MODE" = yes; then
-WARNOPTS="-Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Winline -Wwrite-strings -Werror"
+AC_EGREP_CPP(Winline-broken,
+[#if __GNUC__ < 3
+Winline-broken
+#endif
+],
+WARNOPTS="-Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Wwrite-strings -Werror",
+WARNOPTS="-Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Wwrite-strings -Werror -Winline")
else
WARNOPTS=
fi
@@ -904,7 +913,11 @@
AC_SUBST(DEBUGOPTS)
dnl Other options
-EXTRAOPTS=""
+if test "$USE_MAINTAINER_MODE" = yes; then
+EXTRAOPTS="-O"
+else
+EXTRAOPTS="-O"
+fi
AC_SUBST(EXTRAOPTS)
dnl Test options
@@ -929,6 +942,14 @@
unset ac_cv_prog_cxx_works
unset ac_cv_prog_gxx
unset ac_cv_prog_gxx_version
+fi
+if test x"$CC" != "x" -o x"$CPP" != "x"; then
+ unset ac_cv_prog_CC
+ unset ac_cv_prog_CPP
+ unset ac_cv_prog_cc_cross
+ unset ac_cv_prog_g
+ unset ac_cv_prog_cc_works
+ unset ac_cv_prog_gcc
fi
])
Index: src/libcwd/bfd.cc
diff -u src/libcwd/bfd.cc:1.87 src/libcwd/bfd.cc:1.88
--- src/libcwd/bfd.cc:1.87 Sat Sep 22 21:13:50 2001
+++ src/libcwd/bfd.cc Sat Dec 29 20:17:46 2001
@@ -1,6 +1,6 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/bfd.cc,v 1.87 2001/09/23 04:13:50 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/bfd.cc,v 1.88 2001/12/30 04:17:46 libcw Exp $
//
-// Copyright (C) 2000, by
+// Copyright (C) 2000 - 2001, by
//
// Carlo Wood, Run on IRC <ca...@al...>
// RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
@@ -45,15 +45,13 @@
#endif
#include <cstdio> // Needed for vsnprintf.
#include <algorithm>
-#include <libcw/debug.h>
-#include <libcw/bfd.h>
+#include "cwd_debug.h"
+#include "ios_base_Init.h"
#ifdef CWDEBUG_DLOPEN_DEFINED
#undef dlopen
#undef dlclose
#endif
-#include <libcw/exec_prog.h>
-#include <libcw/cwprint.h>
-#include <libcw/demangle.h>
+#include "exec_prog.h"
#ifdef DEBUGUSEGNULIBBFD
#if defined(BFD64) && !BFD_HOST_64BIT_LONG && defined(__GLIBCPP__) && !defined(_GLIBCPP_USE_LONG_LONG)
// libbfd is compiled with 64bit support on a 32bit host, but libstdc++ is not compiled with support
@@ -62,29 +60,60 @@
#error "Incompatible libbfd and libstdc++ (see comments in source code)."
#endif
#else // !DEBUGUSEGNULIBBFD
-#include <libcw/elf32.h>
+#include "elf32.h"
#endif // !DEBUGUSEGNULIBBFD
-#ifdef DEBUGDEBUGBFD
-#include <iomanip>
-#endif
-
-RCSTAG_CC("$Id: bfd.cc,v 1.87 2001/09/23 04:13:50 libcw Exp $")
+#ifdef LIBCWD_THREAD_SAFE
+using libcw::debug::_private_::rwlock_tct;
+using libcw::debug::_private_::mutex_tct;
+using libcw::debug::_private_::object_files_instance;
+using libcw::debug::_private_::dlopen_map_instance;
+#define BFD_ACQUIRE_WRITE_LOCK rwlock_tct<object_files_instance>::wrlock();
+#define BFD_RELEASE_WRITE_LOCK rwlock_tct<object_files_instance>::wrunlock();
+#define BFD_ACQUIRE_READ_LOCK rwlock_tct<object_files_instance>::rdlock();
+#define BFD_RELEASE_READ_LOCK rwlock_tct<object_files_instance>::rdunlock();
+#define BFD_ACQUIRE_READ2WRITE_LOCK rwlock_tct<object_files_instance>::rd2wrlock();
+#define BFD_ACQUIRE_WRITE2READ_LOCK rwlock_tct<object_files_instance>::wr2rdlock();
+#define DLOPEN_MAP_ACQUIRE_LOCK mutex_tct<dlopen_map_instance>::lock();
+#define DLOPEN_MAP_RELEASE_LOCK mutex_tct<dlopen_map_instance>::unlock();
+#else // !LIBCWD_THREAD_SAFE
+#define BFD_ACQUIRE_WRITE_LOCK
+#define BFD_RELEASE_WRITE_LOCK
+#define BFD_ACQUIRE_READ_LOCK
+#define BFD_RELEASE_READ_LOCK
+#define BFD_ACQUIRE_READ2WRITE_LOCK
+#define BFD_ACQUIRE_WRITE2READ_LOCK
+#define DLOPEN_MAP_ACQUIRE_LOCK
+#define DLOPEN_MAP_RELEASE_LOCK
+#endif // !LIBCWD_THREAD_SAFE
-using namespace std;
-
extern char** environ;
namespace libcw {
namespace debug {
+ extern void demangle_symbol(char const* in, _private_::internal_string& out);
+
// New debug channel
namespace channels {
namespace dc {
- channel_ct const bfd("BFD");
+ /** \addtogroup group_default_dc */
+ /* \{ */
+
+ /** The BFD channel. */
+ channel_ct bfd
+#ifndef HIDE_FROM_DOXYGEN
+ ("BFD")
+#endif
+ ;
+
+ /** \} */
}
}
+ using _private_::set_alloc_checking_on;
+ using _private_::set_alloc_checking_off;
+
// Local stuff
namespace cwbfd {
@@ -111,7 +140,7 @@
inline uint32_t bfd_get_file_flags(bfd const* abfd) { return abfd->has_syms() ? HAS_SYMS : 0; }
inline long bfd_get_symtab_upper_bound(bfd* abfd) { return abfd->get_symtab_upper_bound(); }
inline long bfd_canonicalize_symtab(bfd* abfd, asymbol** symbol_table) { return abfd->canonicalize_symtab(symbol_table); }
-inline bool bfd_is_abs_section(asection const* sect) { return (sect == elf32::absolute_section); }
+inline bool bfd_is_abs_section(asection const* sect) { return (sect == elf32::absolute_section_c); }
inline bool bfd_is_com_section(asection const* sect) { return false; }
inline bool bfd_is_ind_section(asection const* sect) { return false; }
inline bool bfd_is_und_section(asection const* sect) { return false; }
@@ -131,14 +160,15 @@
va_end(vl);
if (len >= buf_size)
{
- set_alloc_checking_off();
+ LIBCWD_TSD_DECLARATION
+ set_alloc_checking_off(LIBCWD_TSD);
char* bufp = new char[len + 1];
- set_alloc_checking_on();
+ set_alloc_checking_on(LIBCWD_TSD);
vsnprintf(bufp, sizeof(buf), format, vl);
Dout(dc::bfd, buf);
- set_alloc_checking_off();
+ set_alloc_checking_off(LIBCWD_TSD);
delete [] bufp;
- set_alloc_checking_on();
+ set_alloc_checking_on(LIBCWD_TSD);
}
else
Dout(dc::bfd, buf);
@@ -163,11 +193,17 @@
bool operator()(symbol_ct const& a, symbol_ct const& b) const;
};
+ // cwbfd::
+ typedef std::set<symbol_ct, symbol_key_greater, _private_::object_files_allocator::rebind<symbol_ct>::other> function_symbols_ct;
+
+ // cwbfd::
+ class object_file_ct;
+
// cwbfd::
- typedef set<symbol_ct, symbol_key_greater> function_symbols_ct;
+ typedef std::list<object_file_ct*, _private_::object_files_allocator> object_files_ct;
// cwbfd::
- class object_file_ct {
+ class object_file_ct { // All allocations related to object_file_ct must be `internal'.
private:
bfd* abfd;
void* lbase;
@@ -187,6 +223,10 @@
long get_number_of_symbols(void) const { return number_of_symbols; }
function_symbols_ct& get_function_symbols(void) { return function_symbols; }
function_symbols_ct const& get_function_symbols(void) const { return function_symbols; }
+ private:
+ friend object_files_ct const& NEEDS_READ_LOCK_object_files(void); // Need access to `ST_list_instance'.
+ friend object_files_ct& NEEDS_WRITE_LOCK_object_files(void); // Need access to `ST_list_instance'.
+ static char ST_list_instance[sizeof(object_files_ct)];
};
// cwbfd::
@@ -225,77 +265,86 @@
return symbol_start_addr(a.symbol) >= reinterpret_cast<char const*>(symbol_start_addr(b.symbol)) + symbol_size(b.symbol);
}
- // Global object (but libcwd must stay independent of stuff in libcw/kernel, so we don't use Global<>)
// cwbfd::
- typedef list<object_file_ct*> object_files_ct;
+ char object_file_ct::ST_list_instance[sizeof(object_files_ct)] __attribute__((__aligned__));
+
// cwbfd::
- static char object_files_instance_[sizeof(object_files_ct)] __attribute__((__aligned__));
+ inline object_files_ct const& NEEDS_READ_LOCK_object_files(void)
+ {
+ return *reinterpret_cast<object_files_ct const*>(object_file_ct::ST_list_instance);
+ }
+
// cwbfd::
- object_files_ct& object_files(void) { return *reinterpret_cast<object_files_ct*>(object_files_instance_); }
+ inline object_files_ct& NEEDS_WRITE_LOCK_object_files(void)
+ {
+ return *reinterpret_cast<object_files_ct*>(object_file_ct::ST_list_instance);
+ }
// cwbfd::
- object_file_ct* find_object_file(void const* addr)
+ object_file_ct* NEEDS_READ_LOCK_find_object_file(void const* addr)
{
- object_files_ct::iterator i(object_files().begin());
- for(; i != object_files().end(); ++i)
+ object_files_ct::const_iterator i(NEEDS_READ_LOCK_object_files().begin());
+ for(; i != NEEDS_READ_LOCK_object_files().end(); ++i)
if ((*i)->get_lbase() < addr && (char*)(*i)->get_lbase() + (*i)->size() > addr)
break;
- return (i != object_files().end()) ? (*i) : NULL;
+ return (i != NEEDS_READ_LOCK_object_files().end()) ? (*i) : NULL;
}
// cwbfd::
- object_file_ct* find_object_file(bfd const* abfd)
+ object_file_ct* NEEDS_READ_LOCK_find_object_file(bfd const* abfd)
{
- object_files_ct::iterator i(object_files().begin());
- for(; i != object_files().end(); ++i)
+ object_files_ct::const_iterator i(NEEDS_READ_LOCK_object_files().begin());
+ for(; i != NEEDS_READ_LOCK_object_files().end(); ++i)
if ((*i)->get_bfd() == abfd)
break;
- return (i != object_files().end()) ? (*i) : NULL;
+ return (i != NEEDS_READ_LOCK_object_files().end()) ? (*i) : NULL;
}
// cwbfd::
struct symbol_less {
- bool operator()(asymbol const* a, asymbol const* b) const
- {
- if (a == b)
- return false;
- if (bfd_get_section(a)->vma + a->value < bfd_get_section(b)->vma + b->value)
- return true;
- else if (bfd_get_section(a)->vma + a->value > bfd_get_section(b)->vma + b->value)
- return false;
- else if (!(a->flags & BSF_FUNCTION) && (b->flags & BSF_FUNCTION))
- return true;
- else if ((a->flags & BSF_FUNCTION) && !(b->flags & BSF_FUNCTION))
- return false;
- else if (*a->name == '.')
- return true;
- else if (*b->name == '.')
- return false;
- else if (!strcmp(a->name, "gcc2_compiled."))
- return true;
- else if (!strcmp(b->name, "gcc2_compiled."))
- return false;
- else if (!strcmp(a->name, "force_to_data"))
- return true;
- else if (!strcmp(b->name, "force_to_data"))
- return false;
- else if (!(a->flags & BSF_GLOBAL) && (b->flags & BSF_GLOBAL))
- return true;
- else if ((a->flags & BSF_GLOBAL) && !(b->flags & BSF_GLOBAL))
- return false;
- else if (!(a->flags & BSF_LOCAL) && (b->flags & BSF_LOCAL))
- return true;
- else if ((a->flags & BSF_LOCAL) && !(b->flags & BSF_LOCAL))
- return false;
- else if (!(a->flags & BSF_OBJECT) && (b->flags & BSF_OBJECT))
- return true;
- else if ((a->flags & BSF_OBJECT) && !(b->flags & BSF_OBJECT))
- return false;
- // Lets hope that IF it matters, that a long name is more important ;)
- return (strlen(a->name) < strlen(b->name));
- }
+ bool operator()(asymbol const* a, asymbol const* b) const;
};
+ bool symbol_less::operator()(asymbol const* a, asymbol const* b) const
+ {
+ if (a == b)
+ return false;
+ if (bfd_get_section(a)->vma + a->value < bfd_get_section(b)->vma + b->value)
+ return true;
+ else if (bfd_get_section(a)->vma + a->value > bfd_get_section(b)->vma + b->value)
+ return false;
+ else if (!(a->flags & BSF_FUNCTION) && (b->flags & BSF_FUNCTION))
+ return true;
+ else if ((a->flags & BSF_FUNCTION) && !(b->flags & BSF_FUNCTION))
+ return false;
+ else if (*a->name == '.')
+ return true;
+ else if (*b->name == '.')
+ return false;
+ else if (!strcmp(a->name, "gcc2_compiled."))
+ return true;
+ else if (!strcmp(b->name, "gcc2_compiled."))
+ return false;
+ else if (!strcmp(a->name, "force_to_data"))
+ return true;
+ else if (!strcmp(b->name, "force_to_data"))
+ return false;
+ else if (!(a->flags & BSF_GLOBAL) && (b->flags & BSF_GLOBAL))
+ return true;
+ else if ((a->flags & BSF_GLOBAL) && !(b->flags & BSF_GLOBAL))
+ return false;
+ else if (!(a->flags & BSF_LOCAL) && (b->flags & BSF_LOCAL))
+ return true;
+ else if ((a->flags & BSF_LOCAL) && !(b->flags & BSF_LOCAL))
+ return false;
+ else if (!(a->flags & BSF_OBJECT) && (b->flags & BSF_OBJECT))
+ return true;
+ else if ((a->flags & BSF_OBJECT) && !(b->flags & BSF_OBJECT))
+ return false;
+ // Lets hope that IF it matters, that a long name is more important ;)
+ return (strlen(a->name) < strlen(b->name));
+ }
+
// cwbfd::
void* const unknown_l_addr = (void*)-1;
@@ -303,7 +352,10 @@
object_file_ct::object_file_ct(char const* filename, void* base) : lbase(base)
{
#ifdef DEBUGDEBUGMALLOC
- CWASSERT( libcw::debug::_internal_::internal );
+ {
+ LIBCWD_TSD_DECLARATION
+ LIBCWD_ASSERT( __libcwd_tsd.internal );
+ }
#endif
abfd = bfd_openr(filename, NULL);
@@ -362,7 +414,6 @@
#endif
symbol_table = (asymbol**) malloc(storage_needed);
- AllocTag_dynamic_description(symbol_table, "symbols of " << filename);
number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
#ifdef DEBUGUSEGNULIBBFD
@@ -412,7 +463,9 @@
if (lbase == unknown_l_addr)
{
#ifdef HAVE_DLOPEN
- libcw::debug::_internal_::internal = false;
+ LIBCWD_TSD_DECLARATION
+ int saved_internal = __libcwd_tsd.internal;
+ __libcwd_tsd.internal = 0;
void* handle = ::dlopen(filename, RTLD_LAZY);
if (!handle)
{
@@ -422,13 +475,13 @@
char* val;
if (s_end_vma && (val = (char*)dlsym(handle, "_end"))) // dlsym will fail when _end is a local symbol.
{
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
lbase = val - s_end_vma;
}
else
#ifdef HAVE_LINK_H
{
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
for(link_map* p = _dl_loaded; p; p = p->l_next)
if (!strcmp(p->l_name, filename))
{
@@ -438,9 +491,10 @@
}
#else // !HAVE_LINK_H
{
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
// The following code uses a heuristic approach to guess the start of an object file.
- map<void*, unsigned int> start_values;
+ typedef std::map<void*, unsigned int, std::less<void*>, _private_::internal_allocator::rebind<void*>::other> start_values_map_ct;
+ start_values_map_ct start_values;
unsigned int best_count = 0;
void* best_start = 0;
for (asymbol** s = symbol_table; s <= &symbol_table[number_of_symbols - 1]; ++s)
@@ -450,13 +504,13 @@
asection const* sect = bfd_get_section(*s);
if (sect->name[1] == 't' && !strcmp(sect->name, ".text"))
{
- libcw::debug::_internal_::internal = false;
+ __libcwd_tsd.internal = 0;
void* val = dlsym(handle, (*s)->name);
if (dlerror() == NULL)
{
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
void* start = reinterpret_cast<char*>(val) - (*s)->value - sect->vma;
- pair<map<void*, unsigned int>::iterator, bool> p = start_values.insert(pair<void* const, unsigned int>(start, 0));
+ std::pair<start_values_map_ct::iterator, bool> p = start_values.insert(std::pair<void* const, unsigned int>(start, 0));
if (++(*(p.first)).second > best_count)
{
best_start = start;
@@ -465,7 +519,7 @@
}
}
else
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
}
}
if (best_count < 3)
@@ -475,17 +529,17 @@
symbol_table = NULL;
bfd_close(abfd);
number_of_symbols = 0;
- libcw::debug::_internal_::internal = false;
+ __libcwd_tsd.internal = 0;
::dlclose(handle);
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
return;
}
lbase = best_start;
}
#endif // !HAVE_LINK_H
- libcw::debug::_internal_::internal = false;
+ __libcwd_tsd.internal = 0;
::dlclose(handle);
- libcw::debug::_internal_::internal = true;
+ __libcwd_tsd.internal = saved_internal;
Dout(dc::continued, '(' << lbase << ") ... ");
#else // !HAVE_DLOPEN
DoutFatal(dc::fatal, "Can't determine start of shared library: you will need libdl to be detected by configure.");
@@ -506,7 +560,7 @@
}
// Sort the symbol table in order of start address.
- sort(symbol_table, &symbol_table[number_of_symbols], symbol_less());
+ std::sort(symbol_table, &symbol_table[number_of_symbols], symbol_less());
// Calculate sizes for every symbol
for (int i = 0; i < number_of_symbols - 1; ++i)
@@ -545,15 +599,18 @@
}
if (number_of_symbols > 0)
- object_files().push_back(this);
+ NEEDS_WRITE_LOCK_object_files().push_back(this);
}
// cwbfd::
object_file_ct::~object_file_ct()
{
- list<object_file_ct*>::iterator iter(find(object_files().begin(), object_files().end(), this));
- if (iter != object_files().end())
- object_files().erase(iter);
+#if defined(LIBCWD_THREAD_SAFE) && defined(DEBUGDEBUG)
+ LIBCWD_ASSERT( _private_::is_locked(object_files_instance) );
+#endif
+ object_files_ct::iterator iter(find(NEEDS_WRITE_LOCK_object_files().begin(), NEEDS_WRITE_LOCK_object_files().end(), this));
+ if (iter != NEEDS_WRITE_LOCK_object_files().end())
+ NEEDS_WRITE_LOCK_object_files().erase(iter);
}
// cwbfd::
@@ -596,12 +653,12 @@
}
// cwbfd::
- string* argv0_ptr;
+ _private_::ST_internal_string* ST_argv0_ptr; // MT: Set in `ST_get_full_path_to_executable', used in `ST_decode_ps'.
// cwbfd::
- string const* pidstr_ptr;
+ _private_::ST_internal_string const* ST_pidstr_ptr; // MT: Set in `ST_get_full_path_to_executable', used in `ST_decode_ps'.
// cwbfd::
- int decode_ps(char const* buf, size_t len)
+ int ST_decode_ps(char const* buf, size_t len) // MT: Single Threaded function.
{
static int pid_token = 0;
static int command_token = 0;
@@ -610,7 +667,7 @@
bool found_PID = false;
bool eating_token = false;
size_t current_column = 1;
- string token;
+ _private_::ST_internal_string token;
for (char const* p = buf; p < &buf[len]; ++p, ++current_column)
{
@@ -632,11 +689,11 @@
{
if (*p == ' ' || *p == '\t' || *p == '\n')
{
- if (pid_token == current_token && token == *pidstr_ptr)
+ if (pid_token == current_token && token == *ST_pidstr_ptr)
found_PID = true;
else if (found_PID && (command_token == current_token || current_column >= command_column))
{
- *argv0_ptr = token + '\0';
+ *ST_argv0_ptr = token + '\0';
return 0;
}
else if (pid_token == 0 && token == "PID")
@@ -673,9 +730,9 @@
// program.
//
// cwbfd::
- void get_full_path_to_executable(string& result)
+ void ST_get_full_path_to_executable(_private_::ST_internal_string& result)
{
- string argv0; // Like main()s argv[0], thus must be zero terminated.
+ _private_::ST_internal_string argv0; // Like main()s argv[0], thus must be zero terminated.
char buf[6];
char* p = &buf[5];
*p = 0;
@@ -686,7 +743,7 @@
strcpy(proc_path, "/proc/");
strcpy(proc_path + 6, p);
strcat(proc_path, "/cmdline");
- ifstream proc_file(proc_path);
+ std::ifstream proc_file(proc_path);
if (proc_file)
{
@@ -695,7 +752,7 @@
}
else
{
- string pidstr;
+ _private_::ST_internal_string pidstr;
size_t const max_pidstr = sizeof("65535\0");
char pidstr_buf[max_pidstr];
@@ -714,19 +771,19 @@
argv[2] = p;
argv[3] = NULL;
- argv0_ptr = &argv0; // Ugly way to pass these strings to decode_ps:
- pidstr_ptr = &pidstr; // pidstr is input, argv0 is output.
+ ST_argv0_ptr = &argv0; // Ugly way to pass these ST_internal_strings to ST_decode_ps:
+ ST_pidstr_ptr = &pidstr; // pidstr is input, argv0 is output.
- if (exec_prog(ps_prog, argv, environ, decode_ps) == -1 || argv0.empty())
+ if (ST_exec_prog(ps_prog, argv, environ, ST_decode_ps) == -1 || argv0.empty())
DoutFatal(dc::fatal|error_cf, "Failed to execute \"" << ps_prog << "\"");
}
- if (argv0.find('/') == string::npos)
+ if (argv0.find('/') == _private_::ST_internal_string::npos)
{
- string prog_name(argv0);
- string path_list(getenv("PATH"));
- string::size_type start_pos = 0, end_pos;
- string path;
+ _private_::ST_internal_string prog_name(argv0);
+ _private_::ST_internal_string path_list(getenv("PATH"));
+ _private_::ST_internal_string::size_type start_pos = 0, end_pos;
+ _private_::ST_internal_string path;
struct stat finfo;
prog_name += '\0';
for (;;)
@@ -745,7 +802,7 @@
break;
}
}
- if (end_pos == string::npos)
+ if (end_pos == _private_::ST_internal_string::npos)
break;
start_pos = end_pos + 1;
}
@@ -758,11 +815,11 @@
DoutFatal(dc::fatal|error_cf, "realpath(\"" << argv0.data() << "\", full_path_buf)");
Dout(dc::debug, "Full path to executable is \"" << full_path << "\".");
- result = full_path;
+ result.assign(full_path);
}
// cwbfd::
- static bool initialized = false;
+ static bool WST_initialized = false; // MT: Set here to false, set to `true' once in `cwbfd::ST_init'.
// cwbfd::
struct my_link_map {
@@ -778,10 +835,12 @@
};
// cwbfd::
- vector<my_link_map> shared_libs;
+ typedef _private_::internal_vector<my_link_map> ST_shared_libs_vector_ct;
+ ST_shared_libs_vector_ct ST_shared_libs; // Written to only in `ST_decode_ldd' which is called from
+ // `cwbfd::ST_init' and read from in a later part of `cwbfd::ST_init'.
// cwbfd::
- int decode(char const* buf, size_t len)
+ int ST_decode_ldd(char const* buf, size_t len)
{
for (char const* p = buf; p < &buf[len]; ++p)
if (p[0] == '=' && p[1] == '>' && p[2] == ' ' || p[2] == '\t')
@@ -795,7 +854,7 @@
for (q = p; q < &buf[len] && *q > ' '; ++q);
if (*q == '\n') // This ldd doesn't return an offset (ie, on solaris).
{
- shared_libs.push_back(my_link_map(p, q - p, unknown_l_addr));
+ ST_shared_libs.push_back(my_link_map(p, q - p, unknown_l_addr));
break;
}
for (char const* r = q; r < &buf[len]; ++r)
@@ -803,7 +862,7 @@
{
char* s;
void* addr = reinterpret_cast<void*>(strtol(++r, &s, 0));
- shared_libs.push_back(my_link_map(p, q - p, addr));
+ ST_shared_libs.push_back(my_link_map(p, q - p, addr));
break;
}
break;
@@ -837,7 +896,10 @@
// cwbfd::
object_file_ct* load_object_file(char const* name, void* l_addr)
{
- CWASSERT( libcw::debug::_internal_::internal );
+ {
+ LIBCWD_TSD_DECLARATION
+ LIBCWD_ASSERT( __libcwd_tsd.internal );
+ }
if (l_addr == unknown_l_addr)
Dout(dc::bfd|continued_cf|flush_cf, "Loading debug info from " << name << ' ');
else if (l_addr == 0)
@@ -847,7 +909,7 @@
object_file_ct* object_file = new object_file_ct(name, l_addr);
if (object_file->get_number_of_symbols() > 0)
{
- Dout(dc::finish, "done (" << dec << object_file->get_number_of_symbols() << " symbols)");
+ Dout(dc::finish, "done (" << std::dec << object_file->get_number_of_symbols() << " symbols)");
#ifdef DEBUGDEBUGBFD
dump_object_file_symbols(object_file);
#endif
@@ -862,18 +924,22 @@
}
// cwbfd::
- int init(void)
+ bool ST_init(void)
{
- static bool being_initialized = false;
+ static bool WST_being_initialized = false;
// This should catch it when we call new or malloc while 'internal'.
- if (being_initialized)
- {
-#ifdef DEBUGMALLOC
- libcw::debug::_internal_::internal = false;
+ if (WST_being_initialized)
+ return false;
+ WST_being_initialized = true;
+
+ // MT: We assume this is called before reaching main().
+ // Therefore, no synchronisation is required.
+#if defined(DEBUGDEBUG) && defined(LIBCWD_THREAD_SAFE)
+ if (_private_::WST_multi_threaded)
+ core_dump();
#endif
- DoutFatal(dc::core, "Bug in libcwd: libcw_bfd_init() called twice or recursively entering itself! Please submit a full bug report to li...@al....");
- }
- being_initialized = true;
+
+ LIBCWD_TSD_DECLARATION
#if defined(DEBUGDEBUG) && defined(DEBUGMALLOC)
// First time we get here, this string is intialized - this must be with `internal' off!
@@ -881,13 +947,13 @@
if (!second_time)
{
second_time = true;
- CWASSERT( !libcw::debug::_internal_::internal );
+ LIBCWD_ASSERT( !__libcwd_tsd.internal );
}
#endif
// ****************************************************************************
// Start INTERNAL!
- set_alloc_checking_off();
+ set_alloc_checking_off(LIBCWD_TSD);
#ifdef DEBUGMALLOC
// Initialize the malloc library if not done yet.
@@ -910,22 +976,38 @@
Debug( dc::bfd.on() );
#endif
- // Initialize object files list
- new (object_files_instance_) object_files_ct;
+ // Initialize object files list, we don't really need the
+ // write lock because this function is Single Threaded.
+ new (&NEEDS_WRITE_LOCK_object_files()) object_files_ct;
#ifdef DEBUGUSEGNULIBBFD
bfd_init();
#endif
// Get the full path and name of executable
- struct non_alloc_checking_string_st {
- string* value;
- non_alloc_checking_string_st(void) { value = new string; } // alloc checking already off.
- ~non_alloc_checking_string_st() { set_alloc_checking_off(); delete value; set_alloc_checking_on(); }
+ struct static_internal_string {
+ _private_::ST_internal_string* value;
+ static_internal_string(void)
+ {
+ value = new _private_::ST_internal_string; // alloc checking already off.
+ }
+ ~static_internal_string()
+ {
+ LIBCWD_TSD_DECLARATION
+ set_alloc_checking_off(LIBCWD_TSD);
+#if defined(DEBUGDEBUG) && defined(LIBCWD_THREAD_SAFE)
+ _private_::WST_multi_threaded = false; // `fullpath' is static and will only be destroyed from exit().
+#endif
+ delete value;
+#if defined(DEBUGDEBUG) && defined(LIBCWD_THREAD_SAFE)
+ _private_::WST_multi_threaded = true; // Make sure we catch other global strings (in order to avoid a static destructor ordering fiasco).
+#endif
+ set_alloc_checking_on(LIBCWD_TSD);
+ }
};
- static non_alloc_checking_string_st fullpath; // Must be static because bfd keeps a pointer to its data()
- get_full_path_to_executable(*fullpath.value);
- *fullpath.value += '\0'; // Make string null terminated so we can use data().
+ static static_internal_string fullpath; // Must be static because bfd keeps a pointer to its data()
+ ST_get_full_path_to_executable(*fullpath.value);
+ *fullpath.value += '\0'; // Make string null terminated so we can use data().
#ifdef DEBUGUSEGNULIBBFD
bfd_set_error_program_name(fullpath.value->data() + fullpath.value->find_last_of('/') + 1);
@@ -933,6 +1015,11 @@
#endif
// Load executable
+ // No write lock is really needed because this is a Single Threaded function,
+ // but the sanity checks inside the allocators used in load_object_file()
+ // require the lock to be set. Fortunately is therefore also doesn't hurt
+ // that we keep the lock a long time (during the execution of ldd_prog).
+ BFD_ACQUIRE_WRITE_LOCK
load_object_file(fullpath.value->data(), 0);
// Load all shared objects
@@ -944,9 +1031,9 @@
argv[0] = "ldd";
argv[1] = fullpath.value->data();
argv[2] = NULL;
- exec_prog(ldd_prog, argv, environ, decode);
+ ST_exec_prog(ldd_prog, argv, environ, ST_decode_ldd);
- for(vector<my_link_map>::iterator iter = shared_libs.begin(); iter != shared_libs.end(); ++iter)
+ for(ST_shared_libs_vector_ct::iterator iter = ST_shared_libs.begin(); iter != ST_shared_libs.end(); ++iter)
{
my_link_map* l = &(*iter);
#else
@@ -956,7 +1043,8 @@
if (l->l_addr)
load_object_file(l->l_name, reinterpret_cast<void*>(l->l_addr));
}
- object_files().sort(object_file_greater());
+ NEEDS_WRITE_LOCK_object_files().sort(object_file_greater());
+ BFD_RELEASE_WRITE_LOCK
#ifdef ALWAYS_PRINT_LOADING
if (libcwd_was_off)
@@ -965,9 +1053,9 @@
Debug( dc::bfd.off() );
#endif
- initialized = true;
+ WST_initialized = true; // MT: Safe, this function is Single Threaded.
- set_alloc_checking_on();
+ set_alloc_checking_on(LIBCWD_TSD);
// End INTERNAL!
// ****************************************************************************
@@ -977,19 +1065,21 @@
dump_object_file_symbols(*i);
#endif
- return 0;
+ return true;
}
// cwbfd::
symbol_ct const* pc_symbol(bfd_vma addr, object_file_ct* object_file)
{
- static asymbol dummy_symbol;
- static asection dummy_section;
if (object_file)
{
- // Make symbol_start_addr(&dummy_symbol) and symbol_size(&dummy_symbol) return the correct value
+ asymbol dummy_symbol; // A dummy symbol with size 1 and start `addr',
+ asection dummy_section;
+
+ // Make symbol_start_addr(&dummy_symbol) and symbol_size(&dummy_symbol) return the correct value:
bfd_asymbol_bfd(&dummy_symbol) = object_file->get_bfd();
- dummy_symbol.section = &dummy_section; // Has dummy_section.vma == 0. Use dummy_symbol.value to store (value + vma):
+ dummy_section.vma = 0; // Use a vma of 0 and
+ dummy_symbol.section = &dummy_section; // use dummy_symbol.value to store (value + vma):
dummy_symbol.value = reinterpret_cast<char const*>(addr) - reinterpret_cast<char const*>(object_file->get_lbase());
symbol_size(&dummy_symbol) = 1;
function_symbols_ct::iterator i(object_file->get_function_symbols().find(symbol_ct(&dummy_symbol, true)));
@@ -1008,19 +1098,28 @@
} // namespace cwbfd
+ /** \addtogroup group_locations */
+ /** \{ */
+
char const* const unknown_function_c = "<unknown function>";
- //
- // Find the mangled function name of the address `addr'.
- //
+ /**
+ * \brief Find the mangled function name of the address \a addr.
+ *
+ * \returns the same pointer that is returned by location_ct::mangled_function_name() on success,
+ * otherwise \ref unknown_function_c is returned.
+ */
char const* pc_mangled_function_name(void const* addr)
{
using namespace cwbfd;
- if (!initialized)
- init();
+ if (!WST_initialized // `WST_initialized' is only false when we are still Single Threaded.
+ && !ST_init())
+ return unknown_function_c;
- symbol_ct const* symbol = pc_symbol((bfd_vma)(size_t)addr, find_object_file(addr));
+ BFD_ACQUIRE_READ_LOCK;
+ symbol_ct const* symbol = pc_symbol((bfd_vma)(size_t)addr, NEEDS_READ_LOCK_find_object_file(addr));
+ BFD_RELEASE_READ_LOCK;
if (!symbol)
return unknown_function_c;
@@ -1028,6 +1127,21 @@
return symbol->get_symbol()->name;
}
+ /** \} */ // End of group 'group_locations'.
+
+ struct bfd_location_ct : public location_ct {
+ friend _private_::no_alloc_ostream_ct& operator<<(_private_::no_alloc_ostream_ct& os, bfd_location_ct const& data);
+ };
+
+ _private_::no_alloc_ostream_ct& operator<<(_private_::no_alloc_ostream_ct& os, bfd_location_ct const& location)
+ {
+ if (location.M_filepath)
+ os << location.M_filename << ':' << location.M_line;
+ else
+ os << "<unknown ...
[truncated message content] |