LCOV - code coverage report
Current view: top level - tools/source/debug - debug.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 3 0.0 %
Date: 2014-04-14 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #if defined (UNX) || defined (__GNUC__)
      21             : #include <unistd.h>
      22             : #else
      23             : #include <direct.h>
      24             : #endif
      25             : 
      26             : #include <errno.h>
      27             : #include <time.h>
      28             : #include <cstdarg>
      29             : #include <stdlib.h>
      30             : #include <string.h>
      31             : #include <stdio.h>
      32             : 
      33             : #if defined ( WNT )
      34             : #include <windows.h>
      35             : #endif
      36             : 
      37             : #include "com/sun/star/task/ErrorCodeIOException.hpp"
      38             : #include <tools/debug.hxx>
      39             : #include <rtl/string.h>
      40             : #include <sal/log.hxx>
      41             : #include <sal/macros.h>
      42             : 
      43             : #include <vector>
      44             : 
      45             : #include <osl/diagnose.h>
      46             : #include <tools/diagnose_ex.h>
      47             : 
      48             : #ifdef DBG_UTIL
      49             : 
      50             : struct DebugData
      51             : {
      52             :     DbgData                 aDbgData;
      53             :     bool                    bInit;
      54             :     DbgTestSolarMutexProc   pDbgTestSolarMutex;
      55             : 
      56             :     DebugData()
      57             :         :bInit( false )
      58             :         ,pDbgTestSolarMutex( NULL )
      59             :     {
      60             :         aDbgData.nTestFlags = DBG_TEST_RESOURCE;
      61             :         aDbgData.aDbgWinState[0] = 0;
      62             :     }
      63             : };
      64             : 
      65             : static DebugData aDebugData;
      66             : 
      67             : #define FILE_LINEEND    "\n"
      68             : 
      69             : typedef FILE*       FILETYPE;
      70             : #define FileOpen    fopen
      71             : #define FileRead    fread
      72             : #define FilePrintF  fprintf
      73             : #define FileClose   fclose
      74             : 
      75             : namespace
      76             : {
      77             :     enum ConfigSection
      78             :     {
      79             :         eGUI,
      80             :         eTest,
      81             : 
      82             :         eUnknown
      83             :     };
      84             : 
      85             :     void lcl_lineFeed( FILETYPE _pFile )
      86             :     {
      87             :         FilePrintF( _pFile, "%s", FILE_LINEEND );
      88             :     }
      89             : 
      90             :     const sal_Char* lcl_getSectionName( ConfigSection _eSection )
      91             :     {
      92             :         const sal_Char* pSectionName = NULL;
      93             :         switch ( _eSection )
      94             :         {
      95             :             case eGUI       : pSectionName = "gui";     break;
      96             :             case eTest      : pSectionName = "test";    break;
      97             :             case eUnknown:
      98             :                 OSL_ASSERT(false);
      99             :                 break;
     100             :         }
     101             :         return pSectionName;
     102             :     }
     103             : 
     104             :     ConfigSection lcl_getSectionFromName( const sal_Char* _pSectionName, size_t _nSectionNameLength )
     105             :     {
     106             :         if ( strncmp( _pSectionName, "gui",     _nSectionNameLength < 3 ? _nSectionNameLength : 3 ) == 0 )
     107             :             return eGUI;
     108             :         if ( strncmp( _pSectionName, "test",    _nSectionNameLength < 4 ? _nSectionNameLength : 4 ) == 0 )
     109             :             return eTest;
     110             :         return eUnknown;
     111             :     }
     112             : 
     113             :     void lcl_startSection( FILETYPE _pFile, ConfigSection _eSection )
     114             :     {
     115             :         FilePrintF( _pFile, "[%s]%s", lcl_getSectionName( _eSection ), FILE_LINEEND );
     116             :     }
     117             : 
     118             :     void lcl_writeConfigString( FILETYPE _pFile, const sal_Char* _pKeyName, const sal_Char* _pValue )
     119             :     {
     120             :         FilePrintF( _pFile, "%s=%s%s", _pKeyName, _pValue, FILE_LINEEND );
     121             :     }
     122             : 
     123             :     void lcl_writeConfigBoolean( FILETYPE _pFile, const sal_Char* _pKeyName, bool _bValue )
     124             :     {
     125             :         lcl_writeConfigString( _pFile, _pKeyName, _bValue ? "1" : "0" );
     126             :     }
     127             : 
     128             :     void lcl_writeConfigFlag( FILETYPE _pFile, const sal_Char* _pKeyName, sal_uIntPtr _nAllFlags, sal_uIntPtr _nCheckFlag )
     129             :     {
     130             :         lcl_writeConfigBoolean( _pFile, _pKeyName, ( _nAllFlags & _nCheckFlag ) != 0 );
     131             :     }
     132             : 
     133             :     bool lcl_isConfigSection( const sal_Char* _pLine, size_t _nLineLen )
     134             :     {
     135             :         if ( _nLineLen < 2 )
     136             :             // not even enough space for '[' and ']'
     137             :             return false;
     138             :         if ( ( _pLine[0] == '[' ) && ( _pLine[ _nLineLen - 1 ] == ']' ) )
     139             :             return true;
     140             :         return false;
     141             :     }
     142             : 
     143             :     bool lcl_isConfigKey( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName )
     144             :     {
     145             :         size_t nKeyLength = strlen( _pKeyName );
     146             :         if ( nKeyLength + 1 >= _nLineLen )
     147             :             // not even long enough for the key name plus "=" plus a one-character value
     148             :             return false;
     149             :         if ( ( strncmp( _pLine, _pKeyName, nKeyLength ) == 0 ) && ( _pLine[ nKeyLength ] == '=' ) )
     150             :             return true;
     151             :         return false;
     152             :     }
     153             : 
     154             :     sal_Int32 lcl_tryReadConfigString( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_Char* _pValue, size_t _nValueLen )
     155             :     {
     156             :         if ( !lcl_isConfigKey( _pLine, _nLineLen, _pKeyName ) )
     157             :             return 0;
     158             :         size_t nValuePos = strlen( _pKeyName ) + 1;
     159             :         size_t nValueLen = _nLineLen - nValuePos;
     160             :         const sal_Char* pValue = _pLine + nValuePos;
     161             :         strncpy( _pValue, pValue, ( _nValueLen > nValueLen ) ? nValueLen : _nValueLen );
     162             :         _pValue[ ( _nValueLen > nValueLen ) ? nValueLen : _nValueLen - 1 ] = 0;
     163             :         return strlen( _pValue );
     164             :     }
     165             : 
     166             :     void lcl_tryReadConfigFlag( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_uIntPtr* _out_pnAllFlags, sal_uIntPtr _nCheckFlag )
     167             :     {
     168             :         sal_Char aBuf[2];
     169             :         size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
     170             :         if ( nValueLen )
     171             :         {
     172             :             if ( strcmp( aBuf, "1" ) == 0 )
     173             :                 *_out_pnAllFlags |= _nCheckFlag;
     174             :             else
     175             :                 *_out_pnAllFlags &= ~_nCheckFlag;
     176             :         }
     177             :     }
     178             : }
     179             : 
     180             : static void DbgGetDbgFileName( sal_Char* pStr, sal_Int32 nMaxLen )
     181             : {
     182             : #if defined( UNX )
     183             :     const sal_Char* pName = getenv("DBGSV_INIT");
     184             :     if ( !pName )
     185             :         pName = ".dbgsv.init";
     186             :     strncpy( pStr, pName, nMaxLen );
     187             : #elif defined( WNT )
     188             :     const sal_Char* pName = getenv("DBGSV_INIT");
     189             :     if ( pName )
     190             :         strncpy( pStr, pName, nMaxLen );
     191             :     else
     192             :         GetProfileStringA( "sv", "dbgsv", "dbgsv.ini", pStr, nMaxLen );
     193             : #else
     194             :     strncpy( pStr, "dbgsv.ini", nMaxLen );
     195             : #endif
     196             :     pStr[ nMaxLen - 1 ] = 0;
     197             : }
     198             : 
     199             : static DebugData* GetDebugData()
     200             : {
     201             :     if ( !aDebugData.bInit )
     202             :     {
     203             :         aDebugData.bInit = true;
     204             : 
     205             :         // DEBUG.INI-File
     206             :         sal_Char aBuf[ 4096 ];
     207             :         DbgGetDbgFileName( aBuf, sizeof( aBuf ) );
     208             :         FILETYPE pIniFile = FileOpen( aBuf, "r" );
     209             :         if ( pIniFile != NULL )
     210             :         {
     211             :             ConfigSection eCurrentSection = eUnknown;
     212             : 
     213             :             // no sophisticated algorithm here, assume that the whole file fits into aBuf ...
     214             :             sal_uIntPtr nReallyRead = FileRead( aBuf, 1, sizeof( aBuf ) / sizeof( sal_Char ) - 1, pIniFile );
     215             :             aBuf[ nReallyRead ] = 0;
     216             :             const sal_Char* pLine = aBuf;
     217             :             while ( const sal_Char* pNextLine = strstr( pLine, FILE_LINEEND ) )
     218             :             {
     219             :                 size_t nLineLength = pNextLine - pLine;
     220             : 
     221             :                 if ( lcl_isConfigSection( pLine, nLineLength ) )
     222             :                     eCurrentSection = lcl_getSectionFromName( pLine + 1, nLineLength - 2 );
     223             : 
     224             :                 // elements of the [gui] section
     225             :                 if ( eCurrentSection == eGUI )
     226             :                 {
     227             :                     lcl_tryReadConfigString( pLine, nLineLength, "debug_window_state", aDebugData.aDbgData.aDbgWinState, sizeof( aDebugData.aDbgData.aDbgWinState ) );
     228             :                 }
     229             : 
     230             :                 // elements of the [test] section
     231             :                 if ( eCurrentSection == eTest )
     232             :                 {
     233             :                     lcl_tryReadConfigFlag( pLine, nLineLength, "resources", &aDebugData.aDbgData.nTestFlags, DBG_TEST_RESOURCE );
     234             :                     lcl_tryReadConfigFlag( pLine, nLineLength, "dialog", &aDebugData.aDbgData.nTestFlags, DBG_TEST_DIALOG );
     235             :                     lcl_tryReadConfigFlag( pLine, nLineLength, "bold_app_font", &aDebugData.aDbgData.nTestFlags, DBG_TEST_BOLDAPPFONT );
     236             :                 }
     237             : 
     238             :                 pLine = pNextLine + strlen( FILE_LINEEND );
     239             :             }
     240             : 
     241             :             FileClose( pIniFile );
     242             :         }
     243             :     }
     244             : 
     245             :     return &aDebugData;
     246             : }
     247             : 
     248             : inline DebugData* ImplGetDebugData()
     249             : {
     250             :     if ( !aDebugData.bInit )
     251             :         return GetDebugData();
     252             :     else
     253             :         return &aDebugData;
     254             : }
     255             : 
     256             : void* DbgFunc( sal_uInt16 nAction, void* pParam )
     257             : {
     258             :     DebugData* pDebugData = ImplGetDebugData();
     259             : 
     260             :     if ( nAction == DBG_FUNC_GETDATA )
     261             :         return (void*)&(pDebugData->aDbgData);
     262             :     else
     263             :     {
     264             :         switch ( nAction )
     265             :         {
     266             :             case DBG_FUNC_SAVEDATA:
     267             :                 {
     268             :                 const DbgData* pData = static_cast< const DbgData* >( pParam );
     269             : 
     270             :                 sal_Char aBuf[ 4096 ];
     271             :                 DbgGetDbgFileName( aBuf, sizeof( aBuf ) );
     272             :                 FILETYPE pIniFile = FileOpen( aBuf, "w" );
     273             :                 if ( pIniFile == NULL )
     274             :                     break;
     275             : 
     276             :                 lcl_lineFeed( pIniFile );
     277             :                 lcl_startSection( pIniFile, eGUI );
     278             :                 lcl_writeConfigString( pIniFile, "debug_window_state", pData->aDbgWinState );
     279             : 
     280             :                 lcl_lineFeed( pIniFile );
     281             :                 lcl_startSection( pIniFile, eTest );
     282             :                 lcl_writeConfigFlag( pIniFile, "resources", pData->nTestFlags, DBG_TEST_RESOURCE );
     283             :                 lcl_writeConfigFlag( pIniFile, "dialog", pData->nTestFlags, DBG_TEST_DIALOG );
     284             :                 lcl_writeConfigFlag( pIniFile, "bold_app_font", pData->nTestFlags, DBG_TEST_BOLDAPPFONT );
     285             : 
     286             :                 FileClose( pIniFile );
     287             :                 }
     288             :                 break;
     289             : 
     290             :             case DBG_FUNC_SETTESTSOLARMUTEX:
     291             :                 pDebugData->pDbgTestSolarMutex = (DbgTestSolarMutexProc)(long)pParam;
     292             :                 break;
     293             : 
     294             :             case DBG_FUNC_TESTSOLARMUTEX:
     295             :                 SAL_WARN_IF(
     296             :                     pDebugData->pDbgTestSolarMutex == 0, "tools.debug",
     297             :                     "no DbgTestSolarMutex function set");
     298             :                 if ( pDebugData->pDbgTestSolarMutex )
     299             :                     pDebugData->pDbgTestSolarMutex();
     300             :                 break;
     301             :        }
     302             : 
     303             :         return NULL;
     304             :     }
     305             : }
     306             : 
     307             : #else
     308             : 
     309           0 : void* DbgFunc( sal_uInt16, void* ) { return NULL; }
     310             : 
     311             : #endif
     312             : 
     313             : 
     314           0 : TOOLS_DLLPUBLIC void DbgUnhandledException(const css::uno::Any & caught, const char* currentFunction, const char* fileAndLineNo)
     315             : {
     316             : #if OSL_DEBUG_LEVEL == 0
     317             :         (void) caught;
     318             :         (void) currentFunction;
     319             :         (void) fileAndLineNo;
     320             : #else
     321             :         OString sMessage( "caught an exception!" );
     322             :         sMessage += "\nin function:";
     323             :         sMessage += currentFunction;
     324             :         sMessage += "\ntype: ";
     325             :         sMessage += OUStringToOString( caught.getValueTypeName(), osl_getThreadTextEncoding() );
     326             :         ::com::sun::star::uno::Exception exception;
     327             :         caught >>= exception;
     328             :         if ( !exception.Message.isEmpty() )
     329             :         {
     330             :             sMessage += "\nmessage: ";
     331             :             sMessage += OUStringToOString( exception.Message, osl_getThreadTextEncoding() );
     332             :         }
     333             :         if ( exception.Context.is() )
     334             :         {
     335             :             const char* pContext = typeid( *exception.Context.get() ).name();
     336             :             sMessage += "\ncontext: ";
     337             :             sMessage += pContext;
     338             :         }
     339             :         {
     340             :             ::com::sun::star::configuration::CorruptedConfigurationException
     341             :                 specialized;
     342             :             if ( caught >>= specialized )
     343             :             {
     344             :                 sMessage += "\ndetails: ";
     345             :                 sMessage += OUStringToOString(
     346             :                     specialized.Details, osl_getThreadTextEncoding() );
     347             :             }
     348             :         }
     349             :         {
     350             :             ::com::sun::star::task::ErrorCodeIOException specialized;
     351             :             if ( caught >>= specialized )
     352             :             {
     353             :                 sMessage += "\ndetails: ";
     354             :                 sMessage += OString::number( specialized.ErrCode );
     355             :             }
     356             :         }
     357             :         sMessage += "\n";
     358             : 
     359             :         SAL_DETAIL_LOG_FORMAT(
     360             :             SAL_DETAIL_ENABLE_LOG_WARN, SAL_DETAIL_LOG_LEVEL_WARN,
     361             :             "legacy.osl", fileAndLineNo, "%s", sMessage.getStr());
     362             : #endif
     363           0 : }
     364             : 
     365             : 
     366             : 
     367             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10