[PATCH] Slightly better way to __USE_MALLOC
Brad Spencer
spencer@infointeractive.com
Tue Oct 8 14:11:00 GMT 2002
Hi, all.. When debugging recently, I found it necessary to use a
__USE_MALLOCed version of the library. Having followed the
discussions about this topic a while back, I was aware that doing this
is somewhat clumsy and (perhaps) error-prone. After I had actually
rebuilt the library (and found my bug quite quickly with "mpatrol",
BTW), I decided that it might be useful to have a malloc-using version
of the library "hanging around". Since "a patch would be
appreciated", here's one, albeit not a perfect one.
I'm no configure wizard, but I think I managed to hack together
a patch that creates a new "--enable-use-malloc=yes" feature. I
changed __USE_MALLOC to be _GLIBCPP_USE_MALLOC in the process, and
eliminated the "#if defined" check in c++config because I think the
linker will always notice if you mismatch allocation mechanisms
between library and application.
To test this, I wrote a small program (before I renamed the macro):
#include <vector>
#include <iostream>
int
main()
{
std::vector<int> x;
#ifdef __USE_MALLOC
std::cout << "malloc use" << std::endl;
#else
std::cout << "not malloc use" << std::endl;
#endif // __USE_MALLOC
return 0;
}
Then, by compiling it four different ways, it seems like only the
valid combinations will link:
$ g++ -Wall -o foo1 foo.cc # Ok
$ g++ -Wall -D__USE_MALLOC -L$malloc_dir -o foo2 foo.cc # Ok
$ g++ -Wall -D__USE_MALLOC -o foo3 foo.cc # Errors; good
/tmp/ccHFHnA5.o: In function `std::__simple_alloc<int,
std::__malloc_alloc_template<(int)0> >::deallocate(int*, unsigned)':
/tmp/ccHFHnA5.o(.gnu.linkonce.t._ZNSt14__simple_allocIiSt23__malloc_alloc_templateILi0EEE10deallocateEPij+0x1d):
undefined reference to
`std::__malloc_alloc_template<(int)0>::deallocate(void*, unsigned)'
collect2: ld returned 1 exit status
$ g++ -Wall -L$malloc_dir -o foo4 foo.cc # Errors; good
/tmp/ccjemhTF.o: In function `std::__simple_alloc<int,
std::__default_alloc_template<(bool)1, (int)0> >::deallocate(int*,
unsigned)':
/tmp/ccjemhTF.o(.gnu.linkonce.t._ZNSt14__simple_allocIiSt24__default_alloc_templateILb1ELi0EEE10deallocateEPij+0x1d):
undefined reference to `std::__default_alloc_template<(bool)1,
(int)0>::deallocate(void*, unsigned)'
collect2: ld returned 1 exit status
Granted, the diagnostic is far from clear, but it does prevent use.
Perhaps a symbol named "__library_not_built_with_use_malloc" would
help? :)
I plan to use this with my build system to let me do something like
g++ -D_GLIBCPP_USE_MALLOC -L$prefix/.../lib/debug
by placing a "use-malloc"-built version of the library in the debug
directory inside the compiler's installation. Someone more familiar
with configure could probably make this happen automatically (by
building and installing the library twice) when --enable-use-malloc
was enabled (or perhaps set to "as-alternate" or something).
Caveat: I've likely patched at least one automatically generated file
:( in the diff I have attached. Hopefully someone will point out if I
have. But I did learn how to write a change log :) This diff is
against the gcc-3.2 release version of libstdc++-v3.
2002-10-08 Brad Spencer <spencer@infointeractive.com>
* acconfig.h, acinclude.m4, config.h.in, configure.in,
include/backward/alloc.h, include/bits/c++config,
include/bits/stl_alloc.h, src/stl-inst.cc: Changed
__USE_MALLOC to _GLIBCPP_USE_MALLOC and added
--enable-use-malloc to configure.
--
------------------------------------------------------------------
Brad Spencer - spencer@infointeractive.com - "It's quite nice..."
Systems Architect | InfoInterActive Corp. | A Canadian AOL Company
-------------- next part --------------
*** ./acconfig.h Fri Dec 14 17:06:32 2001
--- ../../../gcc-3.2/libstdc++-v3/./acconfig.h Fri Oct 4 18:08:00 2002
***************
*** 37,42 ****
--- 37,45 ----
// Define to use concept checking code from the boost libraries.
#undef _GLIBCPP_CONCEPT_CHECKS
+ // Define to use the malloc-based allocator instead pool-based one
+ #undef _GLIBCPP_USE_MALLOC
+
// Define if you have the atan2f function.
#undef _GLIBCPP_HAVE_ATAN2F
*** ./acinclude.m4 Wed Jul 3 19:47:34 2002
--- ../../../gcc-3.2/libstdc++-v3/./acinclude.m4 Fri Oct 4 18:08:25 2002
*************** fi
*** 2089,2094 ****
--- 2089,2123 ----
dnl
+ dnl Check for whether the _GLIBCPP_USE_MALLOC macro should be defined and thus
+ dnl the library should be built in without the default allocator.
+ dnl
+ dnl GLIBCPP_ENABLE_USE_MALLOC
+ dnl --enable-use-malloc turns them on.
+ dnl --disable-use-malloc leaves them off.
+ dnl + Usage: GLIBCPP_ENABLE_USE_MALLOC[(DEFAULT)]
+ dnl Where DEFAULT is either `yes' or `no'. If ommitted, it
+ dnl defaults to `no'.
+ AC_DEFUN(GLIBCPP_ENABLE_USE_MALLOC, [dnl
+ define([GLIBCPP_ENABLE_USE_MALLOC_DEFAULT], ifelse($1, yes, yes, no))dnl
+ AC_ARG_ENABLE(use-malloc,
+ changequote(<<, >>)dnl
+ << --enable-use-malloc use the slower malloc-based allocator [default=>>GLIBCPP_ENABLE_CONCEPT_CHECKS_DEFAULT],
+ changequote([, ])dnl
+ [case "$enableval" in
+ yes) enable_use_malloc=yes ;;
+ no) enable_use_malloc=no ;;
+ *) AC_MSG_ERROR([Unknown argument to enable/disable malloc allocator]) ;;
+ esac],
+ enable_use_malloc=GLIBCPP_ENABLE_USE_MALLOC_DEFAULT)dnl
+ dnl Option parsed, now set things appropriately
+ if test x"$enable_use_malloc" = xyes; then
+ AC_DEFINE(_GLIBCPP_USE_MALLOC)
+ fi
+ ])
+
+
+ dnl
dnl Add version tags to symbols in shared library (or not), additionally
dnl marking other symbols as private/local (or not).
dnl
*** ./config.h.in Mon May 27 12:01:29 2002
--- ../../../gcc-3.2/libstdc++-v3/./config.h.in Fri Oct 4 18:08:05 2002
***************
*** 24,29 ****
--- 24,32 ----
// Define to use concept checking code from the boost libraries.
#undef _GLIBCPP_CONCEPT_CHECKS
+ // Define to use the malloc-based allocator instead pool-based one
+ #undef _GLIBCPP_USE_MALLOC
+
// Define if mbstate_t exists in wchar.h.
#undef HAVE_MBSTATE_T
*** ./configure.in Tue Oct 8 12:18:19 2002
--- ../../../gcc-3.2/libstdc++-v3/./configure.in Fri Oct 4 18:03:50 2002
*************** GLIBCPP_ENABLE_CXX_FLAGS([none])
*** 56,61 ****
--- 56,62 ----
GLIBCPP_ENABLE_SJLJ_EXCEPTIONS
GLIBCPP_ENABLE_LIBUNWIND_EXCEPTIONS
GLIBCPP_ENABLE_CONCEPT_CHECKS
+ GLIBCPP_ENABLE_USE_MALLOC
# Check for headers necessary for libsupc++ using dyn-string.c/cxa_demangle.c
AC_CHECK_HEADERS(string.h stdlib.h)
*** ./include/backward/alloc.h Thu Dec 6 16:29:30 2001
--- ../../../gcc-3.2/libstdc++-v3/./include/backward/alloc.h Fri Oct 4 18:01:48 2002
*************** using std::__debug_alloc;
*** 53,59 ****
using std::__alloc;
using std::__single_client_alloc;
using std::allocator;
! #ifdef __USE_MALLOC
using std::malloc_alloc;
#else
using std::__default_alloc_template;
--- 53,59 ----
using std::__alloc;
using std::__single_client_alloc;
using std::allocator;
! #ifdef _GLIBCPP_USE_MALLOC
using std::malloc_alloc;
#else
using std::__default_alloc_template;
*** ./include/bits/c++config Wed Aug 14 04:16:24 2002
--- ../../../gcc-3.2/libstdc++-v3/./include/bits/c++config Sat Oct 5 13:28:19 2002
***************
*** 69,80 ****
// that threads are properly configured on your platform before
// assigning blame to the STL container-memory allocator. After doing
// so, please report any possible issues to libstdc++@gcc.gnu.org .
! // Do not define __USE_MALLOC on the command line. Enforce it here:
! #ifdef __USE_MALLOC
! #error __USE_MALLOC should only be defined within \
! libstdc++-v3/include/bits/c++config before full recompilation of the library.
! #endif
! // Define __USE_MALLOC after this point in the file in order to aid debugging
// or globally change allocation policy. This breaks the ABI, thus
// completely recompile the library. A patch to better support
// changing the global allocator policy would be probably be accepted.
--- 69,77 ----
// that threads are properly configured on your platform before
// assigning blame to the STL container-memory allocator. After doing
// so, please report any possible issues to libstdc++@gcc.gnu.org .
! // Do not define _GLIBCPP_USE_MALLOC on the command line.
! // It must be defined at library-build time.
! // Configure the library to use malloc in order to aid debugging
// or globally change allocation policy. This breaks the ABI, thus
// completely recompile the library. A patch to better support
// changing the global allocator policy would be probably be accepted.
*** ./include/bits/stl_alloc.h Fri Apr 19 05:28:15 2002
--- ../../../gcc-3.2/libstdc++-v3/./include/bits/stl_alloc.h Fri Oct 4 18:01:48 2002
*************** namespace std
*** 199,205 ****
// Determines the underlying allocator choice for the node allocator.
! #ifdef __USE_MALLOC
typedef __malloc_alloc_template<0> __mem_interface;
#else
typedef __new_alloc __mem_interface;
--- 199,205 ----
// Determines the underlying allocator choice for the node allocator.
! #ifdef _GLIBCPP_USE_MALLOC
typedef __malloc_alloc_template<0> __mem_interface;
#else
typedef __new_alloc __mem_interface;
*************** namespace std
*** 284,290 ****
};
! #ifdef __USE_MALLOC
typedef __mem_interface __alloc;
typedef __mem_interface __single_client_alloc;
--- 284,290 ----
};
! #ifdef _GLIBCPP_USE_MALLOC
typedef __mem_interface __alloc;
typedef __mem_interface __single_client_alloc;
*************** template<bool __threads, int __inst>
*** 591,597 ****
typedef __default_alloc_template<false, 0> __single_client_alloc;
! #endif /* ! __USE_MALLOC */
/**
--- 591,597 ----
typedef __default_alloc_template<false, 0> __single_client_alloc;
! #endif /* ! _GLIBCPP_USE_MALLOC */
/**
*************** template<bool __threads, int __inst>
*** 599,605 ****
* "SGI" style. (See comments at the top of stl_alloc.h.)
*
* The underlying allocator behaves as follows.
! * - if __USE_MALLOC then
* - thread safety depends on malloc and is entirely out of our hands
* - __malloc_alloc_template is used for memory requests
* - else (the default)
--- 599,605 ----
* "SGI" style. (See comments at the top of stl_alloc.h.)
*
* The underlying allocator behaves as follows.
! * - if _GLIBCPP_USE_MALLOC then
* - thread safety depends on malloc and is entirely out of our hands
* - __malloc_alloc_template is used for memory requests
* - else (the default)
*************** struct _Alloc_traits<_Tp, __malloc_alloc
*** 867,873 ****
typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
};
! #ifndef __USE_MALLOC
template <class _Tp, bool __threads, int __inst>
struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
{
--- 867,873 ----
typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
};
! #ifndef _GLIBCPP_USE_MALLOC
template <class _Tp, bool __threads, int __inst>
struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
{
*************** struct _Alloc_traits<_Tp,
*** 899,905 ****
typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
};
! #ifndef __USE_MALLOC
template <class _Tp, class _Tp1, bool __thr, int __inst>
struct _Alloc_traits<_Tp,
__allocator<_Tp1,
--- 899,905 ----
typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
};
! #ifndef _GLIBCPP_USE_MALLOC
template <class _Tp, class _Tp1, bool __thr, int __inst>
struct _Alloc_traits<_Tp,
__allocator<_Tp1,
*************** struct _Alloc_traits<_Tp, __allocator<_T
*** 927,933 ****
// NB: This syntax is a GNU extension.
extern template class allocator<char>;
extern template class allocator<wchar_t>;
! #ifdef __USE_MALLOC
extern template class __malloc_alloc_template<0>;
#else
extern template class __default_alloc_template<true, 0>;
--- 927,933 ----
// NB: This syntax is a GNU extension.
extern template class allocator<char>;
extern template class allocator<wchar_t>;
! #ifdef _GLIBCPP_USE_MALLOC
extern template class __malloc_alloc_template<0>;
#else
extern template class __default_alloc_template<true, 0>;
*** ./src/stl-inst.cc Fri Apr 19 05:28:18 2002
--- ../../../gcc-3.2/libstdc++-v3/./src/stl-inst.cc Sat Oct 5 13:38:02 2002
*************** namespace std
*** 39,45 ****
template class allocator<char>;
template class allocator<wchar_t>;
! #ifdef __USE_MALLOC
template class __malloc_alloc_template<0>;
#else
template class __default_alloc_template<true, 0>;
--- 39,47 ----
template class allocator<char>;
template class allocator<wchar_t>;
! // This will cause linker errors if the user tries to mismatch
! // an allocator-using program and library. That is good.
! #ifdef _GLIBCPP_USE_MALLOC
template class __malloc_alloc_template<0>;
#else
template class __default_alloc_template<true, 0>;
More information about the Libstdc++
mailing list