* 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
|
1.2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
- Added stacktrace support for Solaris and Mac OS X.
|
||||||
- Update event library to libevent-1.1a
|
- Update event library to libevent-1.1a
|
||||||
- Fixed standards conformance issues with MPI_ERR_TRUNCATED and
|
- Fixed standards conformance issues with MPI_ERR_TRUNCATED and
|
||||||
setting MPI_ERROR during MPI_TEST/MPI_WAIT.
|
setting MPI_ERROR during MPI_TEST/MPI_WAIT.
|
||||||
|
@ -17,7 +17,7 @@ dnl
|
|||||||
dnl $HEADER$
|
dnl $HEADER$
|
||||||
dnl
|
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
|
# 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
|
# 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
|
# see if we actually have $1. Use AC_CHECK_FUNCS so that it
|
||||||
# does the glibc "not implemented" check. Will use the current LIBS,
|
# does the glibc "not implemented" check. Will use the current LIBS,
|
||||||
# so will check in -l$2 if we decided we needed it above
|
# 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
|
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 \
|
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 \
|
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 \
|
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 \
|
time.h termios.h ulimit.h unistd.h util.h utmp.h malloc.h])
|
||||||
ucontext.h])
|
|
||||||
|
|
||||||
# Needed to work around Darwin requiring sys/socket.h for
|
# Needed to work around Darwin requiring sys/socket.h for
|
||||||
# net/if.h
|
# net/if.h
|
||||||
@ -689,16 +688,13 @@ AC_CHECK_LIB([socket], [socket])
|
|||||||
# Solaris has sched_yeild in -lrt, usually in libc
|
# Solaris has sched_yeild in -lrt, usually in libc
|
||||||
OMPI_CHECK_FUNC_LIB([sched_yield], [rt])
|
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
|
# IRIX has dirname in -lgen, usually in libc
|
||||||
OMPI_CHECK_FUNC_LIB([dirname], [gen])
|
OMPI_CHECK_FUNC_LIB([dirname], [gen])
|
||||||
|
|
||||||
# Darwin doesn't need -lm, as it's a symlink to libSystem.dylib
|
# Darwin doesn't need -lm, as it's a symlink to libSystem.dylib
|
||||||
OMPI_CHECK_FUNC_LIB([ceil], [m])
|
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)
|
# 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>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_EXECINFO_H
|
|
||||||
#include <execinfo.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UCONTEXT_H
|
|
||||||
#include <ucontext.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
#ifdef HAVE_STRING_H
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
@ -42,6 +34,7 @@
|
|||||||
|
|
||||||
#include "opal/util/stacktrace.h"
|
#include "opal/util/stacktrace.h"
|
||||||
#include "opal/mca/base/mca_base_param.h"
|
#include "opal/mca/base/mca_base_param.h"
|
||||||
|
#include "opal/mca/backtrace/backtrace.h"
|
||||||
#include "opal/constants.h"
|
#include "opal/constants.h"
|
||||||
|
|
||||||
#ifndef _NSIG
|
#ifndef _NSIG
|
||||||
@ -67,12 +60,6 @@
|
|||||||
#if OMPI_WANT_PRETTY_PRINT_STACKTRACE && ! defined(__WINDOWS__)
|
#if OMPI_WANT_PRETTY_PRINT_STACKTRACE && ! defined(__WINDOWS__)
|
||||||
static void opal_show_stackframe (int signo, siginfo_t * info, void * p)
|
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 print_buffer[1024];
|
||||||
char * tmp = print_buffer;
|
char * tmp = print_buffer;
|
||||||
int size = sizeof (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);
|
write(fileno(stderr), print_buffer, sizeof(print_buffer)-size);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
opal_backtrace_print(stderr);
|
||||||
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
|
|
||||||
|
|
||||||
write(fileno(stderr), eof_msg, sizeof(eof_msg));
|
write(fileno(stderr), eof_msg, sizeof(eof_msg));
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user