187d2adbcSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 387d2adbcSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 487d2adbcSAndrew Rist * or more contributor license agreements. See the NOTICE file 587d2adbcSAndrew Rist * distributed with this work for additional information 687d2adbcSAndrew Rist * regarding copyright ownership. The ASF licenses this file 787d2adbcSAndrew Rist * to you under the Apache License, Version 2.0 (the 887d2adbcSAndrew Rist * "License"); you may not use this file except in compliance 987d2adbcSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 1187d2adbcSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 1387d2adbcSAndrew Rist * Unless required by applicable law or agreed to in writing, 1487d2adbcSAndrew Rist * software distributed under the License is distributed on an 1587d2adbcSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1687d2adbcSAndrew Rist * KIND, either express or implied. See the License for the 1787d2adbcSAndrew Rist * specific language governing permissions and limitations 1887d2adbcSAndrew Rist * under the License. 19cdf0e10cSrcweir * 2087d2adbcSAndrew Rist *************************************************************/ 2187d2adbcSAndrew Rist 2287d2adbcSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_sal.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "rtl/strbuf.hxx" 28cdf0e10cSrcweir #include "rtl/string.hxx" 29cdf0e10cSrcweir #include "rtl/ustring.hxx" 30cdf0e10cSrcweir #include "osl/process.h" 31cdf0e10cSrcweir #include "osl/diagnose.hxx" 32cdf0e10cSrcweir #include "boost/bind.hpp" 33cdf0e10cSrcweir #include <vector> 34*82c0ddf2SHerbert Dürr #include <algorithm> 35cdf0e10cSrcweir 36cdf0e10cSrcweir // define own ones, independent of OSL_DEBUG_LEVEL: 37cdf0e10cSrcweir #define DEBUGBASE_ENSURE_(c, f, l, m) \ 38cdf0e10cSrcweir do \ 39cdf0e10cSrcweir { \ 40cdf0e10cSrcweir if (!(c) && _OSL_GLOBAL osl_assertFailedLine(f, l, m)) \ 41cdf0e10cSrcweir _OSL_GLOBAL osl_breakDebug(); \ 42cdf0e10cSrcweir } while (0) 43cdf0e10cSrcweir #define DEBUGBASE_ENSURE(c, m) DEBUGBASE_ENSURE_(c, OSL_THIS_FILE, __LINE__, m) 44cdf0e10cSrcweir 45cdf0e10cSrcweir namespace { 46cdf0e10cSrcweir 47cdf0e10cSrcweir typedef std::vector<rtl::OString, rtl::Allocator<rtl::OString> > OStringVec; 48cdf0e10cSrcweir 49cdf0e10cSrcweir struct StaticDebugBaseAddressFilter 50cdf0e10cSrcweir : rtl::StaticWithInit<OStringVec const, StaticDebugBaseAddressFilter> { 51cdf0e10cSrcweir OStringVec const operator()() const { 52cdf0e10cSrcweir OStringVec vec; 53cdf0e10cSrcweir rtl_uString * pStr = 0; 54cdf0e10cSrcweir rtl::OUString const name( 55cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("OSL_DEBUGBASE_STORE_ADDRESSES") ); 56cdf0e10cSrcweir if (osl_getEnvironment( name.pData, &pStr ) == osl_Process_E_None) { 57cdf0e10cSrcweir rtl::OUString const str(pStr); 58cdf0e10cSrcweir rtl_uString_release(pStr); 59cdf0e10cSrcweir sal_Int32 nIndex = 0; 60cdf0e10cSrcweir do { 61cdf0e10cSrcweir vec.push_back( rtl::OUStringToOString( 62cdf0e10cSrcweir str.getToken( 0, ';', nIndex ), 63cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ) ); 64cdf0e10cSrcweir } 65cdf0e10cSrcweir while (nIndex >= 0); 66cdf0e10cSrcweir } 67cdf0e10cSrcweir return vec; 68cdf0e10cSrcweir } 69cdf0e10cSrcweir }; 70cdf0e10cSrcweir 71cdf0e10cSrcweir inline bool isSubStr( char const* pStr, rtl::OString const& subStr ) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir return rtl_str_indexOfStr( pStr, subStr.getStr() ) >= 0; 74cdf0e10cSrcweir } 75cdf0e10cSrcweir 76cdf0e10cSrcweir struct DebugBaseMutex : ::rtl::Static<osl::Mutex, DebugBaseMutex> {}; 77cdf0e10cSrcweir 78cdf0e10cSrcweir } // anon namespace 79cdf0e10cSrcweir 80cdf0e10cSrcweir extern "C" { 81cdf0e10cSrcweir 82cdf0e10cSrcweir osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex() 83cdf0e10cSrcweir SAL_THROW_EXTERN_C() 84cdf0e10cSrcweir { 85cdf0e10cSrcweir return DebugBaseMutex::get(); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir 88cdf0e10cSrcweir bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses( char const* pName ) 89cdf0e10cSrcweir SAL_THROW_EXTERN_C() 90cdf0e10cSrcweir { 91cdf0e10cSrcweir OStringVec const& rVec = StaticDebugBaseAddressFilter::get(); 92cdf0e10cSrcweir if (rVec.empty()) 93cdf0e10cSrcweir return false; 94cdf0e10cSrcweir // check for "all": 95cdf0e10cSrcweir rtl::OString const& rFirst = rVec[0]; 96cdf0e10cSrcweir if (rtl_str_compare_WithLength( rFirst.getStr(), rFirst.getLength(), 97cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("all") ) == 0) 98cdf0e10cSrcweir return true; 99cdf0e10cSrcweir OStringVec::const_iterator const iEnd( rVec.end() ); 100cdf0e10cSrcweir return std::find_if( rVec.begin(), iEnd, 101cdf0e10cSrcweir boost::bind( &isSubStr, pName, _1 ) ) != iEnd; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount( 105cdf0e10cSrcweir osl::detail::ObjectRegistryData const& rData, std::size_t nExpected ) 106cdf0e10cSrcweir SAL_THROW_EXTERN_C() 107cdf0e10cSrcweir { 108cdf0e10cSrcweir std::size_t nSize; 109cdf0e10cSrcweir if (rData.m_bStoreAddresses) 110cdf0e10cSrcweir nSize = rData.m_addresses.size(); 111cdf0e10cSrcweir else 112cdf0e10cSrcweir nSize = static_cast<std::size_t>(rData.m_nCount); 113cdf0e10cSrcweir 114cdf0e10cSrcweir bool const bRet = (nSize == nExpected); 115cdf0e10cSrcweir if (! bRet) { 116cdf0e10cSrcweir rtl::OStringBuffer buf; 117cdf0e10cSrcweir buf.append( RTL_CONSTASCII_STRINGPARAM("unexpected number of ") ); 118cdf0e10cSrcweir buf.append( rData.m_pName ); 119cdf0e10cSrcweir buf.append( RTL_CONSTASCII_STRINGPARAM(": ") ); 120cdf0e10cSrcweir buf.append( static_cast<sal_Int64>(nSize) ); 121cdf0e10cSrcweir DEBUGBASE_ENSURE( false, buf.makeStringAndClear().getStr() ); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir return bRet; 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir void SAL_CALL osl_detail_ObjectRegistry_registerObject( 127cdf0e10cSrcweir osl::detail::ObjectRegistryData & rData, void const* pObj ) 128cdf0e10cSrcweir SAL_THROW_EXTERN_C() 129cdf0e10cSrcweir { 130cdf0e10cSrcweir if (rData.m_bStoreAddresses) { 131cdf0e10cSrcweir osl::MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() ); 132cdf0e10cSrcweir std::pair<osl::detail::VoidPointerSet::iterator, bool> const insertion( 133cdf0e10cSrcweir rData.m_addresses.insert(pObj) ); 134cdf0e10cSrcweir DEBUGBASE_ENSURE( insertion.second, "### insertion failed!?" ); 135cdf0e10cSrcweir static_cast<void>(insertion); 136cdf0e10cSrcweir } 137cdf0e10cSrcweir else { 138cdf0e10cSrcweir osl_incrementInterlockedCount(&rData.m_nCount); 139cdf0e10cSrcweir } 140cdf0e10cSrcweir } 141cdf0e10cSrcweir 142cdf0e10cSrcweir void SAL_CALL osl_detail_ObjectRegistry_revokeObject( 143cdf0e10cSrcweir osl::detail::ObjectRegistryData & rData, void const* pObj ) 144cdf0e10cSrcweir SAL_THROW_EXTERN_C() 145cdf0e10cSrcweir { 146cdf0e10cSrcweir if (rData.m_bStoreAddresses) { 147cdf0e10cSrcweir osl::MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() ); 148cdf0e10cSrcweir std::size_t const n = rData.m_addresses.erase(pObj); 149cdf0e10cSrcweir DEBUGBASE_ENSURE( n == 1, "erased more than 1 entry!?" ); 150cdf0e10cSrcweir static_cast<void>(n); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir else { 153cdf0e10cSrcweir osl_decrementInterlockedCount(&rData.m_nCount); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir } // extern "C" 158cdf0e10cSrcweir 159