00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef OSL_DIAGNOSE_HXX_INCLUDED
00020 #define OSL_DIAGNOSE_HXX_INCLUDED
00021
00022 #include "sal/config.h"
00023
00024 #include <functional>
00025 #include <typeinfo>
00026
00027 #ifndef HAVE_CXX0X
00028 #define BOOST_NO_0X_HDR_TYPEINDEX
00029 #endif
00030 #include "boost/unordered_set.hpp"
00031 #include "osl/diagnose.h"
00032 #include "osl/interlck.h"
00033 #include "osl/mutex.hxx"
00034 #include "rtl/allocator.hxx"
00035 #include "rtl/instance.hxx"
00036 #include "sal/log.hxx"
00037 #include "sal/saldllapi.h"
00038 #include "sal/types.h"
00039
00041
00042 namespace osl {
00043 namespace detail {
00044
00045 struct ObjectRegistryData;
00046
00047 }
00048 }
00049
00050 extern "C" {
00051
00052 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
00053 char const* pName )
00054 SAL_THROW_EXTERN_C();
00055
00056 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
00057 ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
00058 SAL_THROW_EXTERN_C();
00059
00060 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
00061 ::osl::detail::ObjectRegistryData & rData, void const* pObj )
00062 SAL_THROW_EXTERN_C();
00063
00064 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
00065 ::osl::detail::ObjectRegistryData & rData, void const* pObj )
00066 SAL_THROW_EXTERN_C();
00067
00068
00069
00070 #ifdef __clang__
00071 #pragma clang diagnostic push
00072
00073
00074 #pragma clang diagnostic ignored "-Wunknown-pragmas"
00075 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
00076 #endif
00077
00078 SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
00079 SAL_THROW_EXTERN_C();
00080
00081 #ifdef __clang__
00082 #pragma clang diagnostic pop
00083 #endif
00084
00085 }
00086
00087 namespace osl {
00088
00089 namespace detail {
00090
00091 struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
00092 ::std::size_t operator()( void const* p ) const {
00093 ::std::size_t const d = static_cast< ::std::size_t >(
00094 reinterpret_cast< ::std::ptrdiff_t >(p) );
00095 return d + (d >> 3);
00096 }
00097 };
00098
00099 typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
00100 ::rtl::Allocator<void const*> > VoidPointerSet;
00101
00102 struct ObjectRegistryData {
00103 ObjectRegistryData( ::std::type_info const& rTypeInfo )
00104 : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
00105 m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
00106
00107 char const* const m_pName;
00108 oslInterlockedCount m_nCount;
00109 VoidPointerSet m_addresses;
00110 bool const m_bStoreAddresses;
00111 };
00112
00113 template <typename T>
00114 class ObjectRegistry
00115 {
00116 public:
00117 ObjectRegistry() : m_data( typeid(T) ) {}
00118 ~ObjectRegistry() { checkObjectCount(0); }
00119
00120 bool checkObjectCount( ::std::size_t nExpected ) const {
00121 bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
00122 m_data, nExpected );
00123 if (!bRet && m_data.m_bStoreAddresses) {
00124 MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
00125
00126 VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
00127 VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
00128 for ( ; iPos != iEnd; ++iPos ) {
00129 SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
00130 }
00131 }
00132 return bRet;
00133 }
00134
00135 void registerObject( void const* pObj ) {
00136 osl_detail_ObjectRegistry_registerObject(m_data, pObj);
00137 }
00138
00139 void revokeObject( void const* pObj ) {
00140 osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
00141 }
00142
00143 private:
00144
00145 ObjectRegistry( ObjectRegistry const& );
00146 ObjectRegistry const& operator=( ObjectRegistry const& );
00147
00148 ObjectRegistryData m_data;
00149 };
00150
00151 }
00152
00174 template <typename InheritingClassT>
00175 class DebugBase
00176 {
00177 public:
00178 #if OSL_DEBUG_LEVEL <= 0
00179 static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
00180 #else // OSL_DEBUG_LEVEL > 0
00181
00184 static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
00185 return StaticObjectRegistry::get().checkObjectCount(nExpected);
00186 }
00187
00188 protected:
00189 DebugBase() {
00190 StaticObjectRegistry::get().registerObject( this );
00191 }
00192 ~DebugBase() {
00193 StaticObjectRegistry::get().revokeObject( this );
00194 }
00195
00196 private:
00197 struct StaticObjectRegistry
00198 : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
00199 StaticObjectRegistry> {};
00200 #endif
00201 };
00202
00203 }
00204
00206
00207 #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
00208
00209