2010-10-14 08:27:31 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-07-11 09:51:50 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-12-27 13:37:20 +02:00
|
|
|
#if defined (UNX) || defined (__GNUC__)
|
2000-09-18 16:07:07 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#else
|
|
|
|
#include <direct.h>
|
|
|
|
#endif
|
|
|
|
|
2011-04-14 22:48:29 -07:00
|
|
|
#include <errno.h>
|
2000-09-18 16:07:07 +00:00
|
|
|
#include <time.h>
|
2013-10-22 15:58:57 +03:00
|
|
|
#include <cstdarg>
|
2000-09-18 16:07:07 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#if defined ( WNT )
|
2011-03-25 23:57:35 +01:00
|
|
|
#include <windows.h>
|
2007-09-06 13:14:46 +00:00
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2014-05-21 09:01:21 +02:00
|
|
|
#include <com/sun/star/task/ErrorCodeIOException.hpp>
|
2007-06-27 21:09:41 +00:00
|
|
|
#include <tools/debug.hxx>
|
2006-02-28 09:31:44 +00:00
|
|
|
#include <rtl/string.h>
|
2011-11-23 15:45:43 +01:00
|
|
|
#include <sal/log.hxx>
|
2010-10-18 12:28:33 +02:00
|
|
|
#include <sal/macros.h>
|
2006-02-28 09:31:44 +00:00
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <osl/diagnose.h>
|
2013-05-21 08:40:07 +02:00
|
|
|
#include <tools/diagnose_ex.h>
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
|
|
|
struct DebugData
|
|
|
|
{
|
|
|
|
DbgData aDbgData;
|
2014-01-10 12:41:20 +01:00
|
|
|
bool bInit;
|
2000-09-18 16:07:07 +00:00
|
|
|
DbgTestSolarMutexProc pDbgTestSolarMutex;
|
2006-02-28 09:31:44 +00:00
|
|
|
|
|
|
|
DebugData()
|
2013-06-29 23:57:38 -05:00
|
|
|
:bInit( false )
|
2006-02-28 09:31:44 +00:00
|
|
|
,pDbgTestSolarMutex( NULL )
|
|
|
|
{
|
2012-01-10 07:19:46 +01:00
|
|
|
aDbgData.nTestFlags = DBG_TEST_RESOURCE;
|
2006-02-28 09:31:44 +00:00
|
|
|
aDbgData.aDbgWinState[0] = 0;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
};
|
|
|
|
|
2006-02-28 09:31:44 +00:00
|
|
|
static DebugData aDebugData;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
#define FILE_LINEEND "\n"
|
|
|
|
|
|
|
|
typedef FILE* FILETYPE;
|
|
|
|
#define FileOpen fopen
|
|
|
|
#define FileRead fread
|
|
|
|
#define FilePrintF fprintf
|
|
|
|
#define FileClose fclose
|
|
|
|
|
2006-02-28 09:31:44 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
enum ConfigSection
|
|
|
|
{
|
|
|
|
eGUI,
|
|
|
|
eTest,
|
|
|
|
|
|
|
|
eUnknown
|
|
|
|
};
|
|
|
|
|
|
|
|
void lcl_lineFeed( FILETYPE _pFile )
|
|
|
|
{
|
|
|
|
FilePrintF( _pFile, "%s", FILE_LINEEND );
|
|
|
|
}
|
|
|
|
|
|
|
|
const sal_Char* lcl_getSectionName( ConfigSection _eSection )
|
|
|
|
{
|
|
|
|
const sal_Char* pSectionName = NULL;
|
|
|
|
switch ( _eSection )
|
|
|
|
{
|
|
|
|
case eGUI : pSectionName = "gui"; break;
|
|
|
|
case eTest : pSectionName = "test"; break;
|
2006-06-19 12:37:51 +00:00
|
|
|
case eUnknown:
|
|
|
|
OSL_ASSERT(false);
|
|
|
|
break;
|
2006-02-28 09:31:44 +00:00
|
|
|
}
|
|
|
|
return pSectionName;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConfigSection lcl_getSectionFromName( const sal_Char* _pSectionName, size_t _nSectionNameLength )
|
|
|
|
{
|
|
|
|
if ( strncmp( _pSectionName, "gui", _nSectionNameLength < 3 ? _nSectionNameLength : 3 ) == 0 )
|
|
|
|
return eGUI;
|
|
|
|
if ( strncmp( _pSectionName, "test", _nSectionNameLength < 4 ? _nSectionNameLength : 4 ) == 0 )
|
|
|
|
return eTest;
|
|
|
|
return eUnknown;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcl_startSection( FILETYPE _pFile, ConfigSection _eSection )
|
|
|
|
{
|
|
|
|
FilePrintF( _pFile, "[%s]%s", lcl_getSectionName( _eSection ), FILE_LINEEND );
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcl_writeConfigString( FILETYPE _pFile, const sal_Char* _pKeyName, const sal_Char* _pValue )
|
|
|
|
{
|
|
|
|
FilePrintF( _pFile, "%s=%s%s", _pKeyName, _pValue, FILE_LINEEND );
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcl_writeConfigBoolean( FILETYPE _pFile, const sal_Char* _pKeyName, bool _bValue )
|
|
|
|
{
|
|
|
|
lcl_writeConfigString( _pFile, _pKeyName, _bValue ? "1" : "0" );
|
|
|
|
}
|
|
|
|
|
2010-07-29 10:56:19 +08:00
|
|
|
void lcl_writeConfigFlag( FILETYPE _pFile, const sal_Char* _pKeyName, sal_uIntPtr _nAllFlags, sal_uIntPtr _nCheckFlag )
|
2006-02-28 09:31:44 +00:00
|
|
|
{
|
|
|
|
lcl_writeConfigBoolean( _pFile, _pKeyName, ( _nAllFlags & _nCheckFlag ) != 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool lcl_isConfigSection( const sal_Char* _pLine, size_t _nLineLen )
|
|
|
|
{
|
|
|
|
if ( _nLineLen < 2 )
|
|
|
|
// not even enough space for '[' and ']'
|
|
|
|
return false;
|
|
|
|
if ( ( _pLine[0] == '[' ) && ( _pLine[ _nLineLen - 1 ] == ']' ) )
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2012-08-18 18:12:35 +02:00
|
|
|
|
2006-02-28 09:31:44 +00:00
|
|
|
bool lcl_isConfigKey( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName )
|
|
|
|
{
|
|
|
|
size_t nKeyLength = strlen( _pKeyName );
|
|
|
|
if ( nKeyLength + 1 >= _nLineLen )
|
|
|
|
// not even long enough for the key name plus "=" plus a one-character value
|
|
|
|
return false;
|
|
|
|
if ( ( strncmp( _pLine, _pKeyName, nKeyLength ) == 0 ) && ( _pLine[ nKeyLength ] == '=' ) )
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2012-08-18 18:12:35 +02:00
|
|
|
|
2006-02-28 09:31:44 +00:00
|
|
|
sal_Int32 lcl_tryReadConfigString( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_Char* _pValue, size_t _nValueLen )
|
|
|
|
{
|
|
|
|
if ( !lcl_isConfigKey( _pLine, _nLineLen, _pKeyName ) )
|
|
|
|
return 0;
|
|
|
|
size_t nValuePos = strlen( _pKeyName ) + 1;
|
|
|
|
size_t nValueLen = _nLineLen - nValuePos;
|
|
|
|
const sal_Char* pValue = _pLine + nValuePos;
|
|
|
|
strncpy( _pValue, pValue, ( _nValueLen > nValueLen ) ? nValueLen : _nValueLen );
|
|
|
|
_pValue[ ( _nValueLen > nValueLen ) ? nValueLen : _nValueLen - 1 ] = 0;
|
|
|
|
return strlen( _pValue );
|
|
|
|
}
|
2012-08-18 18:12:35 +02:00
|
|
|
|
2010-07-29 10:56:19 +08:00
|
|
|
void lcl_tryReadConfigFlag( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_uIntPtr* _out_pnAllFlags, sal_uIntPtr _nCheckFlag )
|
2006-02-28 09:31:44 +00:00
|
|
|
{
|
|
|
|
sal_Char aBuf[2];
|
|
|
|
size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
|
|
|
|
if ( nValueLen )
|
2010-12-23 11:19:55 +01:00
|
|
|
{
|
2006-02-28 09:31:44 +00:00
|
|
|
if ( strcmp( aBuf, "1" ) == 0 )
|
|
|
|
*_out_pnAllFlags |= _nCheckFlag;
|
|
|
|
else
|
|
|
|
*_out_pnAllFlags &= ~_nCheckFlag;
|
2010-12-23 11:19:55 +01:00
|
|
|
}
|
2006-02-28 09:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-03 13:49:27 +01:00
|
|
|
static void DbgGetDbgFileName( sal_Char* pStr, sal_Int32 nMaxLen )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2010-02-03 13:49:27 +01:00
|
|
|
#if defined( UNX )
|
|
|
|
const sal_Char* pName = getenv("DBGSV_INIT");
|
|
|
|
if ( !pName )
|
|
|
|
pName = ".dbgsv.init";
|
|
|
|
strncpy( pStr, pName, nMaxLen );
|
|
|
|
#elif defined( WNT )
|
|
|
|
const sal_Char* pName = getenv("DBGSV_INIT");
|
|
|
|
if ( pName )
|
|
|
|
strncpy( pStr, pName, nMaxLen );
|
|
|
|
else
|
|
|
|
GetProfileStringA( "sv", "dbgsv", "dbgsv.ini", pStr, nMaxLen );
|
|
|
|
#else
|
|
|
|
strncpy( pStr, "dbgsv.ini", nMaxLen );
|
|
|
|
#endif
|
|
|
|
pStr[ nMaxLen - 1 ] = 0;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static DebugData* GetDebugData()
|
|
|
|
{
|
|
|
|
if ( !aDebugData.bInit )
|
|
|
|
{
|
2013-06-29 23:57:38 -05:00
|
|
|
aDebugData.bInit = true;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// DEBUG.INI-File
|
2010-02-03 13:49:27 +01:00
|
|
|
sal_Char aBuf[ 4096 ];
|
|
|
|
DbgGetDbgFileName( aBuf, sizeof( aBuf ) );
|
|
|
|
FILETYPE pIniFile = FileOpen( aBuf, "r" );
|
2006-02-28 09:31:44 +00:00
|
|
|
if ( pIniFile != NULL )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2006-02-28 09:31:44 +00:00
|
|
|
ConfigSection eCurrentSection = eUnknown;
|
|
|
|
|
|
|
|
// no sophisticated algorithm here, assume that the whole file fits into aBuf ...
|
2010-07-29 10:56:19 +08:00
|
|
|
sal_uIntPtr nReallyRead = FileRead( aBuf, 1, sizeof( aBuf ) / sizeof( sal_Char ) - 1, pIniFile );
|
2006-02-28 09:31:44 +00:00
|
|
|
aBuf[ nReallyRead ] = 0;
|
|
|
|
const sal_Char* pLine = aBuf;
|
|
|
|
while ( const sal_Char* pNextLine = strstr( pLine, FILE_LINEEND ) )
|
|
|
|
{
|
|
|
|
size_t nLineLength = pNextLine - pLine;
|
|
|
|
|
|
|
|
if ( lcl_isConfigSection( pLine, nLineLength ) )
|
|
|
|
eCurrentSection = lcl_getSectionFromName( pLine + 1, nLineLength - 2 );
|
|
|
|
|
|
|
|
// elements of the [gui] section
|
|
|
|
if ( eCurrentSection == eGUI )
|
|
|
|
{
|
|
|
|
lcl_tryReadConfigString( pLine, nLineLength, "debug_window_state", aDebugData.aDbgData.aDbgWinState, sizeof( aDebugData.aDbgData.aDbgWinState ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// elements of the [test] section
|
|
|
|
if ( eCurrentSection == eTest )
|
|
|
|
{
|
|
|
|
lcl_tryReadConfigFlag( pLine, nLineLength, "resources", &aDebugData.aDbgData.nTestFlags, DBG_TEST_RESOURCE );
|
|
|
|
lcl_tryReadConfigFlag( pLine, nLineLength, "dialog", &aDebugData.aDbgData.nTestFlags, DBG_TEST_DIALOG );
|
|
|
|
lcl_tryReadConfigFlag( pLine, nLineLength, "bold_app_font", &aDebugData.aDbgData.nTestFlags, DBG_TEST_BOLDAPPFONT );
|
|
|
|
}
|
|
|
|
|
|
|
|
pLine = pNextLine + strlen( FILE_LINEEND );
|
|
|
|
}
|
|
|
|
|
|
|
|
FileClose( pIniFile );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &aDebugData;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline DebugData* ImplGetDebugData()
|
|
|
|
{
|
|
|
|
if ( !aDebugData.bInit )
|
|
|
|
return GetDebugData();
|
|
|
|
else
|
|
|
|
return &aDebugData;
|
|
|
|
}
|
|
|
|
|
2011-01-21 13:06:20 +01:00
|
|
|
void* DbgFunc( sal_uInt16 nAction, void* pParam )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2006-02-28 09:31:44 +00:00
|
|
|
DebugData* pDebugData = ImplGetDebugData();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if ( nAction == DBG_FUNC_GETDATA )
|
2006-02-28 09:31:44 +00:00
|
|
|
return (void*)&(pDebugData->aDbgData);
|
2000-09-18 16:07:07 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
switch ( nAction )
|
|
|
|
{
|
|
|
|
case DBG_FUNC_SAVEDATA:
|
|
|
|
{
|
2006-02-28 09:31:44 +00:00
|
|
|
const DbgData* pData = static_cast< const DbgData* >( pParam );
|
|
|
|
|
2010-02-03 13:49:27 +01:00
|
|
|
sal_Char aBuf[ 4096 ];
|
|
|
|
DbgGetDbgFileName( aBuf, sizeof( aBuf ) );
|
|
|
|
FILETYPE pIniFile = FileOpen( aBuf, "w" );
|
2006-02-28 09:31:44 +00:00
|
|
|
if ( pIniFile == NULL )
|
|
|
|
break;
|
|
|
|
|
|
|
|
lcl_lineFeed( pIniFile );
|
|
|
|
lcl_startSection( pIniFile, eGUI );
|
|
|
|
lcl_writeConfigString( pIniFile, "debug_window_state", pData->aDbgWinState );
|
|
|
|
|
|
|
|
lcl_lineFeed( pIniFile );
|
|
|
|
lcl_startSection( pIniFile, eTest );
|
|
|
|
lcl_writeConfigFlag( pIniFile, "resources", pData->nTestFlags, DBG_TEST_RESOURCE );
|
|
|
|
lcl_writeConfigFlag( pIniFile, "dialog", pData->nTestFlags, DBG_TEST_DIALOG );
|
|
|
|
lcl_writeConfigFlag( pIniFile, "bold_app_font", pData->nTestFlags, DBG_TEST_BOLDAPPFONT );
|
|
|
|
|
|
|
|
FileClose( pIniFile );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DBG_FUNC_SETTESTSOLARMUTEX:
|
2014-12-08 08:19:15 +01:00
|
|
|
pDebugData->pDbgTestSolarMutex = reinterpret_cast<DbgTestSolarMutexProc>(reinterpret_cast<sal_uIntPtr>(pParam));
|
2000-09-18 16:07:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DBG_FUNC_TESTSOLARMUTEX:
|
2014-02-03 12:13:17 +01:00
|
|
|
SAL_WARN_IF(
|
|
|
|
pDebugData->pDbgTestSolarMutex == 0, "tools.debug",
|
|
|
|
"no DbgTestSolarMutex function set");
|
2006-02-28 09:31:44 +00:00
|
|
|
if ( pDebugData->pDbgTestSolarMutex )
|
|
|
|
pDebugData->pDbgTestSolarMutex();
|
2000-09-18 16:07:07 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2010-10-14 08:27:31 +02:00
|
|
|
|
2014-07-14 11:29:02 +02:00
|
|
|
#if OSL_DEBUG_LEVEL > 0
|
2013-05-21 08:40:07 +02:00
|
|
|
|
2015-01-05 13:05:50 +01:00
|
|
|
void DbgUnhandledException(const css::uno::Any & caught, const char* currentFunction, const char* fileAndLineNo)
|
2013-05-21 08:40:07 +02:00
|
|
|
{
|
|
|
|
OString sMessage( "caught an exception!" );
|
|
|
|
sMessage += "\nin function:";
|
|
|
|
sMessage += currentFunction;
|
|
|
|
sMessage += "\ntype: ";
|
|
|
|
sMessage += OUStringToOString( caught.getValueTypeName(), osl_getThreadTextEncoding() );
|
|
|
|
::com::sun::star::uno::Exception exception;
|
|
|
|
caught >>= exception;
|
|
|
|
if ( !exception.Message.isEmpty() )
|
|
|
|
{
|
|
|
|
sMessage += "\nmessage: ";
|
|
|
|
sMessage += OUStringToOString( exception.Message, osl_getThreadTextEncoding() );
|
|
|
|
}
|
|
|
|
if ( exception.Context.is() )
|
|
|
|
{
|
|
|
|
const char* pContext = typeid( *exception.Context.get() ).name();
|
|
|
|
sMessage += "\ncontext: ";
|
|
|
|
sMessage += pContext;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
::com::sun::star::configuration::CorruptedConfigurationException
|
|
|
|
specialized;
|
|
|
|
if ( caught >>= specialized )
|
|
|
|
{
|
|
|
|
sMessage += "\ndetails: ";
|
|
|
|
sMessage += OUStringToOString(
|
|
|
|
specialized.Details, osl_getThreadTextEncoding() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
::com::sun::star::task::ErrorCodeIOException specialized;
|
|
|
|
if ( caught >>= specialized )
|
|
|
|
{
|
|
|
|
sMessage += "\ndetails: ";
|
2013-08-21 15:07:31 +02:00
|
|
|
sMessage += OString::number( specialized.ErrCode );
|
2013-05-21 08:40:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
sMessage += "\n";
|
2013-06-07 14:44:48 +02:00
|
|
|
|
|
|
|
SAL_DETAIL_LOG_FORMAT(
|
|
|
|
SAL_DETAIL_ENABLE_LOG_WARN, SAL_DETAIL_LOG_LEVEL_WARN,
|
|
|
|
"legacy.osl", fileAndLineNo, "%s", sMessage.getStr());
|
2013-05-21 08:40:07 +02:00
|
|
|
}
|
|
|
|
|
2014-07-14 11:29:02 +02:00
|
|
|
#endif
|
|
|
|
|
2013-05-21 08:40:07 +02:00
|
|
|
|
|
|
|
|
2010-10-14 08:27:31 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|