* Make the backtrace printing functionality a framework
* Copy Linux and Solaris backtrace support from util/stacktrace.c * Added backtrace support for Mac OS X. This commit was SVN r11023.
Этот коммит содержится в:
родитель
7ea33eac02
Коммит
aaf31c6ade
1
NEWS
1
NEWS
@ -25,6 +25,7 @@ version 1.0.
|
||||
1.2
|
||||
---
|
||||
|
||||
- Added stacktrace support for Solaris and Mac OS X.
|
||||
- Update event library to libevent-1.1a
|
||||
- Fixed standards conformance issues with MPI_ERR_TRUNCATED and
|
||||
setting MPI_ERROR during MPI_TEST/MPI_WAIT.
|
||||
|
@ -17,7 +17,7 @@ dnl
|
||||
dnl $HEADER$
|
||||
dnl
|
||||
|
||||
# OMPI_CHECK_FUNC_LIB(func, lib)
|
||||
# OMPI_CHECK_FUNC_LIB(func, lib, [action-if-found], [action-if-not-found])
|
||||
# ------------------------------
|
||||
# Try to find function func, first with the present LIBS, second with
|
||||
# lib added to LIBS. If func is found with the libraries listed in
|
||||
@ -42,6 +42,6 @@ AC_DEFUN([OMPI_CHECK_FUNC_LIB],[
|
||||
# see if we actually have $1. Use AC_CHECK_FUNCS so that it
|
||||
# does the glibc "not implemented" check. Will use the current LIBS,
|
||||
# so will check in -l$2 if we decided we needed it above
|
||||
AC_CHECK_FUNCS([$1])
|
||||
AC_CHECK_FUNCS([$1], $3, $4)
|
||||
AS_VAR_POPDEF([ompi_var])dnl
|
||||
])
|
||||
|
@ -570,8 +570,7 @@ AC_CHECK_HEADERS([alloca.h aio.h arpa/inet.h dirent.h \
|
||||
sys/resource.h sys/select.h sys/socket.h sys/sockio.h \
|
||||
stdarg.h sys/stat.h sys/statvfs.h sys/time.h sys/tree.h \
|
||||
sys/types.h sys/uio.h sys/utsname.h sys/wait.h syslog.h \
|
||||
time.h termios.h ulimit.h unistd.h util.h utmp.h malloc.h \
|
||||
ucontext.h])
|
||||
time.h termios.h ulimit.h unistd.h util.h utmp.h malloc.h])
|
||||
|
||||
# Needed to work around Darwin requiring sys/socket.h for
|
||||
# net/if.h
|
||||
@ -689,16 +688,13 @@ AC_CHECK_LIB([socket], [socket])
|
||||
# Solaris has sched_yeild in -lrt, usually in libc
|
||||
OMPI_CHECK_FUNC_LIB([sched_yield], [rt])
|
||||
|
||||
# FreeBSD has backtrace in -lexecinfo, usually in libc
|
||||
OMPI_CHECK_FUNC_LIB([backtrace], [execinfo])
|
||||
|
||||
# IRIX has dirname in -lgen, usually in libc
|
||||
OMPI_CHECK_FUNC_LIB([dirname], [gen])
|
||||
|
||||
# Darwin doesn't need -lm, as it's a symlink to libSystem.dylib
|
||||
OMPI_CHECK_FUNC_LIB([ceil], [m])
|
||||
|
||||
AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty htonl ntohl htons ntohs getpwuid fork waitpid execve pipe ptsname setsid mmap mallopt tcgetpgrp printstack])
|
||||
AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty htonl ntohl htons ntohs getpwuid fork waitpid execve pipe ptsname setsid mmap mallopt tcgetpgrp])
|
||||
|
||||
#
|
||||
# Make sure we can copy va_lists (need check declared, not linkable)
|
||||
|
41
opal/mca/backtrace/Makefile.am
Обычный файл
41
opal/mca/backtrace/Makefile.am
Обычный файл
@ -0,0 +1,41 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# main library setup
|
||||
noinst_LTLIBRARIES = libmca_backtrace.la
|
||||
libmca_backtrace_la_SOURCES =
|
||||
|
||||
# header setup
|
||||
nobase_opal_HEADERS =
|
||||
|
||||
# local files
|
||||
headers = backtrace.h
|
||||
libmca_backtrace_la_SOURCES += $(headers)
|
||||
|
||||
# Conditionally install the header files
|
||||
if WANT_INSTALL_HEADERS
|
||||
nobase_opal_HEADERS += $(headers)
|
||||
opaldir = $(includedir)/openmpi/opal/mca/backtrace
|
||||
else
|
||||
opaldir = $(includedir)
|
||||
endif
|
||||
|
||||
include base/Makefile.am
|
||||
|
||||
distclean-local:
|
||||
rm -f base/static-components.h
|
75
opal/mca/backtrace/backtrace.h
Обычный файл
75
opal/mca/backtrace/backtrace.h
Обычный файл
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef OPAL_MCA_BACKTRACE_BACKTRACE_H
|
||||
#define OPAL_MCA_BACKTRACE_BACKTRACE_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
|
||||
/*
|
||||
* Most of this file is just for ompi_info. There are two interface
|
||||
* functions, both of which are called directly. The joy of link-time
|
||||
* components.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* print back trace to FILE file
|
||||
*
|
||||
* \note some attempts made to be signal safe.
|
||||
*/
|
||||
void opal_backtrace_print(FILE *file);
|
||||
|
||||
/*
|
||||
* Return back trace in buffer. buffer will be allocated by the
|
||||
* backtrace component, but should be free'ed by the caller.
|
||||
*
|
||||
* \note Probably bad to call this from a signal handler.
|
||||
*
|
||||
*/
|
||||
int opal_backtrace_buffer(char*** messages, int *len);
|
||||
|
||||
|
||||
/**
|
||||
* Structure for backtrace v1.0.0 components.
|
||||
* Chained to MCA v1.0.0
|
||||
*/
|
||||
struct opal_backtrace_base_component_1_0_0_t {
|
||||
/** MCA base component */
|
||||
mca_base_component_t backtracec_version;
|
||||
/** MCA base data */
|
||||
mca_base_component_data_1_0_0_t backtracec_data;
|
||||
};
|
||||
/**
|
||||
* Convenience typedef
|
||||
*/
|
||||
typedef struct opal_backtrace_base_component_1_0_0_t opal_backtrace_base_component_1_0_0_t;
|
||||
|
||||
/*
|
||||
* Macro for use in components that are of type backtrace v1.0.0
|
||||
*/
|
||||
#define OPAL_BACKTRACE_BASE_VERSION_1_0_0 \
|
||||
/* backtrace v1.0 is chained to MCA v1.0 */ \
|
||||
MCA_BASE_VERSION_1_0_0, \
|
||||
/* backtrace v1.0 */ \
|
||||
"backtrace", 1, 0, 0
|
||||
|
||||
#endif /* OPAL_MCA_BACKTRACE_BACKTRACE_H */
|
23
opal/mca/backtrace/base/Makefile.am
Обычный файл
23
opal/mca/backtrace/base/Makefile.am
Обычный файл
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
headers += \
|
||||
base/base.h
|
||||
|
||||
libmca_backtrace_la_SOURCES += \
|
||||
base/backtrace_component.c
|
74
opal/mca/backtrace/base/backtrace_component.c
Обычный файл
74
opal/mca/backtrace/base/backtrace_component.c
Обычный файл
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
#include "opal/mca/backtrace/base/base.h"
|
||||
|
||||
|
||||
/*
|
||||
* The following file was created by configure. It contains extern
|
||||
* statements and the definition of an array of pointers to each
|
||||
* component's public mca_base_component_t struct.
|
||||
*/
|
||||
#include "opal/mca/backtrace/base/static-components.h"
|
||||
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
opal_list_t opal_backtrace_base_components_opened;
|
||||
|
||||
|
||||
int
|
||||
opal_backtrace_base_open(void)
|
||||
{
|
||||
/* Open up all available components */
|
||||
if (OPAL_SUCCESS !=
|
||||
mca_base_components_open("backtrace", 0,
|
||||
mca_backtrace_base_static_components,
|
||||
&opal_backtrace_base_components_opened,
|
||||
true)) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
opal_backtrace_base_close(void)
|
||||
{
|
||||
/* Close all components that are still open (this should only
|
||||
happen during laminfo). */
|
||||
mca_base_components_close(0,
|
||||
&opal_backtrace_base_components_opened,
|
||||
NULL);
|
||||
OBJ_DESTRUCT(&opal_backtrace_base_components_opened);
|
||||
|
||||
/* All done */
|
||||
return OPAL_SUCCESS;
|
||||
}
|
77
opal/mca/backtrace/base/base.h
Обычный файл
77
opal/mca/backtrace/base/base.h
Обычный файл
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPAL_BACKTRACE_BASE_H
|
||||
#define OPAL_BACKTRACE_BASE_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
|
||||
|
||||
/*
|
||||
* Global functions for MCA overall backtrace open and close
|
||||
*/
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the backtrace MCA framework
|
||||
*
|
||||
* @retval OPAL_SUCCESS Upon success
|
||||
* @retval OPAL_ERROR Upon failure
|
||||
*
|
||||
* This must be the first function invoked in the backtrace MCA
|
||||
* framework. It initializes the backtrace MCA framework, finds
|
||||
* and opens backtrace components, etc.
|
||||
*
|
||||
* This function is invoked during opal_init() and during the
|
||||
* initialization of the special case of the laminfo command.
|
||||
*
|
||||
* This function fills in the internal global variable
|
||||
* opal_backtrace_base_components_opened, which is a list of all
|
||||
* backtrace components that were successfully opened. This
|
||||
* variable should \em only be used by other backtrace base
|
||||
* functions -- it is not considered a public interface member --
|
||||
* and is only mentioned here for completeness.
|
||||
*/
|
||||
OMPI_DECLSPEC int opal_backtrace_base_open(void);
|
||||
|
||||
|
||||
/**
|
||||
* Shut down the backtrace MCA framework.
|
||||
*
|
||||
* @retval OPAL_SUCCESS Always
|
||||
*
|
||||
* This function shuts down everything in the backtrace MCA
|
||||
* framework, and is called during opal_finalize() and the
|
||||
* special case of the laminfo command.
|
||||
*
|
||||
* It must be the last function invoked on the backtrace MCA framework.
|
||||
*/
|
||||
OMPI_DECLSPEC int opal_backtrace_base_close(void);
|
||||
|
||||
extern opal_list_t opal_backtrace_base_components_opened;
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* OPAL_BASE_BACKTRACE_H */
|
21
opal/mca/backtrace/configure.m4
Обычный файл
21
opal/mca/backtrace/configure.m4
Обычный файл
@ -0,0 +1,21 @@
|
||||
dnl -*- shell-script -*-
|
||||
dnl
|
||||
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
dnl University Research and Technology
|
||||
dnl Corporation. All rights reserved.
|
||||
dnl Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
dnl of Tennessee Research Foundation. All rights
|
||||
dnl reserved.
|
||||
dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
dnl University of Stuttgart. All rights reserved.
|
||||
dnl Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
dnl All rights reserved.
|
||||
dnl $COPYRIGHT$
|
||||
dnl
|
||||
dnl Additional copyrights may follow
|
||||
dnl
|
||||
dnl $HEADER$
|
||||
dnl
|
||||
|
||||
dnl we only want one :)
|
||||
m4_define(MCA_backtrace_CONFIGURE_MODE, STOP_AT_FIRST)
|
30
opal/mca/backtrace/darwin/Makefile.am
Обычный файл
30
opal/mca/backtrace/darwin/Makefile.am
Обычный файл
@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/MoreBacktrace
|
||||
|
||||
noinst_LTLIBRARIES = libmca_backtrace_darwin.la
|
||||
|
||||
libmca_backtrace_darwin_la_SOURCES = \
|
||||
backtrace_darwin.c \
|
||||
backtrace_darwin_component.c \
|
||||
MoreBacktrace/MoreSetup.h \
|
||||
MoreBacktrace/MoreDebugging/MoreAddrToSym.c \
|
||||
MoreBacktrace/MoreDebugging/MoreAddrToSym.h \
|
||||
MoreBacktrace/MoreDebugging/MoreBacktrace.c \
|
||||
MoreBacktrace/MoreDebugging/MoreBacktrace.h
|
@ -0,0 +1,339 @@
|
||||
/*
|
||||
File: MoreAddrToSym.c
|
||||
|
||||
Contains: Code for mapping addresses to their symbolic names.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
$Log: MoreAddrToSym.c,v $
|
||||
Revision 1.2 2006/01/22 22:47:13 eskimo1
|
||||
Significant rewrite to account for changes in MoreBacktrace. Still not as functional as I'd like.
|
||||
|
||||
Revision 1.1 2003/04/04 15:02:57 eskimo1
|
||||
First checked in. This code still has bugs, but I've written enough code that checking in is a good idea.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// Our Prototypes
|
||||
|
||||
#include "MoreAddrToSym.h"
|
||||
|
||||
// Mac OS Interfaces
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/nlist.h>
|
||||
#include <mach-o/stab.h>
|
||||
|
||||
// MIB Prototypes
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int MoreAToSCreate(size_t count, MoreAToSSymInfo *symbols[])
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
|
||||
assert(symbols != NULL);
|
||||
assert(*symbols == NULL);
|
||||
|
||||
err = 0;
|
||||
*symbols = calloc(count, sizeof(MoreAToSSymInfo));
|
||||
if (*symbols == NULL) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
assert( (err == 0) == (*symbols != NULL) );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
extern void MoreAToSDestroy(size_t count, MoreAToSSymInfo symbols[])
|
||||
// See comments in header.
|
||||
{
|
||||
size_t index;
|
||||
|
||||
if (symbols != NULL) {
|
||||
for (index = 0; index < count; index++) {
|
||||
free( (void *) symbols[index].symbolName );
|
||||
}
|
||||
free(symbols);
|
||||
}
|
||||
}
|
||||
|
||||
static int ReplaceSymbolIfBetter(
|
||||
MoreAToSSymInfo * existingSymbol,
|
||||
MoreAToSSymbolType symbolType,
|
||||
const char * symbolName,
|
||||
MoreAToSOffset symbolOffset
|
||||
)
|
||||
// Check to see whether the symbolic information defined by symbolType,
|
||||
// symbolName, and symbolOffset is 'better' than the symbolic information
|
||||
// in existingSymbol. If so, replace the old information with the new.
|
||||
// In this case, 'better' is defined as being having a smaller
|
||||
// symbolOffset, that is, we've found a symbol that's closer to the
|
||||
// requested address.
|
||||
//
|
||||
// The idea behind this code is that one day I'll come up with multiple
|
||||
// ways to get at symbolic information, and then I'll only keep the best
|
||||
// result. However, I don't really use this functionality yet.
|
||||
{
|
||||
int err;
|
||||
bool replace;
|
||||
|
||||
assert(existingSymbol != NULL);
|
||||
assert(symbolType != kMoreAToSNoSymbol);
|
||||
assert(symbolName != NULL);
|
||||
assert( (existingSymbol->symbolType == kMoreAToSNoSymbol) == (existingSymbol->symbolName == NULL) );
|
||||
|
||||
err = 0;
|
||||
|
||||
if (existingSymbol->symbolType == kMoreAToSNoSymbol) {
|
||||
replace = true;
|
||||
} else {
|
||||
replace = (symbolOffset < existingSymbol->symbolOffset);
|
||||
}
|
||||
|
||||
if (replace) {
|
||||
char * tmp;
|
||||
|
||||
tmp = strdup(symbolName);
|
||||
if (tmp == NULL) {
|
||||
err = ENOMEM;
|
||||
} else {
|
||||
free( (void *) existingSymbol->symbolName );
|
||||
|
||||
existingSymbol->symbolType = symbolType;
|
||||
existingSymbol->symbolName = tmp;
|
||||
existingSymbol->symbolOffset = symbolOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// FindOwnerOfPC and GetFunctionName countesy of Ed Wynne. Don't ask me
|
||||
// how it works, or I'll start to whimper. Actually, I have a fairly good idea
|
||||
// how it works, and a fairly good idea how to fix its more serious problems,
|
||||
// but I just don't have time at the moment.
|
||||
|
||||
static const struct mach_header *FindOwnerOfPC(unsigned int pc)
|
||||
{
|
||||
unsigned int count,index,offset,cmdex;
|
||||
struct segment_command * seg;
|
||||
struct load_command * cmd;
|
||||
const struct mach_header * header;
|
||||
|
||||
count = _dyld_image_count();
|
||||
for (index = 0;index < count;index += 1)
|
||||
{
|
||||
header = _dyld_get_image_header(index);
|
||||
offset = _dyld_get_image_vmaddr_slide(index);
|
||||
cmd = (struct load_command*)((char*)header + sizeof(struct mach_header));
|
||||
for (cmdex = 0;cmdex < header->ncmds;cmdex += 1,cmd = (struct load_command*)((char*)cmd + cmd->cmdsize))
|
||||
{
|
||||
switch(cmd->cmd)
|
||||
{
|
||||
case LC_SEGMENT:
|
||||
seg = (struct segment_command*)cmd;
|
||||
if ((pc >= (seg->vmaddr + offset)) && (pc < (seg->vmaddr + offset + seg->vmsize)))
|
||||
return header;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *GetFunctionName(unsigned int pc,unsigned int *offset, bool *publicSymbol)
|
||||
{
|
||||
struct segment_command *seg_linkedit = NULL;
|
||||
struct segment_command *seg_text = NULL;
|
||||
struct symtab_command *symtab = NULL;
|
||||
struct load_command *cmd;
|
||||
const struct mach_header*header;
|
||||
unsigned int vm_slide,file_slide;
|
||||
struct nlist *sym,*symbase;
|
||||
char *strings,*name;
|
||||
unsigned int base,index;
|
||||
|
||||
header = FindOwnerOfPC(pc);
|
||||
if (header != NULL)
|
||||
{
|
||||
cmd = (struct load_command*)((char*)header + sizeof(struct mach_header));
|
||||
for (index = 0;index < header->ncmds;index += 1,cmd = (struct load_command*)((char*)cmd + cmd->cmdsize))
|
||||
{
|
||||
switch(cmd->cmd)
|
||||
{
|
||||
case LC_SEGMENT:
|
||||
if (!strcmp(((struct segment_command*)cmd)->segname,SEG_TEXT))
|
||||
seg_text = (struct segment_command*)cmd;
|
||||
else if (!strcmp(((struct segment_command*)cmd)->segname,SEG_LINKEDIT))
|
||||
seg_linkedit = (struct segment_command*)cmd;
|
||||
break;
|
||||
|
||||
case LC_SYMTAB:
|
||||
symtab = (struct symtab_command*)cmd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((seg_text == NULL) || (seg_linkedit == NULL) || (symtab == NULL))
|
||||
{
|
||||
*offset = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vm_slide = (unsigned long)header - (unsigned long)seg_text->vmaddr;
|
||||
file_slide = ((unsigned long)seg_linkedit->vmaddr - (unsigned long)seg_text->vmaddr) - seg_linkedit->fileoff;
|
||||
symbase = (struct nlist*)((unsigned long)header + (symtab->symoff + file_slide));
|
||||
strings = (char*)((unsigned long)header + (symtab->stroff + file_slide));
|
||||
|
||||
// Look for a global symbol.
|
||||
for (index = 0,sym = symbase;index < symtab->nsyms;index += 1,sym += 1)
|
||||
{
|
||||
if (sym->n_type != N_FUN)
|
||||
continue;
|
||||
|
||||
name = sym->n_un.n_strx ? (strings + sym->n_un.n_strx) : NULL;
|
||||
base = sym->n_value + vm_slide;
|
||||
|
||||
for (index += 1,sym += 1;index < symtab->nsyms;index += 1,sym += 1)
|
||||
if (sym->n_type == N_FUN)
|
||||
break;
|
||||
|
||||
if ((pc >= base) && (pc <= (base + sym->n_value)) && (name != NULL) && (strlen(name) > 0))
|
||||
{
|
||||
*offset = pc - base;
|
||||
*publicSymbol = true;
|
||||
return strdup(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a reasonably close private symbol.
|
||||
for (name = NULL,base = 0xFFFFFFFF,index = 0,sym = symbase;index < symtab->nsyms;index += 1,sym += 1)
|
||||
{
|
||||
if ((sym->n_type & 0x0E) != 0x0E)
|
||||
continue;
|
||||
|
||||
if ((sym->n_value + vm_slide) > pc)
|
||||
continue;
|
||||
|
||||
if ((base != 0xFFFFFFFF) && ((pc - (sym->n_value + vm_slide)) >= (pc - base)))
|
||||
continue;
|
||||
|
||||
name = sym->n_un.n_strx ? (strings + sym->n_un.n_strx) : NULL;
|
||||
base = sym->n_value + vm_slide;
|
||||
}
|
||||
|
||||
*offset = pc - base;
|
||||
*publicSymbol = false;
|
||||
return (name != NULL) ? strdup(name) : NULL;
|
||||
}
|
||||
|
||||
*offset = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern int MoreAToSCopySymbolNamesUsingDyld(
|
||||
size_t count,
|
||||
MoreAToSAddr addresses[],
|
||||
MoreAToSSymInfo symbols[]
|
||||
)
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
size_t index;
|
||||
|
||||
assert(addresses != NULL);
|
||||
assert(symbols != NULL);
|
||||
|
||||
err = 0;
|
||||
for (index = 0; index < count; index++) {
|
||||
const char * thisSymbol;
|
||||
const char * cleanSymbol;
|
||||
unsigned int thisSymbolOffset;
|
||||
bool thisSymbolPublic;
|
||||
MoreAToSSymbolType thisSymbolType;
|
||||
|
||||
thisSymbol = NULL;
|
||||
if (addresses[index] != 0) { // NULL is never a useful symbol
|
||||
thisSymbol = GetFunctionName( (unsigned int) addresses[index], &thisSymbolOffset, &thisSymbolPublic);
|
||||
}
|
||||
if (thisSymbol != NULL) {
|
||||
|
||||
// Mach-O symbols virtually always start with '_'. If there's one there,
|
||||
// let's strip it.
|
||||
|
||||
if (thisSymbol[0] == '_') {
|
||||
cleanSymbol = &thisSymbol[1];
|
||||
} else {
|
||||
cleanSymbol = thisSymbol;
|
||||
}
|
||||
|
||||
if (thisSymbolPublic) {
|
||||
thisSymbolType = kMoreAToSDyldPubliSymbol;
|
||||
} else {
|
||||
thisSymbolType = kMoreAToSDyldPrivateSymbol;
|
||||
}
|
||||
|
||||
err = ReplaceSymbolIfBetter(&symbols[index], thisSymbolType, cleanSymbol, thisSymbolOffset);
|
||||
}
|
||||
|
||||
free( (void *) thisSymbol);
|
||||
|
||||
if (err != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
File: MoreAddrToSym.h
|
||||
|
||||
Contains: Code for mapping addresses to their symbolic names.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
$Log: MoreAddrToSym.h,v $
|
||||
Revision 1.2 2006/01/22 22:47:15 eskimo1
|
||||
Significant rewrite to account for changes in MoreBacktrace. Still not as functional as I'd like.
|
||||
|
||||
Revision 1.1 2003/04/04 15:03:00 eskimo1
|
||||
First checked in. This code still has bugs, but I've written enough code that checking in is a good idea.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// MoreIsBetter Setup
|
||||
|
||||
#include "MoreSetup.h"
|
||||
|
||||
// Mac OS Interfaces
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// IMPORTANT:
|
||||
// This code is currently broken in two ways:
|
||||
//
|
||||
// o If the binary has debugging symbols, you often get a debugging
|
||||
// symbol rather than a real symbol. I believe this is caused by
|
||||
// handling of N_FUN in the GetFunctionName routine. Furthermore,
|
||||
// I believe that it did work previous but something changed in the
|
||||
// Mach-O headers to break it. This warrants serious investigation.
|
||||
//
|
||||
// You can work around this problem by removing the debug symbols
|
||||
// using:
|
||||
//
|
||||
// $ strip -S YourBinaryName
|
||||
//
|
||||
// o It doesn't handle 64-bit Mach-O binaries. This is a simple
|
||||
// limitation of the code, and it should be relatively easy to fix.
|
||||
//
|
||||
// I intend to fix both of these problems with a future rewrite.
|
||||
// Until then, I've decided to live with them.
|
||||
|
||||
typedef uint64_t MoreAToSAddr;
|
||||
typedef uint64_t MoreAToSOffset;
|
||||
|
||||
enum MoreAToSSymbolType {
|
||||
kMoreAToSNoSymbol = 0,
|
||||
kMoreAToSDyldPubliSymbol,
|
||||
kMoreAToSDyldPrivateSymbol
|
||||
};
|
||||
typedef enum MoreAToSSymbolType MoreAToSSymbolType;
|
||||
|
||||
struct MoreAToSSymInfo {
|
||||
MoreAToSSymbolType symbolType;
|
||||
const char * symbolName;
|
||||
MoreAToSOffset symbolOffset;
|
||||
};
|
||||
typedef struct MoreAToSSymInfo MoreAToSSymInfo;
|
||||
|
||||
extern int MoreAToSCreate(size_t count, MoreAToSSymInfo *symbols[]);
|
||||
// Creates a blank MoreAToSSymInfo array with count entries.
|
||||
// You must dispose of it using MoreAToSDestroy.
|
||||
//
|
||||
// symbols must not be NULL
|
||||
// *symbols must be NULL
|
||||
// Returns 0 on success, an errno-style error code otherwise
|
||||
// On success, *symbols will not be NULL
|
||||
// On error, *symbols will be NULL
|
||||
|
||||
extern void MoreAToSDestroy(size_t count, MoreAToSSymInfo symbols[]);
|
||||
// Destroys a MoreAToSDestroy array (blank or filled in) of
|
||||
// count entries.
|
||||
|
||||
extern int MoreAToSCopySymbolNamesUsingDyld(
|
||||
size_t count,
|
||||
MoreAToSAddr addresses[],
|
||||
MoreAToSSymInfo symbols[]
|
||||
);
|
||||
// Given count values in the addresses array, works out the symbolic
|
||||
// information for those values and returns it in the symbols array.
|
||||
//
|
||||
// Returns 0 on success, an errno-style error code otherwise
|
||||
//
|
||||
// Note that not being able to map an address to a symbol is not
|
||||
// considered an error. Rather, you get NULL back in the symbolName
|
||||
// field of the corresponding symbols array element.
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1755
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktrace.c
Обычный файл
1755
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktrace.c
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -0,0 +1,274 @@
|
||||
/*
|
||||
File: MoreBacktrace.h
|
||||
|
||||
Contains: Code for generating backtraces.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
$Log: MoreBacktrace.h,v $
|
||||
Revision 1.4 2006/01/22 22:46:48 eskimo1
|
||||
Complete rewrite to account for architecture independence.
|
||||
|
||||
Revision 1.3 2003/04/09 22:48:15 eskimo1
|
||||
Added comments.
|
||||
|
||||
Revision 1.2 2003/04/09 21:58:18 eskimo1
|
||||
Removed the "uncertain PC" flag. I may need to bring it back later, but for now I never use it so there's no point declaring it.
|
||||
|
||||
Revision 1.1 2003/04/04 15:03:08 eskimo1
|
||||
First checked in. This code still has bugs, but I've written enough code that checking in is a good idea.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// MoreIsBetter Setup
|
||||
|
||||
#include "MoreSetup.h"
|
||||
|
||||
// Mac OS Interfaces
|
||||
|
||||
// Put <mach/mach.h> inside extern "C" guards for the C++ build
|
||||
// because the Mach header files don't always have them.
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#if TARGET_RT_MAC_CFM
|
||||
#error MoreBacktrace no longer supports CFM builds.
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Overview
|
||||
--------
|
||||
This module implements a number of backtrace routines. All
|
||||
of the routines are implemented in terms of a common core.
|
||||
The code is structured in a very generic way. For example, if
|
||||
you were running on a version of Mach that support inter-machine
|
||||
messaging, it would be feasible to do a backtrace of a PowerPC
|
||||
program from program executing a completely different instruction
|
||||
set architecture (ISA).
|
||||
|
||||
IMPORTANT:
|
||||
The current code does not support cross-architecture backtraces
|
||||
because of technical limitations (specifically, I haven't had
|
||||
time to implement cross-architecture symbol translation, which
|
||||
is required for cross-architecture backtraces to work properly;
|
||||
see the comments for InitSigTrampAddress in the implementation
|
||||
file for the details).
|
||||
|
||||
Backtraces are inherently processor-specific. Internal to this
|
||||
module is a ISA later than adapts the backtrace for various ISA.
|
||||
Currently it supports PowerPC (32-bit), PowerPC (64-bit), and
|
||||
Intel (32-bit).
|
||||
|
||||
If you're curious about how stack frames work for each ISA, check
|
||||
out the comments in the implementation file. The comments in the
|
||||
header focus on how you use these routines.
|
||||
*/
|
||||
|
||||
/* Changes Since Previous Version
|
||||
------------------------------
|
||||
If you used the previous version of this code, please note the
|
||||
following changes:
|
||||
|
||||
o Everything has changed (-:
|
||||
|
||||
I completely rewrote this code to support multiple architectures.
|
||||
By including support for PowerPC (64-bit), I was forced to
|
||||
eliminate my dependencies on CoreServices (which isn't available
|
||||
to PowerPC (64-bit) on Mac OS X 10.4.x), which means now I depend
|
||||
solely on the System framework. Also, because I had to support
|
||||
Intel, which requires Mach-O, I decided to drop support for CFM.
|
||||
My theory is that anyone who wants to adopt the new version of this
|
||||
module is doing so because they're porting to Intel, and those folks
|
||||
have to leave their CFM build behind.
|
||||
|
||||
The good news is that the new implementation is very similar
|
||||
in spirit to the old, and it should be very easy for you to
|
||||
adopt the new code.
|
||||
*/
|
||||
|
||||
// Within this module, I treat all addresses as 64-bit. That way
|
||||
// the code doesn't change for 64-bit and 32-bit architectures.
|
||||
//
|
||||
// Note:
|
||||
// I could have made this type scale with the current pointer size,
|
||||
// but my eventual goal is to support cross-architecture backtraces,
|
||||
// which means I wanted a size that's at least as big as the 'largest'
|
||||
// architecture I support.
|
||||
|
||||
typedef uint64_t MoreBTAddr;
|
||||
|
||||
// The following flags provide information about a specific frame in
|
||||
// a backtrace.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// kMoreBTFrameBadMask is set for the last frame in the backtrace
|
||||
// (where we've run off the end of the stack), but it can also be set
|
||||
// for intermediate frames (where we've detected a frameless leaf
|
||||
// routine, either at the top of the stack or as part of crossing
|
||||
// a signal frame).
|
||||
|
||||
typedef int MoreBTFlags;
|
||||
enum {
|
||||
kMoreBTFrameBadMask = 0x0001, // this frame pointer is bad
|
||||
kMoreBTPCBadMask = 0x0002, // this PC is bad
|
||||
kMoreBTSignalHandlerMask = 0x0004 // this frame is a signal handler
|
||||
};
|
||||
|
||||
// The end result of a backtrace is an array of MoreBTFrame
|
||||
// structures describing a particular frame in the backtrace.
|
||||
//
|
||||
// Note:
|
||||
// The PC points to the code that's using the frame. It is not
|
||||
// the return address for that code. On architectures where the
|
||||
// frame holds the return address (Intel, but not PowerPC), I do
|
||||
// the appropriate corrections.
|
||||
|
||||
struct MoreBTFrame {
|
||||
MoreBTAddr pc; // PC for this function invocation
|
||||
MoreBTAddr fp; // frame pointer for this function invocation
|
||||
MoreBTFlags flags; // various flags, see above
|
||||
};
|
||||
typedef struct MoreBTFrame MoreBTFrame;
|
||||
|
||||
/* Common Parameters
|
||||
-----------------
|
||||
All of the backtrace routines accept certain common parameters.
|
||||
|
||||
o function result -- This is an errno-style error code.
|
||||
|
||||
o stackBottom and stackTop -- These define the extent of the stack
|
||||
which you are tracing. If this information isn't handy, supply
|
||||
0 for both. Supplying meaningful values can reduce the number
|
||||
of bogus frames reported if the stack is corrupt.
|
||||
|
||||
o frameArray and frameArrayCount -- These define an array of stack
|
||||
frames that the routines fill out. You can supply NULL and 0
|
||||
(respectively) if you're not interested in getting the actual
|
||||
frame data (typically you do this to get the count of the number
|
||||
of frames via frameCount). The routines do not fail if this
|
||||
buffer is exhausted. Instead they simply return as many frames
|
||||
as they can and continue tracing, returning an accurate value
|
||||
for frameCount.
|
||||
|
||||
o frameCountPtr -- You can use this to get back an accurate count of
|
||||
the number of frames in the stack. If you're not interested
|
||||
in this information, you can pass NULL.
|
||||
|
||||
IMPORTANT:
|
||||
Because of the above, on return, *frameCountPtr can be larger than
|
||||
frameArrayCount.
|
||||
|
||||
The following assertions apply to these common parameters.
|
||||
|
||||
o On entry, stackBottom and stackTop must both be zero, or stackBottom
|
||||
must be strictly less than stackTop.
|
||||
|
||||
o On entry, if frameArrayCount is not zero, frameArray must be not NULL.
|
||||
|
||||
o On entry, frameCountPtr must not be NULL.
|
||||
|
||||
o On return, *frameCountPtr will be the number of frames that were
|
||||
found. On success, this is likely to be a meaningful number. On
|
||||
error, this just indicates how far we got.
|
||||
|
||||
o On return, if frameArrayCount is not NULL, frame data has been placed
|
||||
into the frame array. The number of valid entries is
|
||||
min(frameArray, *frameArrayCount).
|
||||
*/
|
||||
|
||||
extern int MoreBacktraceMachSelf(
|
||||
MoreBTAddr stackBottom,
|
||||
MoreBTAddr stackTop,
|
||||
MoreBTFrame * frameArray,
|
||||
size_t frameArrayCount,
|
||||
size_t * frameCountPtr
|
||||
);
|
||||
// Does a backtrace of the current thread. All of the parameters
|
||||
// are described by the "Common Parameters" section above.
|
||||
|
||||
extern int MoreBacktraceMachThread(
|
||||
task_t task,
|
||||
thread_t thread,
|
||||
MoreBTAddr stackBottom,
|
||||
MoreBTAddr stackTop,
|
||||
MoreBTFrame * frameArray,
|
||||
size_t frameArrayCount,
|
||||
size_t * frameCountPtr
|
||||
);
|
||||
// Does a backtrace of a particular thread within a particular tasks.
|
||||
// The common parameters (stackBottom and later) are described by the
|
||||
// "Common Parameters" section above. The task parameter must a
|
||||
// task control port; for a thread in the current task, use
|
||||
// mach_task_self to get this value. The thread parameter is the thread
|
||||
// to sample. It's generally inappropriate to use mach_thread_self
|
||||
// (call MoreBacktraceMachSelf instead), but it does work.
|
||||
//
|
||||
// On entry, task must not be MACH_PORT_NULL.
|
||||
// On entry, thread must not be MACH_PORT_NULL.
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Двоичные данные
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/._MainWindow.nib
сгенерированный
Обычный файл
Двоичные данные
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/._MainWindow.nib
сгенерированный
Обычный файл
Двоичный файл не отображается.
Двоичные данные
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/._main.nib
сгенерированный
Обычный файл
Двоичные данные
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/._main.nib
сгенерированный
Обычный файл
Двоичный файл не отображается.
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>MoreBacktraceTest</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.dts.MoreIsBetter.MoreBacktraceTest</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>MoreBacktraceTest</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
4
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/MainWindow.nib/classes.nib
сгенерированный
Обычный файл
4
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/MainWindow.nib/classes.nib
сгенерированный
Обычный файл
@ -0,0 +1,4 @@
|
||||
{
|
||||
IBClasses = ();
|
||||
IBVersion = 1;
|
||||
}
|
18
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/MainWindow.nib/info.nib
сгенерированный
Обычный файл
18
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/MainWindow.nib/info.nib
сгенерированный
Обычный файл
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>69 10 356 240 0 0 1280 832 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>443.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>166</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>8G32</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCarbonFramework</string>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<object class="NSIBObjectData">
|
||||
<string name="targetFramework">IBCarbonFramework</string>
|
||||
<object name="rootObject" class="NSCustomObject" id="1">
|
||||
<string name="customClass">NSApplication</string>
|
||||
</object>
|
||||
<array count="9" name="allObjects">
|
||||
<object class="IBCarbonWindow" id="166">
|
||||
<string name="windowRect">51 8 649 747 </string>
|
||||
<string name="title">MoreBacktraceTest</string>
|
||||
<object name="rootControl" class="IBCarbonRootControl" id="167">
|
||||
<string name="bounds">0 0 598 739 </string>
|
||||
<array count="7" name="subviews">
|
||||
<object class="IBCarbonButton" id="199">
|
||||
<string name="bounds">20 20 40 245 </string>
|
||||
<string name="title">MoreBacktraceMachSelf</string>
|
||||
<ostype name="command">btMS</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonButton" id="202">
|
||||
<string name="bounds">20 251 40 488 </string>
|
||||
<string name="title">MoreBacktraceMachThread</string>
|
||||
<ostype name="command">btMT</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonEditText" id="203">
|
||||
<string name="bounds">23 536 39 613 </string>
|
||||
<ostype name="controlSignature">PIDT</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonStaticText" id="204">
|
||||
<string name="bounds">22 494 38 525 </string>
|
||||
<string name="title">PID:</string>
|
||||
</object>
|
||||
<object class="IBCarbonButton" id="205">
|
||||
<string name="bounds">52 257 72 482 </string>
|
||||
<string name="title">Signal Test</string>
|
||||
<ostype name="command">btST</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonButton" id="208">
|
||||
<string name="bounds">52 20 72 245 </string>
|
||||
<string name="title">Stack Smash Test</string>
|
||||
<ostype name="command">btSS</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonEditText" id="209">
|
||||
<string name="bounds">95 23 575 716 </string>
|
||||
<ostype name="controlSignature">ETXT</ostype>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<boolean name="hasCloseBox">FALSE</boolean>
|
||||
<boolean name="hasHorizontalZoom">FALSE</boolean>
|
||||
<boolean name="isResizable">FALSE</boolean>
|
||||
<boolean name="hasVerticalZoom">FALSE</boolean>
|
||||
<int name="windowPosition">1</int>
|
||||
</object>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="199"/>
|
||||
<reference idRef="202"/>
|
||||
<reference idRef="203"/>
|
||||
<reference idRef="204"/>
|
||||
<reference idRef="205"/>
|
||||
<reference idRef="208"/>
|
||||
<reference idRef="209"/>
|
||||
</array>
|
||||
<array count="9" name="allParents">
|
||||
<reference idRef="1"/>
|
||||
<reference idRef="166"/>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="167"/>
|
||||
<reference idRef="167"/>
|
||||
</array>
|
||||
<dictionary count="2" name="nameTable">
|
||||
<string>Files Owner</string>
|
||||
<reference idRef="1"/>
|
||||
<string>MainWindow</string>
|
||||
<reference idRef="166"/>
|
||||
</dictionary>
|
||||
<unsigned_int name="nextObjectID">248</unsigned_int>
|
||||
</object>
|
@ -0,0 +1,573 @@
|
||||
/*
|
||||
File: MoreBacktraceTest.c
|
||||
|
||||
Contains: A simple program to test MoreBacktrace.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "MoreSetup.h"
|
||||
|
||||
// System prototypes
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
// Our interfaces
|
||||
|
||||
#include "MoreBacktraceTestCommon.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** Utilities
|
||||
|
||||
static OSStatus GetControlByIDQ(WindowRef inWindow, OSType signature, SInt32 id, ControlRef *outControl)
|
||||
// A simple wrapper around GetControlByID.
|
||||
{
|
||||
ControlID theID;
|
||||
|
||||
theID.signature = signature;
|
||||
theID.id = id;
|
||||
return GetControlByID(inWindow, &theID, outControl);
|
||||
}
|
||||
|
||||
static OSStatus FindFinderProcess(ProcessSerialNumber *psnPtr)
|
||||
// Find the ProcessSerialNumber of the Finder process.
|
||||
{
|
||||
OSStatus err;
|
||||
ProcessInfoRec info;
|
||||
Boolean found;
|
||||
|
||||
psnPtr->lowLongOfPSN = kNoProcess;
|
||||
psnPtr->highLongOfPSN = kNoProcess;
|
||||
|
||||
found = false;
|
||||
do {
|
||||
err = GetNextProcess(psnPtr);
|
||||
if (err == noErr) {
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
err = GetProcessInformation(psnPtr, &info);
|
||||
if (err == noErr) {
|
||||
found = (info.processSignature == 'MACS');
|
||||
}
|
||||
}
|
||||
} while ( (err == noErr) && ! found );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** Compile-Time Parameters
|
||||
|
||||
// We hard-code our output to Monaco 10. This is bad programming,
|
||||
// but it suffices for a simple hack like this.
|
||||
|
||||
static const UInt8 kOutputFont[] = "\pMonaco";
|
||||
static const SInt16 kOutputSize = 10;
|
||||
|
||||
// The main text field will display about 70 frames, so that's all that
|
||||
// we ask for. This is more than enough for our tests.
|
||||
|
||||
enum {
|
||||
kFrameCount = 70
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** GUI Infrastructure
|
||||
|
||||
static void DoAbout(void)
|
||||
// Displays the about box.
|
||||
{
|
||||
SInt16 junkHit;
|
||||
|
||||
(void) StandardAlert(kAlertPlainAlert, "\pMoreBacktraceTest", "\pA simple program to test MoreBacktrace.\r\rDTS\r\rй 2006 Apple Computer, Inc.", NULL, &junkHit);
|
||||
}
|
||||
|
||||
static void DisplayError(OSStatus errNum)
|
||||
{
|
||||
OSStatus junk;
|
||||
Str255 errStr;
|
||||
SInt16 junkHit;
|
||||
|
||||
if ( (errNum != noErr) && (errNum != userCanceledErr) ) {
|
||||
NumToString(errNum, errStr);
|
||||
|
||||
junk = StandardAlert(kAlertStopAlert, "\pError.", errStr, NULL, &junkHit);
|
||||
assert(junk == noErr);
|
||||
}
|
||||
}
|
||||
|
||||
static ControlRef gOutputText = NULL;
|
||||
static ControlRef gPIDText = NULL;
|
||||
|
||||
static OSStatus SetOutputText(CFStringRef newText)
|
||||
// Put newText into the output edit text control.
|
||||
// We use an edit text control because it's
|
||||
// a) easy, b) handles multiple lines of text, and
|
||||
// c) allows the user to copy the results.
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
assert(newText != NULL);
|
||||
|
||||
err = SetControlData(gOutputText, kControlEntireControl, kControlEditTextCFStringTag, sizeof(newText), &newText);
|
||||
Draw1Control(gOutputText);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ClearOutput(void)
|
||||
// Clear the output text.
|
||||
{
|
||||
OSStatus junk;
|
||||
|
||||
junk = SetOutputText(CFSTR(""));
|
||||
assert(junk == noErr);
|
||||
}
|
||||
|
||||
static OSStatus OutputFrames(char *bt)
|
||||
// Output a textual description of frameCount frames from frameArray
|
||||
// into the output text control. Actually generating the text from
|
||||
// the frame array is handled by the common test code; all we have
|
||||
// to do here is reflow the text into two columns so it fits in
|
||||
// our text field.
|
||||
{
|
||||
OSStatus err;
|
||||
Boolean removedOne;
|
||||
size_t row;
|
||||
size_t col;
|
||||
CFStringRef btStr;
|
||||
CFArrayRef frameStrings;
|
||||
size_t frameCount;
|
||||
size_t frameIndex;
|
||||
CFMutableStringRef result;
|
||||
|
||||
btStr = NULL;
|
||||
frameStrings = NULL;
|
||||
result = NULL;
|
||||
|
||||
// Remove any trailing newlines.
|
||||
|
||||
removedOne = false;
|
||||
do {
|
||||
size_t len;
|
||||
|
||||
len = strlen(bt);
|
||||
if (len > 0 && bt[len] == '\n') {
|
||||
bt[len] = 0;
|
||||
removedOne = true;
|
||||
}
|
||||
} while ( removedOne );
|
||||
|
||||
// Break the string up into lines.
|
||||
|
||||
err = noErr;
|
||||
btStr = CFStringCreateWithCString(NULL, bt, kCFStringEncodingUTF8);
|
||||
if (btStr == NULL) {
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
|
||||
if (err == noErr) {
|
||||
frameStrings = CFStringCreateArrayBySeparatingStrings(NULL, btStr, CFSTR("\n"));
|
||||
if (frameStrings == NULL) {
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
assert(frameStrings != NULL);
|
||||
}
|
||||
|
||||
// Count the frames and then place it into the output text field.
|
||||
|
||||
if (err == noErr) {
|
||||
frameCount = (size_t) CFArrayGetCount(frameStrings);
|
||||
|
||||
result = CFStringCreateMutable(NULL, 0);
|
||||
if (result == NULL) {
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
}
|
||||
if (err == noErr) {
|
||||
if ( frameCount > (kFrameCount / 2) ) {
|
||||
|
||||
// We need two columns, so reflow. Nasty.
|
||||
|
||||
for (row = 0; row < (kFrameCount / 2); row++) {
|
||||
for (col = 0; col < 2; col++) {
|
||||
frameIndex = (col * (kFrameCount / 2)) + row;
|
||||
|
||||
if (frameIndex < frameCount) {
|
||||
CFStringRef frameStr;
|
||||
CFStringRef frameStrTrimmed;
|
||||
CFStringRef columnPad;
|
||||
|
||||
columnPad = NULL;
|
||||
frameStrTrimmed = NULL;
|
||||
|
||||
frameStr = CFArrayGetValueAtIndex(frameStrings, frameIndex);
|
||||
assert(frameStr != NULL);
|
||||
|
||||
if ( CFStringGetLength(frameStr) > 56 ) {
|
||||
frameStrTrimmed = CFStringCreateWithSubstring(NULL, frameStr, CFRangeMake(0, 56));
|
||||
columnPad = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);
|
||||
} else {
|
||||
frameStrTrimmed = CFRetain(frameStr);
|
||||
if (col == 0) {
|
||||
columnPad = CFStringCreateWithFormat(NULL, NULL, CFSTR("%*.*s"), 56 - CFStringGetLength(frameStr), 56 - CFStringGetLength(frameStr), "");
|
||||
} else {
|
||||
columnPad = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);
|
||||
}
|
||||
}
|
||||
assert(frameStrTrimmed != NULL);
|
||||
assert(columnPad != NULL);
|
||||
|
||||
if ( (frameStrTrimmed != NULL) && (columnPad != NULL) ) {
|
||||
CFStringAppendFormat(result, NULL, CFSTR("%@%@"), frameStrTrimmed, columnPad);
|
||||
if (col == 0) {
|
||||
CFStringAppend(result, CFSTR(" "));
|
||||
}
|
||||
}
|
||||
|
||||
if (columnPad != NULL) {
|
||||
CFRelease(columnPad);
|
||||
}
|
||||
if (frameStrTrimmed != NULL) {
|
||||
CFRelease(frameStrTrimmed);
|
||||
}
|
||||
}
|
||||
}
|
||||
CFStringAppend(result, CFSTR("\r"));
|
||||
}
|
||||
} else {
|
||||
|
||||
// We can get away with a single column.
|
||||
|
||||
for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
CFStringAppendFormat(result, NULL, CFSTR("%@\r"), CFArrayGetValueAtIndex(frameStrings, frameIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put the string into the control.
|
||||
|
||||
if (err == noErr) {
|
||||
err = SetOutputText(result);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
|
||||
if (btStr != NULL) {
|
||||
CFRelease(btStr);
|
||||
}
|
||||
if (frameStrings != NULL) {
|
||||
CFRelease(frameStrings);
|
||||
}
|
||||
if (result != NULL) {
|
||||
CFRelease(result);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** Test Handlers
|
||||
|
||||
static void GUITestMoreBacktraceMachSelf(void)
|
||||
// Run in response to a click of the "MoreBacktraceMachSelf"
|
||||
// button. It does the test and displays the result.
|
||||
{
|
||||
OSStatus err;
|
||||
char * bt;
|
||||
|
||||
ClearOutput();
|
||||
|
||||
bt = NULL;
|
||||
err = TestMoreBacktraceMachSelf(&bt);
|
||||
if (err == noErr) {
|
||||
err = OutputFrames(bt);
|
||||
}
|
||||
DisplayError(err);
|
||||
free(bt);
|
||||
}
|
||||
|
||||
static void GUITestMoreBacktraceMachThread(void)
|
||||
// Run in response to a click of the "MoreBacktraceMachThread"
|
||||
// button. It does the test and displays the result. It gets
|
||||
// the target PID from the "PID" field.
|
||||
{
|
||||
OSStatus err;
|
||||
CFStringRef pidStr;
|
||||
pid_t pid;
|
||||
char * bt;
|
||||
|
||||
ClearOutput();
|
||||
|
||||
bt = NULL;
|
||||
pidStr = NULL;
|
||||
|
||||
// Get the PID of the process to sample from the
|
||||
// gPIDText edit text control and convert that to
|
||||
// the Mach task control port.
|
||||
|
||||
err = GetControlData(gPIDText, kControlEntireControl, kControlEditTextCFStringTag, sizeof(pidStr), &pidStr, NULL);
|
||||
if (err == noErr) {
|
||||
pid = (pid_t) CFStringGetIntValue(pidStr);
|
||||
}
|
||||
if (err == noErr) {
|
||||
err = TestMoreBacktraceMachThread(pid, &bt);
|
||||
}
|
||||
if (err == noErr) {
|
||||
err = OutputFrames(bt);
|
||||
}
|
||||
DisplayError(err);
|
||||
|
||||
// Clean up.
|
||||
|
||||
free(bt);
|
||||
if (pidStr != NULL) {
|
||||
CFRelease(pidStr);
|
||||
}
|
||||
}
|
||||
|
||||
static void GUITestSignalBacktrace(void)
|
||||
// Run in response to a click of the "Signal Test"
|
||||
// button. It does the test and displays the result.
|
||||
{
|
||||
OSStatus err;
|
||||
char * bt;
|
||||
|
||||
bt = NULL;
|
||||
|
||||
ClearOutput();
|
||||
|
||||
// Call a routine that sends a signal to us.
|
||||
|
||||
err = TestMoreBacktraceMachSelfSignal(false, &bt);
|
||||
if (err == noErr) {
|
||||
err = OutputFrames(bt);
|
||||
}
|
||||
DisplayError(err);
|
||||
|
||||
free(bt);
|
||||
}
|
||||
|
||||
static void GUITestStackSmash(void)
|
||||
// Run in response to a click of the "Stack Smash Test"
|
||||
// button. It does the test and displays the result.
|
||||
{
|
||||
OSStatus err;
|
||||
char * bt;
|
||||
|
||||
ClearOutput();
|
||||
|
||||
bt = NULL;
|
||||
|
||||
err = TestMoreBacktraceMachThreadStackSmash(&bt);
|
||||
if (err == noErr) {
|
||||
err = OutputFrames(bt);
|
||||
}
|
||||
DisplayError(err);
|
||||
|
||||
free(bt);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** Boilerplate Application Stuff
|
||||
|
||||
static EventHandlerUPP gApplicationEventHandlerUPP; // -> ApplicationEventHandler
|
||||
|
||||
static const EventTypeSpec kApplicationEvents[] = { {kEventClassCommand, kEventCommandProcess} };
|
||||
|
||||
static pascal OSStatus ApplicationEventHandler(EventHandlerCallRef inHandlerCallRef,
|
||||
EventRef inEvent, void *inUserData)
|
||||
// Dispatches HICommands to their implementations.
|
||||
{
|
||||
OSStatus err;
|
||||
HICommand command;
|
||||
#pragma unused(inHandlerCallRef)
|
||||
#pragma unused(inUserData)
|
||||
|
||||
assert( GetEventClass(inEvent) == kEventClassCommand );
|
||||
assert( GetEventKind(inEvent) == kEventCommandProcess);
|
||||
|
||||
err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command);
|
||||
if (err == noErr) {
|
||||
switch (command.commandID) {
|
||||
case kHICommandAbout:
|
||||
DoAbout();
|
||||
break;
|
||||
case 'btMS':
|
||||
GUITestMoreBacktraceMachSelf();
|
||||
break;
|
||||
case 'btMT':
|
||||
GUITestMoreBacktraceMachThread();
|
||||
break;
|
||||
case 'btST':
|
||||
GUITestSignalBacktrace();
|
||||
break;
|
||||
case 'btSS':
|
||||
GUITestStackSmash();
|
||||
break;
|
||||
default:
|
||||
err = eventNotHandledErr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
OSStatus err;
|
||||
IBNibRef nibRef;
|
||||
WindowRef window;
|
||||
#pragma unused(argc)
|
||||
#pragma unused(argv)
|
||||
|
||||
// DebugStr("\pmain");
|
||||
|
||||
nibRef = NULL;
|
||||
|
||||
// Create menu bar from NIB.
|
||||
|
||||
err = CreateNibReference(CFSTR("main"), &nibRef);
|
||||
if (err == noErr) {
|
||||
err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
|
||||
}
|
||||
if (nibRef != NULL) {
|
||||
DisposeNibReference(nibRef);
|
||||
nibRef = NULL;
|
||||
}
|
||||
|
||||
// Create main window from NIB.
|
||||
|
||||
if (err == noErr) {
|
||||
err = CreateNibReference(CFSTR("MainWindow"), &nibRef);
|
||||
}
|
||||
if (err == noErr) {
|
||||
err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
|
||||
}
|
||||
if (nibRef != NULL) {
|
||||
DisposeNibReference(nibRef);
|
||||
nibRef = NULL;
|
||||
}
|
||||
|
||||
// Install our HICommand handler.
|
||||
|
||||
if (err == noErr) {
|
||||
gApplicationEventHandlerUPP = NewEventHandlerUPP(ApplicationEventHandler);
|
||||
assert(gApplicationEventHandlerUPP != NULL);
|
||||
|
||||
err = InstallApplicationEventHandler(gApplicationEventHandlerUPP,
|
||||
GetEventTypeCount(kApplicationEvents),
|
||||
kApplicationEvents, NULL, NULL);
|
||||
}
|
||||
|
||||
// Get the output static text control and set it to Monaco 9.
|
||||
|
||||
if (err == noErr) {
|
||||
err = GetControlByIDQ(window, 'ETXT', 0, &gOutputText);
|
||||
}
|
||||
if (err == noErr) {
|
||||
ControlFontStyleRec styleRec;
|
||||
SInt16 monacoFontNum;
|
||||
|
||||
GetFNum(kOutputFont, &monacoFontNum);
|
||||
|
||||
styleRec.flags = kControlUseFontMask | kControlUseSizeMask;
|
||||
styleRec.font = monacoFontNum;
|
||||
styleRec.size = kOutputSize;
|
||||
|
||||
err = SetControlData(gOutputText, kControlEntireControl, kControlStaticTextStyleTag,
|
||||
sizeof(styleRec), &styleRec);
|
||||
}
|
||||
|
||||
// Get the PID edit text field and initialise it to the Finder's PID.
|
||||
|
||||
if (err == noErr) {
|
||||
err = GetControlByIDQ(window, 'PIDT', 0, &gPIDText);
|
||||
}
|
||||
if (err == noErr) {
|
||||
ProcessSerialNumber finderPSN;
|
||||
pid_t finderPID;
|
||||
CFStringRef finderPIDStr;
|
||||
|
||||
finderPIDStr = NULL;
|
||||
|
||||
err = FindFinderProcess(&finderPSN);
|
||||
if (err == noErr) {
|
||||
err = GetProcessPID(&finderPSN, &finderPID);
|
||||
}
|
||||
if (err == noErr) {
|
||||
finderPIDStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), (long) finderPID);
|
||||
if (finderPIDStr == NULL) {
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
}
|
||||
if (err == noErr) {
|
||||
err = SetControlData(gPIDText, kControlEntireControl, kControlEditTextCFStringTag, sizeof(finderPIDStr), &finderPIDStr);
|
||||
}
|
||||
|
||||
if (finderPIDStr) {
|
||||
CFRelease(finderPIDStr);
|
||||
}
|
||||
|
||||
// I don't want to refuse to start up just because this code failed,
|
||||
// so swallow any error.
|
||||
|
||||
assert(err == noErr);
|
||||
err = noErr;
|
||||
}
|
||||
|
||||
if (err == noErr) {
|
||||
// The window was created hidden so show it.
|
||||
|
||||
ShowWindow( window );
|
||||
|
||||
// Call the event loop
|
||||
|
||||
RunApplicationEventLoop();
|
||||
}
|
||||
|
||||
return (err == noErr) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
@ -0,0 +1,424 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E42C50FB097D62FC00D1B30B /* MoreBacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D9D9CA043A170400002802 /* MoreBacktrace.h */; };
|
||||
E42C50FC097D62FC00D1B30B /* MoreSetup.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D9D9CD043A171200002802 /* MoreSetup.h */; };
|
||||
E42C5104097D62FC00D1B30B /* MoreAddrToSym.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E6C079043DD1A000002802 /* MoreAddrToSym.h */; };
|
||||
E42C5108097D62FC00D1B30B /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = E4D9D9D3043AEDB800002802 /* main.nib */; };
|
||||
E42C5109097D62FC00D1B30B /* MainWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = E4A2067F0444ADE300002802 /* MainWindow.nib */; };
|
||||
E42C510B097D62FC00D1B30B /* MoreBacktrace.c in Sources */ = {isa = PBXBuildFile; fileRef = E4D9D9C9043A170400002802 /* MoreBacktrace.c */; };
|
||||
E42C510C097D62FC00D1B30B /* MoreBacktraceTest.c in Sources */ = {isa = PBXBuildFile; fileRef = E4D9D9CF043A172300002802 /* MoreBacktraceTest.c */; };
|
||||
E42C5114097D62FC00D1B30B /* MoreAddrToSym.c in Sources */ = {isa = PBXBuildFile; fileRef = E4E6C078043DD1A000002802 /* MoreAddrToSym.c */; };
|
||||
E42C5117097D62FC00D1B30B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
|
||||
E42C5285097D728200D1B30B /* MoreBacktraceTestTool.c in Sources */ = {isa = PBXBuildFile; fileRef = E42C5163097D6D7400D1B30B /* MoreBacktraceTestTool.c */; };
|
||||
E4CA23DB0982F7690043C210 /* MoreBacktrace.c in Sources */ = {isa = PBXBuildFile; fileRef = E4D9D9C9043A170400002802 /* MoreBacktrace.c */; };
|
||||
E4CA24050982FE650043C210 /* MoreBacktraceTestCommon.c in Sources */ = {isa = PBXBuildFile; fileRef = E4CA24040982FE650043C210 /* MoreBacktraceTestCommon.c */; };
|
||||
E4CA24060982FE650043C210 /* MoreBacktraceTestCommon.c in Sources */ = {isa = PBXBuildFile; fileRef = E4CA24040982FE650043C210 /* MoreBacktraceTestCommon.c */; };
|
||||
E4CA24080982FE6C0043C210 /* MoreBacktraceTestCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = E4CA24070982FE6C0043C210 /* MoreBacktraceTestCommon.h */; };
|
||||
E4CA25F709831B6D0043C210 /* MoreAddrToSym.c in Sources */ = {isa = PBXBuildFile; fileRef = E4E6C078043DD1A000002802 /* MoreAddrToSym.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildStyle section */
|
||||
4A9504C5FFE6A39111CA0CBA /* Development */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
OPTIMIZATION_CFLAGS = "-O0";
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
4A9504C6FFE6A39111CA0CBA /* Deployment */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
/* End PBXBuildStyle section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
E42C511D097D62FC00D1B30B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
E42C511E097D62FC00D1B30B /* MoreBacktraceTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MoreBacktraceTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E42C5163097D6D7400D1B30B /* MoreBacktraceTestTool.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = MoreBacktraceTestTool.c; sourceTree = "<group>"; };
|
||||
E42C5172097D6E1D00D1B30B /* MoreBacktraceTestTool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MoreBacktraceTestTool; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4A2067F0444ADE300002802 /* MainWindow.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = MainWindow.nib; sourceTree = "<group>"; };
|
||||
E4CA24040982FE650043C210 /* MoreBacktraceTestCommon.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = MoreBacktraceTestCommon.c; sourceTree = "<group>"; };
|
||||
E4CA24070982FE6C0043C210 /* MoreBacktraceTestCommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MoreBacktraceTestCommon.h; sourceTree = "<group>"; };
|
||||
E4D9D9C9043A170400002802 /* MoreBacktrace.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = MoreBacktrace.c; path = ../MoreBacktrace.c; sourceTree = SOURCE_ROOT; };
|
||||
E4D9D9CA043A170400002802 /* MoreBacktrace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MoreBacktrace.h; path = ../MoreBacktrace.h; sourceTree = SOURCE_ROOT; };
|
||||
E4D9D9CD043A171200002802 /* MoreSetup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MoreSetup.h; path = ../../MoreSetup.h; sourceTree = SOURCE_ROOT; };
|
||||
E4D9D9CF043A172300002802 /* MoreBacktraceTest.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = MoreBacktraceTest.c; sourceTree = "<group>"; };
|
||||
E4D9D9D3043AEDB800002802 /* main.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = main.nib; sourceTree = "<group>"; };
|
||||
E4E6C078043DD1A000002802 /* MoreAddrToSym.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = MoreAddrToSym.c; path = ../MoreAddrToSym.c; sourceTree = SOURCE_ROOT; };
|
||||
E4E6C079043DD1A000002802 /* MoreAddrToSym.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MoreAddrToSym.h; path = ../MoreAddrToSym.h; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
E42C5116097D62FC00D1B30B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E42C5117097D62FC00D1B30B /* Carbon.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E42C5170097D6E1D00D1B30B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
195DF8CFFE9D517E11CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E42C511E097D62FC00D1B30B /* MoreBacktraceTest.app */,
|
||||
E42C5172097D6E1D00D1B30B /* MoreBacktraceTestTool */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
20286C29FDCF999611CA2CEA /* MoreBacktraceTest */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4DA7D6B09843FE2000630D1 /* Test Code */,
|
||||
20286C2AFDCF999611CA2CEA /* Reusable Code */,
|
||||
195DF8CFFE9D517E11CA2CBB /* Products */,
|
||||
E42C511D097D62FC00D1B30B /* Info.plist */,
|
||||
);
|
||||
name = MoreBacktraceTest;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
20286C2AFDCF999611CA2CEA /* Reusable Code */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4E6C079043DD1A000002802 /* MoreAddrToSym.h */,
|
||||
E4E6C078043DD1A000002802 /* MoreAddrToSym.c */,
|
||||
E4D9D9CA043A170400002802 /* MoreBacktrace.h */,
|
||||
E4D9D9C9043A170400002802 /* MoreBacktrace.c */,
|
||||
E4D9D9CD043A171200002802 /* MoreSetup.h */,
|
||||
);
|
||||
name = "Reusable Code";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4DA7D6B09843FE2000630D1 /* Test Code */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E42C5163097D6D7400D1B30B /* MoreBacktraceTestTool.c */,
|
||||
E4D9D9CF043A172300002802 /* MoreBacktraceTest.c */,
|
||||
E4CA24070982FE6C0043C210 /* MoreBacktraceTestCommon.h */,
|
||||
E4CA24040982FE650043C210 /* MoreBacktraceTestCommon.c */,
|
||||
E4D9D9D3043AEDB800002802 /* main.nib */,
|
||||
E4A2067F0444ADE300002802 /* MainWindow.nib */,
|
||||
20286C33FDCF999611CA2CEA /* Carbon.framework */,
|
||||
);
|
||||
name = "Test Code";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
E42C50FA097D62FC00D1B30B /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E42C50FB097D62FC00D1B30B /* MoreBacktrace.h in Headers */,
|
||||
E42C50FC097D62FC00D1B30B /* MoreSetup.h in Headers */,
|
||||
E42C5104097D62FC00D1B30B /* MoreAddrToSym.h in Headers */,
|
||||
E4CA24080982FE6C0043C210 /* MoreBacktraceTestCommon.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
E42C50F9097D62FC00D1B30B /* App */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E42C5119097D62FC00D1B30B /* Build configuration list for PBXNativeTarget "App" */;
|
||||
buildPhases = (
|
||||
E42C50FA097D62FC00D1B30B /* Headers */,
|
||||
E42C5107097D62FC00D1B30B /* Resources */,
|
||||
E42C510A097D62FC00D1B30B /* Sources */,
|
||||
E42C5116097D62FC00D1B30B /* Frameworks */,
|
||||
E42C5118097D62FC00D1B30B /* Rez */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
HEADER_SEARCH_PATHS = "";
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_REZFLAGS = "";
|
||||
PRODUCT_NAME = MoreBacktraceTest;
|
||||
SECTORDER_FLAGS = "";
|
||||
WARNING_CFLAGS = (
|
||||
"-Wmost",
|
||||
"-Wno-four-char-constants",
|
||||
"-Wno-unknown-pragmas",
|
||||
);
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
name = App;
|
||||
productInstallPath = "$(HOME)/Applications";
|
||||
productName = MoreBacktraceTest;
|
||||
productReference = E42C511E097D62FC00D1B30B /* MoreBacktraceTest.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
E42C5171097D6E1D00D1B30B /* Tool */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E42C5179097D6E2E00D1B30B /* Build configuration list for PBXNativeTarget "Tool" */;
|
||||
buildPhases = (
|
||||
E42C516F097D6E1D00D1B30B /* Sources */,
|
||||
E42C5170097D6E1D00D1B30B /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
buildSettings = {
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = MoreBacktraceTestTool;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
name = Tool;
|
||||
productName = MoreBacktraceTestTool;
|
||||
productReference = E42C5172097D6E1D00D1B30B /* MoreBacktraceTestTool */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
20286C28FDCF999611CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = E42C5087097D61DA00D1B30B /* Build configuration list for PBXProject "MoreBacktraceTest" */;
|
||||
buildSettings = {
|
||||
};
|
||||
buildStyles = (
|
||||
4A9504C5FFE6A39111CA0CBA /* Development */,
|
||||
4A9504C6FFE6A39111CA0CBA /* Deployment */,
|
||||
);
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 20286C29FDCF999611CA2CEA /* MoreBacktraceTest */;
|
||||
projectDirPath = "";
|
||||
targets = (
|
||||
E42C50F9097D62FC00D1B30B /* App */,
|
||||
E42C5171097D6E1D00D1B30B /* Tool */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
E42C5107097D62FC00D1B30B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E42C5108097D62FC00D1B30B /* main.nib in Resources */,
|
||||
E42C5109097D62FC00D1B30B /* MainWindow.nib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXRezBuildPhase section */
|
||||
E42C5118097D62FC00D1B30B /* Rez */ = {
|
||||
isa = PBXRezBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXRezBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
E42C510A097D62FC00D1B30B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E42C510B097D62FC00D1B30B /* MoreBacktrace.c in Sources */,
|
||||
E42C510C097D62FC00D1B30B /* MoreBacktraceTest.c in Sources */,
|
||||
E42C5114097D62FC00D1B30B /* MoreAddrToSym.c in Sources */,
|
||||
E4CA24050982FE650043C210 /* MoreBacktraceTestCommon.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E42C516F097D6E1D00D1B30B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E42C5285097D728200D1B30B /* MoreBacktraceTestTool.c in Sources */,
|
||||
E4CA23DB0982F7690043C210 /* MoreBacktrace.c in Sources */,
|
||||
E4CA24060982FE650043C210 /* MoreBacktraceTestCommon.c in Sources */,
|
||||
E4CA25F709831B6D0043C210 /* MoreAddrToSym.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
E42C5088097D61DA00D1B30B /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEPLOYMENT_POSTPROCESSING = NO;
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VALUE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.1;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
E42C5089097D61DA00D1B30B /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEPLOYMENT_POSTPROCESSING = YES;
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VALUE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.1;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
E42C511A097D62FC00D1B30B /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
PRODUCT_NAME = MoreBacktraceTest;
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
E42C511B097D62FC00D1B30B /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
PRODUCT_NAME = MoreBacktraceTest;
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
E42C517A097D6E2E00D1B30B /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
ppc64,
|
||||
i386,
|
||||
);
|
||||
BUILD_VARIANTS = normal;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_CFLAGS = "-fasm-blocks";
|
||||
OTHER_LDFLAGS = (
|
||||
"-pagezero_size",
|
||||
1000,
|
||||
);
|
||||
PRODUCT_NAME = MoreBacktraceTestTool;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
E42C517B097D6E2E00D1B30B /* Deployment */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
ppc64,
|
||||
i386,
|
||||
);
|
||||
BUILD_VARIANTS = normal;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_CFLAGS = "-fasm-blocks";
|
||||
OTHER_LDFLAGS = (
|
||||
"-pagezero_size",
|
||||
1000,
|
||||
);
|
||||
PRODUCT_NAME = MoreBacktraceTestTool;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
E42C5087097D61DA00D1B30B /* Build configuration list for PBXProject "MoreBacktraceTest" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E42C5088097D61DA00D1B30B /* Development */,
|
||||
E42C5089097D61DA00D1B30B /* Deployment */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Development;
|
||||
};
|
||||
E42C5119097D62FC00D1B30B /* Build configuration list for PBXNativeTarget "App" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E42C511A097D62FC00D1B30B /* Development */,
|
||||
E42C511B097D62FC00D1B30B /* Deployment */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Development;
|
||||
};
|
||||
E42C5179097D6E2E00D1B30B /* Build configuration list for PBXNativeTarget "Tool" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E42C517A097D6E2E00D1B30B /* Development */,
|
||||
E42C517B097D6E2E00D1B30B /* Deployment */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Development;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 20286C28FDCF999611CA2CEA /* Project object */;
|
||||
}
|
@ -0,0 +1,765 @@
|
||||
/*
|
||||
File: MoreBacktraceTestCommon.c
|
||||
|
||||
Contains: Common code for testing MoreBacktrace.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
$Log: MoreBacktraceTestCommon.c,v $
|
||||
Revision 1.5 2006/01/23 19:26:07 eskimo1
|
||||
Spin on a volatile int because the compiler doesn't like spinning an a volatile pointer (even after I declare it correctly).
|
||||
|
||||
Revision 1.1 2006/01/22 22:47:49 eskimo1
|
||||
A new module that abstracts the test code out of the GUI test app so that it can also be used by the command line tool.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// Our Prototypes
|
||||
|
||||
#include "MoreBacktraceTestCommon.h"
|
||||
|
||||
// Mac OS Interfaces
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
// MIB Interfaces
|
||||
|
||||
#include "MoreAddrToSym.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma mark ***** Backtrace To Text
|
||||
|
||||
// TestMoreBacktraceFramesToText uses a memory based (FILE *) (created using
|
||||
// fwopen) to collect its results. WriteCallback is the routine that handles
|
||||
// writes for this (FILE *). WriteCallbackContext holds its state.
|
||||
|
||||
struct WriteCallbackContext {
|
||||
size_t dataSize; // current data size
|
||||
char * data; // current data
|
||||
};
|
||||
typedef struct WriteCallbackContext WriteCallbackContext;
|
||||
|
||||
static int WriteCallback(void *cookie, const char *data, int dataSize)
|
||||
// Passed as a write callback to fwopen to create a memory-based
|
||||
// (FILE *). See <x-man-page://3/fwopen> for details.
|
||||
{
|
||||
int err;
|
||||
int result;
|
||||
char * tmp;
|
||||
WriteCallbackContext * context;
|
||||
|
||||
// Recover our context from the cookie.
|
||||
|
||||
context = (WriteCallbackContext *) cookie;
|
||||
|
||||
// Allocate a new buffer to accommodate the old data and the new.
|
||||
|
||||
err = 0;
|
||||
tmp = malloc(context->dataSize + dataSize);
|
||||
if (tmp == NULL) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
// Fill it in.
|
||||
|
||||
if (err == 0) {
|
||||
memcpy(tmp, context->data, context->dataSize); // old data
|
||||
memcpy(tmp + context->dataSize, data, dataSize); // new data
|
||||
|
||||
free(context->data);
|
||||
context->data = tmp;
|
||||
context->dataSize += dataSize;
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
|
||||
if (err == 0) {
|
||||
result = dataSize;
|
||||
} else {
|
||||
errno = err;
|
||||
result = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
extern int TestMoreBacktraceFramesToText(
|
||||
const MoreBTFrame frames[],
|
||||
size_t frameCount,
|
||||
bool lookupSymbolNames,
|
||||
char ** btPtr
|
||||
)
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
int junk;
|
||||
WriteCallbackContext resultContext;
|
||||
FILE * result;
|
||||
size_t frameIndex;
|
||||
MoreAToSSymInfo * symbols;
|
||||
|
||||
assert(frames != NULL);
|
||||
assert(btPtr != NULL);
|
||||
assert(*btPtr == NULL);
|
||||
|
||||
result = NULL;
|
||||
resultContext.dataSize = 0;
|
||||
resultContext.data = NULL;
|
||||
symbols = NULL;
|
||||
|
||||
// Create an array of NULL CFStringRefs to hold the symbol pointers.
|
||||
|
||||
err = MoreAToSCreate(frameCount, &symbols);
|
||||
|
||||
// If we've been asked to look up the symbols, do so.
|
||||
|
||||
if ( (err == 0) && lookupSymbolNames) {
|
||||
MoreAToSAddr *addresses;
|
||||
|
||||
// Allocate an array for the addresses and fill it in.
|
||||
|
||||
addresses = (MoreAToSAddr *) malloc(frameCount * sizeof(*addresses));
|
||||
if (addresses == NULL) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
if (err == 0) {
|
||||
for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
if (frames[frameIndex].flags & kMoreBTPCBadMask) {
|
||||
addresses[frameIndex] = 0;
|
||||
} else {
|
||||
addresses[frameIndex] = frames[frameIndex].pc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call MoreAddrToSym module to do the job.
|
||||
|
||||
if (err == 0) {
|
||||
err = MoreAToSCopySymbolNamesUsingDyld(frameCount, addresses, symbols);
|
||||
}
|
||||
|
||||
free(addresses);
|
||||
}
|
||||
|
||||
// Create the output string, starting with an empty string and then
|
||||
// appending an entry for each frame. This uses the little known
|
||||
// ability of BSD to create a (FILE *) with custom I/O routines. In this
|
||||
// case, I have a write routine that outputs to a memory buffer (the
|
||||
// details of which are held in resultContext).
|
||||
|
||||
if (err == 0) {
|
||||
result = fwopen(&resultContext, WriteCallback);
|
||||
if (result == NULL) {
|
||||
err = errno;
|
||||
}
|
||||
}
|
||||
if (err == 0) {
|
||||
int ptrWidth;
|
||||
|
||||
// Determine whether we can treat the backtrace is 32-bit or whether we have to
|
||||
// output the full 64-bits of each pointer.
|
||||
|
||||
ptrWidth = 8;
|
||||
for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
const MoreBTFrame * thisFrame;
|
||||
|
||||
thisFrame = &frames[frameIndex];
|
||||
|
||||
if ( !(thisFrame->flags & kMoreBTPCBadMask) && (thisFrame->pc & 0xFFFFFFFF00000000LL) ) {
|
||||
ptrWidth = 16;
|
||||
}
|
||||
if ( !(thisFrame->flags & kMoreBTFrameBadMask) && (thisFrame->fp & 0xFFFFFFFF00000000LL) ) {
|
||||
ptrWidth = 16;
|
||||
}
|
||||
}
|
||||
|
||||
// Now output each entry.
|
||||
|
||||
for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
const char *thisSymbol;
|
||||
|
||||
// First the frame number and the flags.
|
||||
|
||||
junk = fprintf(result, "%2zu %c%c%c ",
|
||||
frameIndex,
|
||||
(frames[frameIndex].flags & kMoreBTFrameBadMask) ? 'F' : 'f',
|
||||
(frames[frameIndex].flags & kMoreBTPCBadMask) ? 'P' : 'p',
|
||||
(frames[frameIndex].flags & kMoreBTSignalHandlerMask) ? 'S' : 's'
|
||||
);
|
||||
assert(junk > 0);
|
||||
|
||||
// Then the frame pointer.
|
||||
|
||||
if (frames[frameIndex].flags & kMoreBTFrameBadMask) {
|
||||
fprintf(result, "%*s ", ptrWidth, "");
|
||||
} else {
|
||||
fprintf(result, "%*llx ", ptrWidth, frames[frameIndex].fp);
|
||||
}
|
||||
|
||||
// Then the PC.
|
||||
|
||||
if (frames[frameIndex].flags & kMoreBTPCBadMask) {
|
||||
fprintf(result, "%*s ", ptrWidth, "");
|
||||
} else {
|
||||
fprintf(result, "%*llx ", ptrWidth, frames[frameIndex].pc);
|
||||
}
|
||||
|
||||
// Finally the symbolic name, if present.
|
||||
|
||||
thisSymbol = symbols[frameIndex].symbolName;
|
||||
if (thisSymbol != NULL) {
|
||||
junk = fprintf(result, " %s+%04llx", thisSymbol, symbols[frameIndex].symbolOffset);
|
||||
assert(junk > 0);
|
||||
}
|
||||
|
||||
junk = fprintf(result, "\n");
|
||||
assert(junk > 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Null terminate the string.
|
||||
|
||||
if (err == 0) {
|
||||
junk = fputc(0, result);
|
||||
assert(junk >= 0);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
|
||||
if (result != NULL) {
|
||||
junk = fclose(result);
|
||||
assert(junk == 0);
|
||||
}
|
||||
if (err == 0) {
|
||||
*btPtr = resultContext.data; // all good, return resultContext.data to the client
|
||||
} else {
|
||||
free(resultContext.data); // all bad, free up resultContext.data and leave *btPtr as NULL
|
||||
}
|
||||
MoreAToSDestroy(frameCount, symbols);
|
||||
|
||||
assert( (err == 0) == (*btPtr != NULL) );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#pragma mark ***** Self Test
|
||||
|
||||
// To simplify the test code, I receive the backtrace into a fixed size array.
|
||||
// The number of elements in this array, 70, is the number that I can reasonably
|
||||
// display in the window of the GUI app. I've carried it forward into the common
|
||||
// code because I don't see any pressing need to change it.
|
||||
|
||||
enum {
|
||||
kFrameCount = 70
|
||||
};
|
||||
|
||||
extern int TestMoreBacktraceMachSelf(char **btPtr)
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
MoreBTFrame frames[kFrameCount];
|
||||
size_t frameCount;
|
||||
size_t validFrames;
|
||||
|
||||
assert( btPtr != NULL);
|
||||
assert(*btPtr == NULL);
|
||||
|
||||
frameCount = sizeof(frames) / sizeof(*frames);
|
||||
err = MoreBacktraceMachSelf(0, 0, frames, frameCount, &validFrames);
|
||||
if (err == 0) {
|
||||
if (validFrames > frameCount) {
|
||||
validFrames = frameCount;
|
||||
}
|
||||
err = TestMoreBacktraceFramesToText(frames, validFrames, true, btPtr);
|
||||
}
|
||||
|
||||
assert( (err == 0) == (*btPtr != NULL) );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#pragma mark ***** Other Task Test
|
||||
|
||||
extern int TestMoreBacktraceMachThread(pid_t pid, char **btPtr)
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
int junk;
|
||||
MoreBTFrame frames[kFrameCount];
|
||||
size_t frameCount;
|
||||
size_t validFrames;
|
||||
task_t targetTask;
|
||||
bool didSuspend;
|
||||
thread_array_t threadList;
|
||||
mach_msg_type_number_t threadCount;
|
||||
|
||||
assert(pid > 0);
|
||||
assert(btPtr != NULL);
|
||||
assert(*btPtr == NULL);
|
||||
|
||||
targetTask = MACH_PORT_NULL;
|
||||
threadList = NULL;
|
||||
didSuspend = false;
|
||||
|
||||
frameCount = 0; // just to quieten a warning
|
||||
|
||||
// Convert pid to the Mach task control port.
|
||||
|
||||
err = task_for_pid(mach_task_self(), pid, &targetTask);
|
||||
if (err == 0) {
|
||||
if (targetTask == mach_task_self()) {
|
||||
err = -1; // this won't go well
|
||||
}
|
||||
}
|
||||
|
||||
// Suspend the task while we sample it. Otherwise the
|
||||
// list of threads might change.
|
||||
|
||||
if (err == 0) {
|
||||
err = task_suspend(targetTask);
|
||||
didSuspend = (err == 0);
|
||||
}
|
||||
if (err == 0) {
|
||||
err = task_threads(targetTask, &threadList, &threadCount);
|
||||
}
|
||||
if (err == 0) {
|
||||
// A task without any threads makes no sense.
|
||||
|
||||
assert(threadCount > 0);
|
||||
|
||||
// We always sample the first thread. This has no real
|
||||
// significance because Mach doesn't guarantee to return
|
||||
// the threads in any particular order. In a real tool
|
||||
// you'd iterate over all of the threads and sample each,
|
||||
// but I have no way of displaying the results in my
|
||||
// test framework.
|
||||
|
||||
frameCount = sizeof(frames) / sizeof(*frames);
|
||||
err = MoreBacktraceMachThread(targetTask, threadList[0], 0, 0, frames, frameCount, &validFrames);
|
||||
}
|
||||
|
||||
// Resume the task as quickly as possibly after the backtrace.
|
||||
|
||||
if (didSuspend) {
|
||||
junk = task_resume(targetTask);
|
||||
assert(junk == 0);
|
||||
}
|
||||
|
||||
// Create the text output without symbols.
|
||||
|
||||
if (err == 0) {
|
||||
if (validFrames > frameCount) {
|
||||
validFrames = frameCount;
|
||||
}
|
||||
err = TestMoreBacktraceFramesToText(frames, validFrames, false, btPtr);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
|
||||
junk = mach_port_deallocate(mach_task_self(), targetTask);
|
||||
assert(junk == 0);
|
||||
if (threadList != NULL) {
|
||||
mach_msg_type_number_t thisThread;
|
||||
|
||||
for (thisThread = 0; thisThread < threadCount; thisThread++) {
|
||||
junk = mach_port_deallocate(mach_task_self(), threadList[thisThread]);
|
||||
assert(junk == 0);
|
||||
}
|
||||
junk = vm_deallocate(mach_task_self(), (vm_address_t) threadList, threadCount * sizeof(*threadList));
|
||||
assert(junk == 0);
|
||||
}
|
||||
|
||||
assert( (err == 0) == (*btPtr != NULL) );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#pragma mark ***** Signal Test
|
||||
|
||||
// The following are set by the signal handler when it runs.
|
||||
|
||||
static volatile int gError = -1;
|
||||
static char volatile * gBacktrace = NULL;
|
||||
|
||||
static void MySIGUSR1Handler(int signal)
|
||||
// Handle SIGUSR1. Note that we call many functions
|
||||
// here that aren't "signal safe". However, we know
|
||||
// that this signal isn't happening asynchronously,
|
||||
// we're sending it to ourselves via a call to "pthread_kill",
|
||||
// so most of the unsafeness is moot. Still, if this
|
||||
// wasn't a just test program I'd figure out a better way.
|
||||
{
|
||||
int err;
|
||||
char * tmp;
|
||||
assert(signal == SIGUSR1);
|
||||
|
||||
fprintf(stderr, "MySIGUSR1Handler calls TestMoreBacktraceMachSelf.\n");
|
||||
tmp = (char *) gBacktrace;
|
||||
err = TestMoreBacktraceMachSelf(&tmp);
|
||||
gBacktrace = tmp; // Because the code in TestSignalBacktraceNested
|
||||
gError = err; // might be spinning on gError, assign that last.
|
||||
}
|
||||
|
||||
static int TestSignalBacktraceNested(bool nonLeaf)
|
||||
// Send a SIGUSR1 to ourselves.
|
||||
{
|
||||
int err;
|
||||
|
||||
if ( ! nonLeaf ) {
|
||||
|
||||
// This is the standard branch. We use pthread_kill to send a signal
|
||||
// to ourself.
|
||||
|
||||
err = pthread_kill(pthread_self(), SIGUSR1);
|
||||
} else {
|
||||
|
||||
// Use this branch of the code, in tandem with sending the SIGUSR1 from
|
||||
// the command line, to test the case where a signal interrupts a non-leaf
|
||||
// routine. I added this because pthread_kill (well, actually __pthread_kill)
|
||||
// is a system call leaf routine, so the main test only checks the
|
||||
// in leaf routine case.
|
||||
//
|
||||
// Also, this is a hard spin loop because I can't
|
||||
// add a delay call because then it's likely that the signal would come
|
||||
// in while we're blocked in the delay, and then we're back to the leaf
|
||||
// routine test again.
|
||||
|
||||
fprintf(stderr, "Signal this process using:\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "$ kill -USR1 %ld\n", (long) getpid());
|
||||
|
||||
while (gError == -1) {
|
||||
// do nothing
|
||||
}
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
extern int TestMoreBacktraceMachSelfSignal(bool nonLeaf, char **btPtr)
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
int junk;
|
||||
struct sigaction oldSig;
|
||||
struct sigaction newSig;
|
||||
|
||||
assert(btPtr != NULL);
|
||||
assert(*btPtr == NULL);
|
||||
|
||||
assert(gBacktrace == NULL);
|
||||
assert(gError == -1);
|
||||
|
||||
// Install MySIGUSR1Handler as the SIGUSR1 handler.
|
||||
|
||||
memset(&newSig, 0, sizeof(newSig));
|
||||
newSig.sa_handler = &MySIGUSR1Handler;
|
||||
err = sigaction(SIGUSR1, &newSig, &oldSig);
|
||||
if (err < 0) {
|
||||
err = errno;
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
|
||||
// Call a routine that sends a signal to us.
|
||||
|
||||
err = TestSignalBacktraceNested(nonLeaf);
|
||||
|
||||
// Restore the old signal handler.
|
||||
|
||||
junk = sigaction(SIGUSR1, &oldSig, NULL);
|
||||
assert(junk == 0);
|
||||
|
||||
if (err == 0) {
|
||||
err = gError; // get the error from the signal handler
|
||||
gError = -1; // just for tidiness
|
||||
}
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
*btPtr = (char *) gBacktrace; // get the backtrace from the signal handler
|
||||
gBacktrace = NULL; // just for tidiness
|
||||
}
|
||||
|
||||
assert( (err == 0) == (*btPtr != NULL) );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#pragma mark ***** Stack Smash Test
|
||||
|
||||
// This test works by create a dummy thread that blocks forever deep in nested
|
||||
// routines, then smashing its stack.
|
||||
|
||||
static pthread_t gDeadThread;
|
||||
// The dummy thread itself.
|
||||
|
||||
static pthread_mutex_t gDeadThreadReadyMutex;
|
||||
static pthread_cond_t gDeadThreadReadyCond;
|
||||
// A condition variable that protects gDeadThreadReady and gDeadThreadID.
|
||||
|
||||
static volatile bool gDeadThreadReady = false;
|
||||
// True if the dead thread is ready to be smashed.
|
||||
|
||||
static volatile thread_t gDeadThreadID = MACH_PORT_NULL;
|
||||
// The Mach thread ID of the thread.
|
||||
|
||||
static void DeadThreadNested4(void)
|
||||
// The victim routine itself.
|
||||
{
|
||||
int junk;
|
||||
|
||||
// Set our condition to true.
|
||||
|
||||
junk = pthread_mutex_lock(&gDeadThreadReadyMutex);
|
||||
assert(junk == 0);
|
||||
|
||||
gDeadThreadReady = true;
|
||||
gDeadThreadID = mach_thread_self();
|
||||
|
||||
junk = pthread_mutex_unlock(&gDeadThreadReadyMutex);
|
||||
assert(junk == 0);
|
||||
|
||||
// Signal the main thread who is waiting on our condition.
|
||||
|
||||
junk = pthread_cond_signal(&gDeadThreadReadyCond);
|
||||
assert(junk == 0);
|
||||
|
||||
// Loop forever.
|
||||
|
||||
do {
|
||||
(void) pause();
|
||||
} while (true);
|
||||
}
|
||||
|
||||
static void DeadThreadNested3(void)
|
||||
// A few nested procedures so you get an interesting trace.
|
||||
{
|
||||
DeadThreadNested4();
|
||||
}
|
||||
|
||||
static void DeadThreadNested2(void)
|
||||
// A few nested procedures so you get an interesting trace.
|
||||
{
|
||||
DeadThreadNested3();
|
||||
}
|
||||
|
||||
static void DeadThreadNested1(void)
|
||||
// A few nested procedures so you get an interesting trace.
|
||||
{
|
||||
DeadThreadNested2();
|
||||
}
|
||||
|
||||
static void * DeadThread(void *param)
|
||||
// The thread entry point for the victim thread.
|
||||
{
|
||||
#pragma unused(param)
|
||||
DeadThreadNested1();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int StartDeadThread(void)
|
||||
// Start a victim thread whose stack we intend to smash
|
||||
// in order to test our handling of bad pointers in a
|
||||
// stack crawl.
|
||||
//
|
||||
// Returns an errno-style error.
|
||||
{
|
||||
int err;
|
||||
int junk;
|
||||
thread_t threadID;
|
||||
MoreBTFrame frames[10];
|
||||
size_t frameCount;
|
||||
size_t validFrames;
|
||||
|
||||
// Init resources required for condition variable.
|
||||
|
||||
err = pthread_mutex_init(&gDeadThreadReadyMutex, NULL);
|
||||
if (err == 0) {
|
||||
err = pthread_cond_init(&gDeadThreadReadyCond, NULL);
|
||||
}
|
||||
|
||||
// Start the thread.
|
||||
|
||||
if (err == 0) {
|
||||
err = pthread_create(&gDeadThread, NULL, DeadThread, NULL);
|
||||
}
|
||||
if (err == 0) {
|
||||
junk = pthread_detach(gDeadThread);
|
||||
assert(junk == 0);
|
||||
}
|
||||
|
||||
// Wait for the condition.
|
||||
|
||||
if (err == 0) {
|
||||
threadID = MACH_PORT_NULL;
|
||||
do {
|
||||
junk = pthread_mutex_lock(&gDeadThreadReadyMutex);
|
||||
assert(junk == 0);
|
||||
|
||||
if (gDeadThreadReady) {
|
||||
threadID = gDeadThreadID;
|
||||
}
|
||||
|
||||
if (threadID == MACH_PORT_NULL) {
|
||||
junk = pthread_cond_wait(&gDeadThreadReadyCond, &gDeadThreadReadyMutex);
|
||||
assert(junk == 0);
|
||||
}
|
||||
|
||||
junk = pthread_mutex_unlock(&gDeadThreadReadyMutex);
|
||||
assert(junk == 0);
|
||||
} while ( threadID == MACH_PORT_NULL );
|
||||
}
|
||||
|
||||
// Take a backtrace.
|
||||
|
||||
if (err == 0) {
|
||||
frameCount = sizeof(frames) / sizeof(frames[0]);
|
||||
|
||||
err = MoreBacktraceMachThread(
|
||||
mach_task_self(),
|
||||
threadID,
|
||||
0,
|
||||
0,
|
||||
frames,
|
||||
frameCount,
|
||||
&validFrames
|
||||
);
|
||||
}
|
||||
if (err == 0) {
|
||||
if (validFrames < frameCount) {
|
||||
err = -1;
|
||||
} else if (validFrames > frameCount) {
|
||||
validFrames = frameCount;
|
||||
}
|
||||
}
|
||||
if ( (err == 0) && true) {
|
||||
char * bt;
|
||||
|
||||
bt = NULL;
|
||||
|
||||
err = TestMoreBacktraceFramesToText(frames, validFrames, true, &bt);
|
||||
if (err == 0) {
|
||||
fprintf(stderr, "Pre-smash backtrace:\n");
|
||||
fprintf(stdout, "%s\n", bt);
|
||||
}
|
||||
|
||||
free(bt);
|
||||
|
||||
err = 0;
|
||||
}
|
||||
|
||||
// Now let's use that backtrace to vandalise the stack!
|
||||
|
||||
if (err == 0) {
|
||||
int i;
|
||||
char * busErrorAddress;
|
||||
char ** fp;
|
||||
|
||||
// I don't want to use 0 for the Mac OS X bus error value, because
|
||||
// it's a little obvious. Instead I use a value that's in the bottom
|
||||
// page (ie is less than 0x1000) and is easily recognisable.
|
||||
|
||||
busErrorAddress = (char *) (intptr_t) 0xfec;
|
||||
|
||||
// 1. We go down 4 frames on the stack and smash the next
|
||||
// frame pointer.
|
||||
|
||||
fp = (char **) (intptr_t) frames[4].fp;
|
||||
fp[0] = busErrorAddress;
|
||||
|
||||
// 2. We go down 2 frames on the stack and smash the
|
||||
// return address. As its location is architecture dependent,
|
||||
// we just smash 8 words and hope that we get it (-:
|
||||
|
||||
fp = (char **) (intptr_t) frames[2].fp;
|
||||
for (i = 0; i < 8; i++) {
|
||||
fp[i] = busErrorAddress;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
extern int TestMoreBacktraceMachThreadStackSmash(char **btPtr)
|
||||
// See comments in header.
|
||||
{
|
||||
int err;
|
||||
MoreBTFrame frames[kFrameCount];
|
||||
size_t frameCount;
|
||||
size_t validFrames;
|
||||
|
||||
assert( btPtr != NULL);
|
||||
assert(*btPtr == NULL);
|
||||
|
||||
// Start a thread that just blocks indefinitely. In the
|
||||
// process, smash its stack.
|
||||
|
||||
err = 0;
|
||||
if ( ! gDeadThreadReady ) {
|
||||
err = StartDeadThread();
|
||||
}
|
||||
assert( (err != 0) || (gDeadThreadReady && (gDeadThreadID != MACH_PORT_NULL)) );
|
||||
|
||||
// Take a backtrace of that thread and return it.
|
||||
|
||||
if (err == 0) {
|
||||
frameCount = sizeof(frames) / sizeof(*frames);
|
||||
err = MoreBacktraceMachThread(mach_task_self(), gDeadThreadID, 0, 0, frames, frameCount, &validFrames);
|
||||
}
|
||||
if (err == 0) {
|
||||
if (validFrames > frameCount) {
|
||||
validFrames = frameCount;
|
||||
}
|
||||
err = TestMoreBacktraceFramesToText(frames, validFrames, true, btPtr);
|
||||
}
|
||||
|
||||
assert( (err == 0) == (*btPtr != NULL) );
|
||||
|
||||
return err;
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
File: MoreBacktraceTestCommon.h
|
||||
|
||||
Contains: Common code for testing backtraces.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
$Log: MoreBacktraceTestCommon.h,v $
|
||||
Revision 1.1 2006/01/22 22:47:51 eskimo1
|
||||
A new module that abstracts the test code out of the GUI test app so that it can also be used by the command line tool.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// MoreIsBetter Setup
|
||||
|
||||
#include "MoreSetup.h"
|
||||
|
||||
// Mac OS Interfaces
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// MIB Interfaces
|
||||
|
||||
#include "MoreBacktrace.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// This module contains common test code that's shared between the application
|
||||
// and the command line tool.
|
||||
|
||||
extern int TestMoreBacktraceFramesToText(
|
||||
const MoreBTFrame frames[],
|
||||
size_t frameCount,
|
||||
bool lookupSymbolNames,
|
||||
char ** btPtr
|
||||
);
|
||||
// Converts a backtrace (specified by frames and frameCount)
|
||||
// to textual form, returning a pointer to the text in *btPtr.
|
||||
// Each line is separated by a '\n' and the entire string
|
||||
// is null terminated. The caller is responsible for disposing
|
||||
// of this result using free.
|
||||
//
|
||||
// If lookupSymbolNames is true,
|
||||
// the textual representation will contain symbols generated
|
||||
// using the MoreAddrToSym module. Given that this module
|
||||
// only supports looking up symbols in the current task
|
||||
// (at least currently), you should only pass true to this
|
||||
// parameter if the backtrace came from the current task.
|
||||
//
|
||||
// On entry, frames must not be NULL.
|
||||
// On entry, btPtr must not be NULL.
|
||||
// On entry, *btPtr must be NULL.
|
||||
// Returns an errno-style error code.
|
||||
// On success, *btPtr will not be NULL.
|
||||
// On error, *btPtr will be NULL.
|
||||
|
||||
// The following routines run a variety of different backtrace tests.
|
||||
// This each return an errno-style error code, and set *btPtr as
|
||||
// specified by TestMoreBacktraceFramesToText.
|
||||
|
||||
extern int TestMoreBacktraceMachSelf(char **btPtr);
|
||||
// Backtrace the current thread.
|
||||
|
||||
extern int TestMoreBacktraceMachThread(pid_t pid, char **btPtr);
|
||||
// Backtrace a random thread in the specified task.
|
||||
|
||||
extern int TestMoreBacktraceMachSelfSignal(bool nonLeaf, char **btPtr);
|
||||
// Backtrace across a signal handler. If nonLeaf is set,
|
||||
// this requires user intervention to deliver the signal.
|
||||
|
||||
extern int TestMoreBacktraceMachThreadStackSmash(char **btPtr);
|
||||
// Backtrace a thread with a smashed stack.
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
File: MoreBacktraceTestTool.c
|
||||
|
||||
Contains: Command line tool to test MoreBacktrace.
|
||||
|
||||
Written by: DTS
|
||||
|
||||
Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple╒s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// System interfaces
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
// MIB interfaces
|
||||
|
||||
#include "MoreBacktraceTestCommon.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
static void PrintUsage(const char *argv0)
|
||||
// Print the program's usage.
|
||||
{
|
||||
const char *command;
|
||||
|
||||
command = strrchr(argv0, '/');
|
||||
if (command == NULL) {
|
||||
command = argv0;
|
||||
} else {
|
||||
command += 1;
|
||||
}
|
||||
fprintf(stderr, "usage: %s command...\n", command);
|
||||
fprintf(stderr, " commands: -self\n");
|
||||
fprintf(stderr, " commands: -signal\n");
|
||||
fprintf(stderr, " commands: -signal-nonleaf\n");
|
||||
fprintf(stderr, " commands: -pid <pid>\n");
|
||||
fprintf(stderr, " commands: -smash\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int err;
|
||||
int retVal;
|
||||
const char * builtArch;
|
||||
bool printUsage;
|
||||
int argIndex;
|
||||
pid_t pid;
|
||||
|
||||
// Just for convenience's sake, print out the architecture of the
|
||||
// code we're actually running. In the world of universal binaries,
|
||||
// Rosseta, and PowerPC 32- and 64-bit, it's often hard to remember
|
||||
// what's what.
|
||||
|
||||
#if TARGET_CPU_PPC
|
||||
builtArch = "ppc";
|
||||
#elif TARGET_CPU_PPC64
|
||||
builtArch = "ppc64";
|
||||
#elif TARGET_CPU_X86
|
||||
builtArch = "i386";
|
||||
#else
|
||||
#error What are you building?
|
||||
#endif
|
||||
fprintf(stderr, "Built for %s.\n", builtArch);
|
||||
|
||||
// Process command line arguments.
|
||||
|
||||
retVal = EXIT_SUCCESS;
|
||||
printUsage = false;
|
||||
if (argc < 2) {
|
||||
printUsage = true;
|
||||
} else {
|
||||
argIndex = 1;
|
||||
while (argIndex < argc) {
|
||||
char * bt;
|
||||
|
||||
err = 0;
|
||||
bt = NULL;
|
||||
if ( strcmp(argv[argIndex], "-self") == 0 ) {
|
||||
argIndex += 1;
|
||||
err = TestMoreBacktraceMachSelf(&bt);
|
||||
} else if ( strcmp(argv[argIndex], "-pid") == 0 ) {
|
||||
argIndex += 1;
|
||||
if (argIndex < argc) {
|
||||
pid = (pid_t) atol(argv[argIndex]);
|
||||
argIndex += 1;
|
||||
|
||||
err = TestMoreBacktraceMachThread(pid, &bt);
|
||||
} else {
|
||||
printUsage = true;
|
||||
}
|
||||
} else if ( strcmp(argv[argIndex], "-signal") == 0 ) {
|
||||
argIndex += 1;
|
||||
err = TestMoreBacktraceMachSelfSignal(false, &bt);
|
||||
} else if ( strcmp(argv[argIndex], "-signal-nonleaf") == 0 ) {
|
||||
argIndex += 1;
|
||||
err = TestMoreBacktraceMachSelfSignal(true, &bt);
|
||||
} else if ( strcmp(argv[argIndex], "-smash") == 0 ) {
|
||||
argIndex += 1;
|
||||
err = TestMoreBacktraceMachThreadStackSmash(&bt);
|
||||
if (err == 0) {
|
||||
fprintf(stderr, "Post-smash backtrace:\n");
|
||||
}
|
||||
} else {
|
||||
argIndex = argc;
|
||||
printUsage = true;
|
||||
}
|
||||
|
||||
if ( (err == 0) && (bt != NULL) ) {
|
||||
fprintf(stdout, "%s\n", bt);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to backtrace (error %d).\n", err);
|
||||
}
|
||||
free(bt);
|
||||
}
|
||||
}
|
||||
|
||||
if (printUsage) {
|
||||
PrintUsage(argv[0]);
|
||||
retVal = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
4
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/main.nib/classes.nib
сгенерированный
Обычный файл
4
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/main.nib/classes.nib
сгенерированный
Обычный файл
@ -0,0 +1,4 @@
|
||||
{
|
||||
IBClasses = ();
|
||||
IBVersion = 1;
|
||||
}
|
19
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/main.nib/info.nib
сгенерированный
Обычный файл
19
opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktraceTest/main.nib/info.nib
сгенерированный
Обычный файл
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>69 10 356 240 0 0 1280 832 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>29</key>
|
||||
<string>69 252 216 44 0 0 1280 1002 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>443.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>8G32</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCarbonFramework</string>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<object class="NSIBObjectData">
|
||||
<string name="targetFramework">IBCarbonFramework</string>
|
||||
<object name="rootObject" class="NSCustomObject" id="1">
|
||||
<string name="customClass">NSApplication</string>
|
||||
</object>
|
||||
<array count="12" name="allObjects">
|
||||
<object class="IBCarbonMenu" id="29">
|
||||
<string name="title">main</string>
|
||||
<array count="2" name="items">
|
||||
<object class="IBCarbonMenuItem" id="185">
|
||||
<string name="title">MoreBacktraceTest</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="184">
|
||||
<string name="title">MoreBacktraceTest</string>
|
||||
<array count="1" name="items">
|
||||
<object class="IBCarbonMenuItem" id="187">
|
||||
<string name="title">About MoreBacktraceTest</string>
|
||||
<int name="keyEquivalentModifier">0</int>
|
||||
<ostype name="command">abou</ostype>
|
||||
</object>
|
||||
</array>
|
||||
<string name="name">_NSAppleMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="192">
|
||||
<string name="title">Window</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="195">
|
||||
<string name="title">Window</string>
|
||||
<array count="6" name="items">
|
||||
<object class="IBCarbonMenuItem" id="197">
|
||||
<string name="title">Zoom Window</string>
|
||||
<ostype name="command">zoom</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="190">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<string name="title">Minimize Window</string>
|
||||
<string name="keyEquivalent">m</string>
|
||||
<ostype name="command">mini</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="191">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<string name="title">Minimize All Windows</string>
|
||||
<string name="keyEquivalent">m</string>
|
||||
<int name="keyEquivalentModifier">1572864</int>
|
||||
<ostype name="command">mina</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="194">
|
||||
<boolean name="separator">TRUE</boolean>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="196">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<string name="title">Bring All to Front</string>
|
||||
<ostype name="command">bfrt</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="193">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<string name="title">Arrange in Front</string>
|
||||
<int name="keyEquivalentModifier">1572864</int>
|
||||
<ostype name="command">frnt</ostype>
|
||||
</object>
|
||||
</array>
|
||||
<string name="name">_NSWindowsMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
<string name="name">_NSMainMenu</string>
|
||||
</object>
|
||||
<reference idRef="184"/>
|
||||
<reference idRef="185"/>
|
||||
<reference idRef="187"/>
|
||||
<reference idRef="190"/>
|
||||
<reference idRef="191"/>
|
||||
<reference idRef="192"/>
|
||||
<reference idRef="193"/>
|
||||
<reference idRef="194"/>
|
||||
<reference idRef="195"/>
|
||||
<reference idRef="196"/>
|
||||
<reference idRef="197"/>
|
||||
</array>
|
||||
<array count="12" name="allParents">
|
||||
<reference idRef="1"/>
|
||||
<reference idRef="185"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="184"/>
|
||||
<reference idRef="195"/>
|
||||
<reference idRef="195"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="195"/>
|
||||
<reference idRef="195"/>
|
||||
<reference idRef="192"/>
|
||||
<reference idRef="195"/>
|
||||
<reference idRef="195"/>
|
||||
</array>
|
||||
<dictionary count="2" name="nameTable">
|
||||
<string>Files Owner</string>
|
||||
<reference idRef="1"/>
|
||||
<string>MenuBar</string>
|
||||
<reference idRef="29"/>
|
||||
</dictionary>
|
||||
<unsigned_int name="nextObjectID">246</unsigned_int>
|
||||
</object>
|
1
opal/mca/backtrace/darwin/MoreBacktrace/MoreSetup.h
Обычный файл
1
opal/mca/backtrace/darwin/MoreBacktrace/MoreSetup.h
Обычный файл
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
105
opal/mca/backtrace/darwin/backtrace_darwin.c
Обычный файл
105
opal/mca/backtrace/darwin/backtrace_darwin.c
Обычный файл
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
#include "opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreBacktrace.h"
|
||||
#include "opal/mca/backtrace/darwin/MoreBacktrace/MoreDebugging/MoreAddrToSym.h"
|
||||
|
||||
#define SIGNAL_SKIPFRAME 4
|
||||
#define ALWAYS_SKIPFRAME 2
|
||||
#define kFrameCount 32
|
||||
|
||||
void
|
||||
opal_backtrace_print(FILE *file)
|
||||
{
|
||||
int ret;
|
||||
unsigned long frameCount;
|
||||
unsigned long validFrames;
|
||||
MoreBTFrame frames[kFrameCount];
|
||||
unsigned long frameIndex, skipframe = 0;
|
||||
MoreAToSSymInfo symbol;
|
||||
MoreAToSAddr address;
|
||||
|
||||
frameCount = sizeof(frames) / sizeof(*frames);
|
||||
ret = MoreBacktraceMachSelf(0, 0, frames, frameCount, &validFrames);
|
||||
if (0 != ret) {
|
||||
fprintf(file, "Stack corrupted and not printable\n");
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (validFrames > frameCount) {
|
||||
validFrames = frameCount;
|
||||
}
|
||||
|
||||
if ((validFrames >= SIGNAL_SKIPFRAME) &&
|
||||
(frames[SIGNAL_SKIPFRAME-1].flags & kMoreBTSignalHandlerMask)) {
|
||||
skipframe = SIGNAL_SKIPFRAME;
|
||||
} else if (validFrames >= ALWAYS_SKIPFRAME) {
|
||||
skipframe = ALWAYS_SKIPFRAME;
|
||||
}
|
||||
|
||||
for (frameIndex = skipframe; frameIndex < validFrames; frameIndex++) {
|
||||
fprintf(stderr, "[%2ld] ", frameIndex - skipframe + 1);
|
||||
|
||||
if (frames[frameIndex].flags & kMoreBTPCBadMask) {
|
||||
address = 0;
|
||||
} else {
|
||||
address = (MoreAToSAddr) frames[frameIndex].pc;
|
||||
}
|
||||
|
||||
symbol.symbolName = NULL;
|
||||
symbol.symbolType = kMoreAToSNoSymbol;
|
||||
symbol.symbolOffset = 0;
|
||||
|
||||
ret = MoreAToSCopySymbolNamesUsingDyld(1, &address, &symbol);
|
||||
|
||||
if (symbol.symbolName) {
|
||||
if (symbol.symbolName[0]) {
|
||||
fprintf(file, "(%s + 0x%llx) ",
|
||||
symbol.symbolName, symbol.symbolOffset);
|
||||
free( (void *) symbol.symbolName);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "[0x%08llx, 0x%08llx] ",
|
||||
frames[frameIndex].fp,
|
||||
frames[frameIndex].pc);
|
||||
|
||||
if (frames[frameIndex].flags) {
|
||||
fprintf(file, "(%c%c%c)",
|
||||
(frames[frameIndex].flags & kMoreBTFrameBadMask) ? 'F' : '-',
|
||||
(frames[frameIndex].flags & kMoreBTPCBadMask) ? 'P' : '-',
|
||||
(frames[frameIndex].flags & kMoreBTSignalHandlerMask) ? 'S' : '-');
|
||||
}
|
||||
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
opal_backtrace_buffer(char ***message_out, int *len_out)
|
||||
{
|
||||
return OPAL_SUCCESS;
|
||||
}
|
47
opal/mca/backtrace/darwin/backtrace_darwin_component.c
Обычный файл
47
opal/mca/backtrace/darwin/backtrace_darwin_component.c
Обычный файл
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
|
||||
const opal_backtrace_base_component_1_0_0_t mca_backtrace_darwin_component = {
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
{
|
||||
/* Indicate that we are a backtrace v1.0.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
OPAL_BACKTRACE_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
"darwin",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* Next the MCA v1.0.0 component meta data */
|
||||
{
|
||||
/* Whether the component is checkpointable or not */
|
||||
true
|
||||
},
|
||||
};
|
43
opal/mca/backtrace/darwin/configure.m4
Обычный файл
43
opal/mca/backtrace/darwin/configure.m4
Обычный файл
@ -0,0 +1,43 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([MCA_backtrace_darwin_COMPILE_MODE], [
|
||||
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||
$4="static"
|
||||
AC_MSG_RESULT([$$4])
|
||||
])
|
||||
|
||||
|
||||
# MCA_backtrace_darwin_CONFIG(action-if-can-compile,
|
||||
# [action-if-cant-compile])
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_backtrace_darwin_CONFIG],[
|
||||
AC_CHECK_FUNCS([vm_read_overwrite],
|
||||
[backtrace_darwin_happy="yes"],
|
||||
[backtrace_darwin_happy="no"])
|
||||
|
||||
if test "$backtrace_darwin_happy" = "yes" ; then
|
||||
if test "$OMPI_C_GCC_INLINE_ASSEMBLY" = "0" ; then
|
||||
backtrace_darwin_happy="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
AS_IF([test "$backtrace_darwin_happy" = "yes"],
|
||||
[$1], [$2])
|
||||
])
|
15
opal/mca/backtrace/darwin/configure.params
Обычный файл
15
opal/mca/backtrace/darwin/configure.params
Обычный файл
@ -0,0 +1,15 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# Specific to this module
|
||||
|
||||
PARAM_CONFIG_PRIORITY=30
|
||||
PARAM_CONFIG_FILES="Makefile"
|
23
opal/mca/backtrace/execinfo/Makefile.am
Обычный файл
23
opal/mca/backtrace/execinfo/Makefile.am
Обычный файл
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
noinst_LTLIBRARIES = libmca_backtrace_execinfo.la
|
||||
|
||||
libmca_backtrace_execinfo_la_SOURCES = \
|
||||
backtrace_execinfo.c \
|
||||
backtrace_execinfo_component.c
|
61
opal/mca/backtrace/execinfo/backtrace_execinfo.c
Обычный файл
61
opal/mca/backtrace/execinfo/backtrace_execinfo.c
Обычный файл
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
|
||||
void
|
||||
opal_backtrace_print(FILE *file)
|
||||
{
|
||||
int i;
|
||||
int trace_size;
|
||||
void * trace[32];
|
||||
char ** messages = (char **)NULL;
|
||||
|
||||
trace_size = backtrace (trace, 32);
|
||||
messages = backtrace_symbols (trace, trace_size);
|
||||
|
||||
for (i = 0; i < trace_size; i++) {
|
||||
fprintf(file, "[%d] func:%s\n", i, messages[i]);
|
||||
fflush(file);
|
||||
}
|
||||
|
||||
free(messages);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
opal_backtrace_buffer(char ***message_out, int *len_out)
|
||||
{
|
||||
int trace_size;
|
||||
void * trace[32];
|
||||
char ** funcs = (char **)NULL;
|
||||
|
||||
trace_size = backtrace (trace, 32);
|
||||
funcs = backtrace_symbols (trace, trace_size);
|
||||
|
||||
*message_out = funcs;
|
||||
*len_out = trace_size;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
47
opal/mca/backtrace/execinfo/backtrace_execinfo_component.c
Обычный файл
47
opal/mca/backtrace/execinfo/backtrace_execinfo_component.c
Обычный файл
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
|
||||
const opal_backtrace_base_component_1_0_0_t mca_backtrace_execinfo_component = {
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
{
|
||||
/* Indicate that we are a backtrace v1.0.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
OPAL_BACKTRACE_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
"execinfo",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* Next the MCA v1.0.0 component meta data */
|
||||
{
|
||||
/* Whether the component is checkpointable or not */
|
||||
true
|
||||
},
|
||||
};
|
39
opal/mca/backtrace/execinfo/configure.m4
Обычный файл
39
opal/mca/backtrace/execinfo/configure.m4
Обычный файл
@ -0,0 +1,39 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([MCA_backtrace_execinfo_COMPILE_MODE], [
|
||||
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||
$4="static"
|
||||
AC_MSG_RESULT([$$4])
|
||||
])
|
||||
|
||||
|
||||
# MCA_backtrace_execinfo_CONFIG(action-if-can-compile,
|
||||
# [action-if-cant-compile])
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_backtrace_execinfo_CONFIG],[
|
||||
AC_CHECK_HEADERS([execinfo.h])
|
||||
# FreeBSD has backtrace in -lexecinfo, usually in libc
|
||||
OMPI_CHECK_FUNC_LIB([backtrace], [execinfo],
|
||||
[backtrace_execinfo_happy="yes"],
|
||||
[backtrace_execinfo_happy="no"])
|
||||
|
||||
AS_IF([test "$backtrace_execinfo_happy" = "yes"],
|
||||
[$1], [$2])
|
||||
])
|
15
opal/mca/backtrace/execinfo/configure.params
Обычный файл
15
opal/mca/backtrace/execinfo/configure.params
Обычный файл
@ -0,0 +1,15 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# Specific to this module
|
||||
|
||||
PARAM_CONFIG_PRIORITY=30
|
||||
PARAM_CONFIG_FILES="Makefile"
|
23
opal/mca/backtrace/none/Makefile.am
Обычный файл
23
opal/mca/backtrace/none/Makefile.am
Обычный файл
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
noinst_LTLIBRARIES = libmca_backtrace_none.la
|
||||
|
||||
libmca_backtrace_none_la_SOURCES = \
|
||||
backtrace_none.c \
|
||||
backtrace_none_component.c
|
33
opal/mca/backtrace/none/backtrace_none.c
Обычный файл
33
opal/mca/backtrace/none/backtrace_none.c
Обычный файл
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
opal_backtrace_print(FILE *file)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
opal_backtrace_buffer(char ***message_out, int *len_out);
|
||||
{
|
||||
*messages_out = NULL;
|
||||
*len_out = 0;
|
||||
|
||||
return OMPI_ERR_NOT_IMPLEMENTED
|
||||
}
|
47
opal/mca/backtrace/none/backtrace_none_component.c
Обычный файл
47
opal/mca/backtrace/none/backtrace_none_component.c
Обычный файл
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
|
||||
const opal_backtrace_base_component_1_0_0_t mca_backtrace_none_component = {
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
{
|
||||
/* Indicate that we are a backtrace v1.0.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
OPAL_BACKTRACE_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
"none",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* Next the MCA v1.0.0 component meta data */
|
||||
{
|
||||
/* Whether the component is checkpointable or not */
|
||||
true
|
||||
},
|
||||
};
|
30
opal/mca/backtrace/none/configure.m4
Обычный файл
30
opal/mca/backtrace/none/configure.m4
Обычный файл
@ -0,0 +1,30 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([MCA_backtrace_none_COMPILE_MODE], [
|
||||
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||
$4="static"
|
||||
AC_MSG_RESULT([$$4])
|
||||
])
|
||||
|
||||
|
||||
# MCA_backtrace_none_CONFIG(action-if-can-compile,
|
||||
# [action-if-cant-compile])
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_backtrace_none_CONFIG],[$1])
|
15
opal/mca/backtrace/none/configure.params
Обычный файл
15
opal/mca/backtrace/none/configure.params
Обычный файл
@ -0,0 +1,15 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# Specific to this module
|
||||
|
||||
PARAM_CONFIG_PRIORITY=0
|
||||
PARAM_CONFIG_FILES="Makefile"
|
23
opal/mca/backtrace/printstack/Makefile.am
Обычный файл
23
opal/mca/backtrace/printstack/Makefile.am
Обычный файл
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
noinst_LTLIBRARIES = libmca_backtrace_printstack.la
|
||||
|
||||
libmca_backtrace_printstack_la_SOURCES = \
|
||||
backtrace_printstack.c \
|
||||
backtrace_printstack_component.c
|
38
opal/mca/backtrace/printstack/backtrace_printstack.c
Обычный файл
38
opal/mca/backtrace/printstack/backtrace_printstack.c
Обычный файл
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
opal_backtrace_print(FILE *file)
|
||||
{
|
||||
printstack(fileno(file));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
opal_backtrace_buffer(char ***message_out, int *len_out);
|
||||
{
|
||||
*messages_out = NULL;
|
||||
*len_out = 0;
|
||||
|
||||
/* BWB - I think we can implement this in a similar way that
|
||||
printstack is implemented. I just don't have time right
|
||||
now. */
|
||||
|
||||
return OMPI_ERR_NOT_IMPLEMENTED
|
||||
}
|
47
opal/mca/backtrace/printstack/backtrace_printstack_component.c
Обычный файл
47
opal/mca/backtrace/printstack/backtrace_printstack_component.c
Обычный файл
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
|
||||
const opal_backtrace_base_component_1_0_0_t mca_backtrace_printstack_component = {
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
{
|
||||
/* Indicate that we are a backtrace v1.0.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
OPAL_BACKTRACE_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
"printstack",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* Next the MCA v1.0.0 component meta data */
|
||||
{
|
||||
/* Whether the component is checkpointable or not */
|
||||
true
|
||||
},
|
||||
};
|
39
opal/mca/backtrace/printstack/configure.m4
Обычный файл
39
opal/mca/backtrace/printstack/configure.m4
Обычный файл
@ -0,0 +1,39 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([MCA_backtrace_printstack_COMPILE_MODE], [
|
||||
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||
$4="static"
|
||||
AC_MSG_RESULT([$$4])
|
||||
])
|
||||
|
||||
|
||||
# MCA_backtrace_printstack_CONFIG(action-if-can-compile,
|
||||
# [action-if-cant-compile])
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_backtrace_printstack_CONFIG],[
|
||||
AC_CHECK_HEADERS([ucontext.h])
|
||||
# FreeBSD has backtrace in -lexecinfo, usually in libc
|
||||
AC_CHECK_FUNCS([printstack],
|
||||
[backtrace_printstack_happy="yes"],
|
||||
[backtrace_printstack_happy="no"])
|
||||
|
||||
AS_IF([test "$backtrace_printstack_happy" = "yes"],
|
||||
[$1], [$2])
|
||||
])
|
15
opal/mca/backtrace/printstack/configure.params
Обычный файл
15
opal/mca/backtrace/printstack/configure.params
Обычный файл
@ -0,0 +1,15 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# Specific to this module
|
||||
|
||||
PARAM_CONFIG_PRIORITY=30
|
||||
PARAM_CONFIG_FILES="Makefile"
|
@ -24,14 +24,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UCONTEXT_H
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
@ -42,6 +34,7 @@
|
||||
|
||||
#include "opal/util/stacktrace.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/mca/backtrace/backtrace.h"
|
||||
#include "opal/constants.h"
|
||||
|
||||
#ifndef _NSIG
|
||||
@ -67,12 +60,6 @@
|
||||
#if OMPI_WANT_PRETTY_PRINT_STACKTRACE && ! defined(__WINDOWS__)
|
||||
static void opal_show_stackframe (int signo, siginfo_t * info, void * p)
|
||||
{
|
||||
#ifdef HAVE_BACKTRACE
|
||||
int i;
|
||||
int trace_size;
|
||||
void * trace[32];
|
||||
char ** messages = (char **)NULL;
|
||||
#endif
|
||||
char print_buffer[1024];
|
||||
char * tmp = print_buffer;
|
||||
int size = sizeof (print_buffer);
|
||||
@ -295,17 +282,7 @@ static void opal_show_stackframe (int signo, siginfo_t * info, void * p)
|
||||
write(fileno(stderr), print_buffer, sizeof(print_buffer)-size);
|
||||
fflush(stderr);
|
||||
|
||||
#ifdef HAVE_BACKTRACE
|
||||
trace_size = backtrace (trace, 32);
|
||||
messages = backtrace_symbols (trace, trace_size);
|
||||
|
||||
for (i = 0; i < trace_size; i++) {
|
||||
fprintf(stderr, "[%d] func:%s\n", i, messages[i]);
|
||||
fflush(stderr);
|
||||
}
|
||||
#elif defined(HAVE_PRINTSTACK)
|
||||
printstack(fileno(stderr));
|
||||
#endif
|
||||
opal_backtrace_print(stderr);
|
||||
|
||||
write(fileno(stderr), eof_msg, sizeof(eof_msg));
|
||||
fflush(stderr);
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user