LCOV - code coverage report
Current view: top level - solver/unxlngi6.pro/inc/osl - diagnose.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 4 25.0 %
Date: 2012-08-25 Functions: 7 11 63.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : #ifndef OSL_DIAGNOSE_HXX_INCLUDED
      29                 :            : #define OSL_DIAGNOSE_HXX_INCLUDED
      30                 :            : 
      31                 :            : #include "sal/config.h"
      32                 :            : 
      33                 :            : #include <functional>
      34                 :            : #include <typeinfo>
      35                 :            : 
      36                 :            : #include "boost/unordered_set.hpp"
      37                 :            : #include "osl/diagnose.h"
      38                 :            : #include "osl/interlck.h"
      39                 :            : #include "osl/mutex.hxx"
      40                 :            : #include "rtl/allocator.hxx"
      41                 :            : #include "rtl/instance.hxx"
      42                 :            : #include "sal/log.hxx"
      43                 :            : #include "sal/types.h"
      44                 :            : 
      45                 :            : /// @cond INTERNAL
      46                 :            : 
      47                 :            : namespace osl {
      48                 :            : namespace detail {
      49                 :            : 
      50                 :            : struct ObjectRegistryData;
      51                 :            : 
      52                 :            : } // namespace detail
      53                 :            : } // namespace osl
      54                 :            : 
      55                 :            : extern "C" {
      56                 :            : 
      57                 :            : SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
      58                 :            :         char const* pName )
      59                 :            :     SAL_THROW_EXTERN_C();
      60                 :            : 
      61                 :            : SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
      62                 :            :     ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
      63                 :            :     SAL_THROW_EXTERN_C();
      64                 :            : 
      65                 :            : SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
      66                 :            :     ::osl::detail::ObjectRegistryData & rData, void const* pObj )
      67                 :            :     SAL_THROW_EXTERN_C();
      68                 :            : 
      69                 :            : SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
      70                 :            :     ::osl::detail::ObjectRegistryData & rData, void const* pObj )
      71                 :            :     SAL_THROW_EXTERN_C();
      72                 :            : 
      73                 :            : // These functions presumably should not be extern "C", but changing
      74                 :            : // that would break binary compatibility.
      75                 :            : #if SUPD < 400
      76                 :            : #ifdef __clang__
      77                 :            : #pragma clang diagnostic push
      78                 :            : // Guard against slightly older clang versions that don't have
      79                 :            : // -Wreturn-type-c-linkage...
      80                 :            : #pragma clang diagnostic ignored "-Wunknown-pragmas"
      81                 :            : #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
      82                 :            : #endif
      83                 :            : #endif
      84                 :            : SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
      85                 :            :     SAL_THROW_EXTERN_C();
      86                 :            : #if SUPD < 400
      87                 :            : #ifdef __clang__
      88                 :            : #pragma clang diagnostic pop
      89                 :            : #endif
      90                 :            : #endif
      91                 :            : 
      92                 :            : } // extern "C"
      93                 :            : 
      94                 :            : namespace osl {
      95                 :            : 
      96                 :            : namespace detail {
      97                 :            : 
      98                 :            : struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
      99                 :          0 :     ::std::size_t operator()( void const* p ) const {
     100                 :            :         ::std::size_t const d = static_cast< ::std::size_t >(
     101                 :          0 :             reinterpret_cast< ::std::ptrdiff_t >(p) );
     102                 :          0 :         return d + (d >> 3);
     103                 :            :     }
     104                 :            : };
     105                 :            : 
     106                 :            : typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
     107                 :            :                         ::rtl::Allocator<void const*> > VoidPointerSet;
     108                 :            : 
     109                 :            : struct ObjectRegistryData {
     110                 :            :     ObjectRegistryData( ::std::type_info const& rTypeInfo )
     111                 :            :         : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
     112                 :            :           m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
     113                 :            : 
     114                 :            :     char const* const m_pName;
     115                 :            :     oslInterlockedCount m_nCount;
     116                 :            :     VoidPointerSet m_addresses;
     117                 :            :     bool const m_bStoreAddresses;
     118                 :            : };
     119                 :            : 
     120                 :            : template <typename T>
     121                 :            : class ObjectRegistry
     122                 :            : {
     123                 :            : public:
     124                 :            :     ObjectRegistry() : m_data( typeid(T) ) {}
     125                 :            :     ~ObjectRegistry() { checkObjectCount(0); }
     126                 :            : 
     127                 :            :     bool checkObjectCount( ::std::size_t nExpected ) const {
     128                 :            :         bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
     129                 :            :             m_data, nExpected );
     130                 :            :         if (!bRet && m_data.m_bStoreAddresses) {
     131                 :            :             MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
     132                 :            :             // following loop is for debugging purposes, iterating over map:
     133                 :            :             VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
     134                 :            :             VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
     135                 :            :             for ( ; iPos != iEnd; ++iPos ) {
     136                 :            :                 SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
     137                 :            :             }
     138                 :            :         }
     139                 :            :         return bRet;
     140                 :            :     }
     141                 :            : 
     142                 :            :     void registerObject( void const* pObj ) {
     143                 :            :         osl_detail_ObjectRegistry_registerObject(m_data, pObj);
     144                 :            :     }
     145                 :            : 
     146                 :            :     void revokeObject( void const* pObj ) {
     147                 :            :         osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
     148                 :            :     }
     149                 :            : 
     150                 :            : private:
     151                 :            :     // not impl:
     152                 :            :     ObjectRegistry( ObjectRegistry const& );
     153                 :            :     ObjectRegistry const& operator=( ObjectRegistry const& );
     154                 :            : 
     155                 :            :     ObjectRegistryData m_data;
     156                 :            : };
     157                 :            : 
     158                 :            : } // namespace detail
     159                 :            : 
     160                 :            : /** Helper class which indicates leaking object(s) of a particular class in
     161                 :            :     non-pro builds; use e.g.
     162                 :            : 
     163                 :            :     <pre>
     164                 :            :     class MyClass : private osl::DebugBase<MyClass> {...};
     165                 :            :     </pre>
     166                 :            : 
     167                 :            :     Using the environment variable
     168                 :            : 
     169                 :            :     OSL_DEBUGBASE_STORE_ADDRESSES=MyClass;YourClass;...
     170                 :            : 
     171                 :            :     you can specify a ';'-separated list of strings matching to class names
     172                 :            :     (or "all" for all classes), for which DebugBase stores addresses to created
     173                 :            :     objects instead of just counting them.  This enables you to iterate over
     174                 :            :     leaking objects in your debugger.
     175                 :            : 
     176                 :            :     @tparam InheritingClassT binds the template instance to that class
     177                 :            :     @attention Use at own risk.
     178                 :            :               For now this is just public (yet unpublished) API and may change
     179                 :            :               in the future!
     180                 :            : */
     181                 :            : template <typename InheritingClassT>
     182                 :      96335 : class DebugBase
     183                 :            : {
     184                 :            : public:
     185                 :            : #if OSL_DEBUG_LEVEL <= 0
     186                 :            :     static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
     187                 :            : #else // OSL_DEBUG_LEVEL > 0
     188                 :            :     /** @return whether the expected number of objects is alive,
     189                 :            :                 else this function SAL_WARNs
     190                 :            :     */
     191                 :            :     static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
     192                 :            :         return StaticObjectRegistry::get().checkObjectCount(nExpected);
     193                 :            :     }
     194                 :            : 
     195                 :            : protected:
     196                 :            :     DebugBase() {
     197                 :            :         StaticObjectRegistry::get().registerObject( this );
     198                 :            :     }
     199                 :            :     ~DebugBase() {
     200                 :            :         StaticObjectRegistry::get().revokeObject( this );
     201                 :            :     }
     202                 :            : 
     203                 :            : private:
     204                 :            :     struct StaticObjectRegistry
     205                 :            :         : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
     206                 :            :                         StaticObjectRegistry> {};
     207                 :            : #endif
     208                 :            : };
     209                 :            : 
     210                 :            : } // namespace osl
     211                 :            : 
     212                 :            : /// @endcond
     213                 :            : 
     214                 :            : #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
     215                 :            : 
     216                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10