mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 17:10:48 +01:00
SERVER-7080 Link to backtrace, backtrace_symbols and backtrace_symbols_fd at runtime
Do not make direct calls to backtrace, backtrace_symbols or backtrace_symbols_fd, which are present in Solaris 11 but not in Solaris 10. Instead, see if they are available in a loaded library (which will be libc.so.1) at runtime and either call them or call an emulation.
This commit is contained in:
parent
38d638004c
commit
54f25e6292
@ -1224,7 +1224,8 @@ def doConfigure(myenv):
|
||||
|
||||
if (conf.CheckCXXHeader( "execinfo.h" ) and
|
||||
conf.CheckDeclaration('backtrace', includes='#include <execinfo.h>') and
|
||||
conf.CheckDeclaration('backtrace_symbols', includes='#include <execinfo.h>')):
|
||||
conf.CheckDeclaration('backtrace_symbols', includes='#include <execinfo.h>') and
|
||||
conf.CheckDeclaration('backtrace_symbols_fd', includes='#include <execinfo.h>')):
|
||||
|
||||
conf.env.Append( CPPDEFINES=[ "MONGO_HAVE_EXECINFO_BACKTRACE" ] )
|
||||
|
||||
|
@ -51,6 +51,7 @@ clientSourceBasic = [
|
||||
'mongo/db/namespace.cpp',
|
||||
'mongo/db/dbmessage.cpp',
|
||||
'mongo/pch.cpp',
|
||||
'mongo/platform/backtrace.cpp',
|
||||
'mongo/platform/posix_fadvise.cpp',
|
||||
'mongo/platform/process_id.cpp',
|
||||
'mongo/platform/random.cpp',
|
||||
|
@ -3,6 +3,7 @@
|
||||
Import("env")
|
||||
|
||||
env.Library('platform', [
|
||||
'backtrace.cpp',
|
||||
'posix_fadvise.cpp',
|
||||
'process_id.cpp',
|
||||
'random.cpp',
|
||||
|
93
src/mongo/platform/backtrace.cpp
Normal file
93
src/mongo/platform/backtrace.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/* Copyright 2013 10gen Inc.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__sunos__) || !defined(MONGO_HAVE_EXECINFO_BACKTRACE)
|
||||
|
||||
#include "mongo/platform/backtrace.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "mongo/base/init.h"
|
||||
#include "mongo/base/status.h"
|
||||
|
||||
namespace mongo {
|
||||
namespace pal {
|
||||
|
||||
int backtrace_emulation(void** array, int size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char** backtrace_symbols_emulation(void* const* array, int size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void backtrace_symbols_fd_emulation(void* const* array, int size, int fd) {
|
||||
}
|
||||
|
||||
typedef int (*BacktraceFunc)(void** array, int size);
|
||||
static BacktraceFunc backtrace_switcher =
|
||||
pal::backtrace_emulation;
|
||||
|
||||
typedef char** (*BacktraceSymbolsFunc)(void* const* array, int size);
|
||||
static BacktraceSymbolsFunc backtrace_symbols_switcher =
|
||||
pal::backtrace_symbols_emulation;
|
||||
|
||||
typedef void (*BacktraceSymbolsFdFunc)(void* const* array, int size, int fd);
|
||||
static BacktraceSymbolsFdFunc backtrace_symbols_fd_switcher =
|
||||
pal::backtrace_symbols_fd_emulation;
|
||||
|
||||
int backtrace(void** array, int size) {
|
||||
return backtrace_switcher(array, size);
|
||||
}
|
||||
|
||||
char** backtrace_symbols(void* const* array, int size) {
|
||||
return backtrace_symbols_switcher(array, size);
|
||||
}
|
||||
|
||||
void backtrace_symbols_fd(void* const* array, int size, int fd) {
|
||||
backtrace_symbols_fd_switcher(array, size, fd);
|
||||
}
|
||||
|
||||
} // namespace pal
|
||||
|
||||
// 'backtrace()', 'backtrace_symbols()' and 'backtrace_symbols_fd()' on Solaris will call
|
||||
// emulation functions if the symbols are not found
|
||||
//
|
||||
MONGO_INITIALIZER_GENERAL(SolarisBacktrace,
|
||||
MONGO_NO_PREREQUISITES,
|
||||
("default"))(InitializerContext* context) {
|
||||
void* functionAddress = dlsym(RTLD_DEFAULT, "backtrace");
|
||||
if (functionAddress != NULL) {
|
||||
pal::backtrace_switcher =
|
||||
reinterpret_cast<pal::BacktraceFunc>(functionAddress);
|
||||
}
|
||||
functionAddress = dlsym(RTLD_DEFAULT, "backtrace_symbols");
|
||||
if (functionAddress != NULL) {
|
||||
pal::backtrace_symbols_switcher =
|
||||
reinterpret_cast<pal::BacktraceSymbolsFunc>(functionAddress);
|
||||
}
|
||||
functionAddress = dlsym(RTLD_DEFAULT, "backtrace_symbols_fd");
|
||||
if (functionAddress != NULL) {
|
||||
pal::backtrace_symbols_fd_switcher =
|
||||
reinterpret_cast<pal::BacktraceSymbolsFdFunc>(functionAddress);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
} // namespace mongo
|
||||
|
||||
#endif // #if defined(__sunos__)
|
||||
#endif // #if !defined(_WIN32)
|
43
src/mongo/platform/backtrace.h
Normal file
43
src/mongo/platform/backtrace.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* Copyright 2013 10gen Inc.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__sunos__) || !defined(MONGO_HAVE_EXECINFO_BACKTRACE)
|
||||
|
||||
namespace mongo {
|
||||
namespace pal {
|
||||
int backtrace(void** array, int size);
|
||||
char** backtrace_symbols(void* const* array, int size);
|
||||
void backtrace_symbols_fd(void* const* array, int size, int fd);
|
||||
} // namespace pal
|
||||
using pal::backtrace;
|
||||
using pal::backtrace_symbols;
|
||||
using pal::backtrace_symbols_fd;
|
||||
} // namespace mongo
|
||||
|
||||
#else
|
||||
|
||||
#include <execinfo.h>
|
||||
|
||||
namespace mongo {
|
||||
using ::backtrace;
|
||||
using ::backtrace_symbols;
|
||||
using ::backtrace_symbols_fd;
|
||||
} // namespace mongo
|
||||
|
||||
#endif
|
||||
#endif
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pch.h"
|
||||
#include "mongo/pch.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
@ -26,20 +26,17 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef MONGO_HAVE_EXECINFO_BACKTRACE
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "signal_handlers.h"
|
||||
#include "mongo/platform/backtrace.h"
|
||||
#include "mongo/util/log.h"
|
||||
#include "mongo/util/signal_handlers.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/*
|
||||
* WARNING: PLEASE READ BEFORE CHANGING THIS MODULE
|
||||
*
|
||||
* All code in this module should be singal-friendly. Before adding any system
|
||||
* call or other dependency, please make sure the latter still holds.
|
||||
* All code in this module must be signal-friendly. Before adding any system
|
||||
* call or other dependency, please make sure that this still holds.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -84,7 +81,7 @@ namespace mongo {
|
||||
|
||||
static void formattedBacktrace( int fd ) {
|
||||
|
||||
#ifdef MONGO_HAVE_EXECINFO_BACKTRACE
|
||||
#if !defined(_WIN32)
|
||||
|
||||
int numFrames;
|
||||
const int MAX_DEPTH = 20;
|
||||
|
@ -18,22 +18,21 @@
|
||||
|
||||
#include "mongo/util/stack_introspect.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cxxabi.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mongo/platform/backtrace.h"
|
||||
#include "mongo/util/concurrency/mutex.h"
|
||||
#include "mongo/util/text.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef MONGO_HAVE_EXECINFO_BACKTRACE
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
namespace mongo {
|
||||
|
||||
namespace {
|
||||
@ -111,7 +110,7 @@ namespace mongo {
|
||||
|
||||
bool inConstructorChain( bool printOffending ){
|
||||
void* b[maxBackTraceFrames];
|
||||
int size = ::backtrace( b, maxBackTraceFrames );
|
||||
int size = backtrace( b, maxBackTraceFrames );
|
||||
|
||||
char** strings = 0;
|
||||
|
||||
@ -127,7 +126,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
if ( ! strings )
|
||||
strings = ::backtrace_symbols( b, size );
|
||||
strings = backtrace_symbols( b, size );
|
||||
|
||||
string symbol = strings[i];
|
||||
|
||||
@ -181,5 +180,4 @@ namespace mongo {
|
||||
bool inConstructorChainSupported() { return false; }
|
||||
}
|
||||
|
||||
#endif // defined(MONGO_HAVE_EXECINFO_BACKTRACE)
|
||||
|
||||
#endif // #if !defined(_WIN32)
|
||||
|
@ -24,53 +24,18 @@
|
||||
#include "mongo/util/log.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/smart_ptr/scoped_array.hpp>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include "mongo/platform/windows_basic.h"
|
||||
#include <DbgHelp.h>
|
||||
#include "mongo/util/assert_util.h"
|
||||
#else
|
||||
#include "mongo/platform/backtrace.h"
|
||||
#endif
|
||||
|
||||
#ifdef MONGO_HAVE_EXECINFO_BACKTRACE
|
||||
|
||||
#include <execinfo.h>
|
||||
|
||||
namespace mongo {
|
||||
static const int maxBackTraceFrames = 20;
|
||||
|
||||
/**
|
||||
* Print a stack backtrace for the current thread to the specified ostream.
|
||||
*
|
||||
* @param os ostream& to receive printed stack backtrace
|
||||
*/
|
||||
void printStackTrace( std::ostream& os ) {
|
||||
|
||||
void *b[maxBackTraceFrames];
|
||||
|
||||
int size = ::backtrace( b, maxBackTraceFrames );
|
||||
for ( int i = 0; i < size; i++ )
|
||||
os << std::hex << b[i] << std::dec << ' ';
|
||||
os << std::endl;
|
||||
|
||||
char **strings;
|
||||
|
||||
strings = ::backtrace_symbols( b, size );
|
||||
if (strings == NULL) {
|
||||
const int err = errno;
|
||||
os << "Unable to collect backtrace symbols (" << errnoWithDescription(err) << ")"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
for ( int i = 0; i < size; i++ )
|
||||
os << ' ' << strings[i] << '\n';
|
||||
os.flush();
|
||||
::free( strings );
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
|
||||
namespace mongo {
|
||||
|
||||
@ -319,12 +284,43 @@ namespace mongo {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace mongo {
|
||||
void printStackTrace( std::ostream &os ) {}
|
||||
static const int maxBackTraceFrames = 20;
|
||||
|
||||
/**
|
||||
* Print a stack backtrace for the current thread to the specified ostream.
|
||||
*
|
||||
* @param os ostream& to receive printed stack backtrace
|
||||
*/
|
||||
void printStackTrace( std::ostream& os ) {
|
||||
|
||||
void* addresses[maxBackTraceFrames];
|
||||
|
||||
int addressCount = backtrace(addresses, maxBackTraceFrames);
|
||||
if (addressCount == 0) {
|
||||
const int err = errno;
|
||||
os << "Unable to collect backtrace addresses (" << errnoWithDescription(err) << ")"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < addressCount; i++)
|
||||
os << std::hex << addresses[i] << std::dec << ' ';
|
||||
os << std::endl;
|
||||
|
||||
char** backtraceStrings = backtrace_symbols(addresses, addressCount);
|
||||
if (backtraceStrings == NULL) {
|
||||
const int err = errno;
|
||||
os << "Unable to collect backtrace symbols (" << errnoWithDescription(err) << ")"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < addressCount; i++)
|
||||
os << ' ' << backtraceStrings[i] << '\n';
|
||||
os.flush();
|
||||
free(backtraceStrings);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user