2013-03-02 61 views
0

在我的Ubuntu 32位计算机下,一切都很好。但是,当我的朋友尝试下面的代码时,程序被中止,try catch块失败。这很奇怪,因为它是一个全部阻挡块。C++捕获所有异常失败在Os X

osm.h:

#ifndef _OSM_H 
#define _OSM_H 


/* calling a system call that does nothing */ 
#define OSM_NULLSYSCALL asm volatile("int $0x80 " : : \ 
     "a" (0xffffffff) /* no such syscall */, "b" (0), "c" (0), "d" (0) /*:\ 
     "eax", "ebx", "ecx", "edx"*/) 


/* Time measurement function for an empty function call. 
    returns time in nano-seconds upon success, 
    and -1 upon failure. 
    */ 
double osm_function_time(unsigned int osm_iterations); 

/* Time measurement function for an empty trap into the operating system. 
    returns time in nano-seconds upon success, 
    and -1 upon failure. 
    */ 
double osm_syscall_time(unsigned int osm_iterations); 

/* Time measurement function for a simple arithmetic operation. 
    returns time in nano-seconds upon success, 
    and -1 upon failure. 
    */ 
double osm_operation_time(unsigned int osm_iterations); 

typedef struct { 
    char* machineName; 
    int numberOfIterations; 
    double instructionTimeNanoSecond; 
    double functionTimeNanoSecond; 
    double trapTimeNanoSecond; 
    double functionInstructionRatio; 
    double trapInstructionRatio;  
} timeMeasurmentStructure; 

timeMeasurmentStructure measureTimes (unsigned int numOfIterations); 


#endif 

osm.cpp

#include "osm.h" 
#include <cmath> 
#include <stdlib.h> 
#include <sys/time.h> 
#include <unistd.h> 
#define SEC_MICROSEC_RATIO 1000000 
#define NANOSEC_MICROSEC_RATIO 1000 
#define DEFAULT_NUM_ITERATIONS 50000 
#define MAX_MACHINE_NAME 30 
#define ERR_CODE -1 

void dummy_function() 
{ 

} 

double osm_function_time(unsigned int osm_iterations) 
{ 
    unsigned int i; 
    double elapsed = 0; 
    struct timeval timeFirst, timeSecond; 

    for (i=0; i<osm_iterations;i++) 
    { 
     gettimeofday(&timeFirst, NULL); 
     dummy_function(); 
     gettimeofday(&timeSecond, NULL); 
     elapsed += (timeSecond.tv_sec-timeFirst.tv_sec)*SEC_MICROSEC_RATIO + timeSecond.tv_usec-timeFirst.tv_usec; 
    } 

    return (elapsed/osm_iterations) * NANOSEC_MICROSEC_RATIO; 
} 

double osm_operation_time(unsigned int osm_iterations) 
{ 
    unsigned int i; 
    int a=1,b=10; 
    double elapsed = 0; 
    struct timeval timeFirst, timeSecond; 

    for (i=0; i<osm_iterations;i++) 
    { 
     gettimeofday(&timeFirst, NULL); 
     a = a + b; 
     gettimeofday(&timeSecond, NULL); 
     elapsed += (timeSecond.tv_sec-timeFirst.tv_sec)*SEC_MICROSEC_RATIO + timeSecond.tv_usec-timeFirst.tv_usec; 
    } 

    return (elapsed/osm_iterations) * NANOSEC_MICROSEC_RATIO; 
} 

double osm_syscall_time(unsigned int osm_iterations) 
{ 
    unsigned int i; 
    double elapsed = 0; 
    struct timeval timeFirst, timeSecond; 

    for (i=0; i<osm_iterations;i++) 
    { 
     gettimeofday(&timeFirst, NULL); 
     OSM_NULLSYSCALL; 
     gettimeofday(&timeSecond, NULL); 
     elapsed += (timeSecond.tv_sec-timeFirst.tv_sec)*SEC_MICROSEC_RATIO + timeSecond.tv_usec-timeFirst.tv_usec; 
    } 

    return (elapsed/osm_iterations) * NANOSEC_MICROSEC_RATIO; 
} 

timeMeasurmentStructure measureTimes (unsigned int numOfIterations) 
{ 
    if (numOfIterations<=0) 
    { 
     numOfIterations = DEFAULT_NUM_ITERATIONS; 
    } 

    timeMeasurmentStructure timer; 
    timer.numberOfIterations = numOfIterations; 

    // get machine name 
    timer.machineName = new char[MAX_MACHINE_NAME]; 
    try{ 
     gethostname(timer.machineName,MAX_MACHINE_NAME); 
    } catch(...){ 
     delete [] timer.machineName; 
     timer.machineName = NULL; 
    } 

    try{ 
     timer.functionTimeNanoSecond = osm_function_time(numOfIterations); 
    } catch(...){ 
     timer.functionTimeNanoSecond = ERR_CODE; 
    } 

    try{ 
     timer.instructionTimeNanoSecond = osm_operation_time(numOfIterations); 
    } catch(...){ 
     timer.instructionTimeNanoSecond = ERR_CODE; 
    } 

    try{ 
     timer.trapTimeNanoSecond = osm_syscall_time(numOfIterations); 
    } catch(...){ 
     timer.trapTimeNanoSecond = ERR_CODE; 
    } 

    // trap/instruction 
    if((timer.trapInstructionRatio!=ERR_CODE) && (timer.trapTimeNanoSecond!=ERR_CODE)) 
    { 
     timer.trapInstructionRatio = timer.trapTimeNanoSecond/timer.instructionTimeNanoSecond; 
    } else 
    { 
     timer.trapInstructionRatio = ERR_CODE; 
    } 

    // function/instruction 
    if((timer.functionTimeNanoSecond!=ERR_CODE) && (timer.instructionTimeNanoSecond!=ERR_CODE)) 
    { 
     timer.functionInstructionRatio = timer.functionTimeNanoSecond/timer.instructionTimeNanoSecond; 
    } else 
    { 
     timer.functionInstructionRatio = ERR_CODE; 
    } 

    return timer; 
} 

的main.cpp

#include <iostream> 
#include "osm.h" 
using namespace std; 

int main() 
{ 
    timeMeasurmentStructure timeMe = measureTimes(0); 
    if(timeMe.machineName!=NULL) 
    { 
     cout << "machine name: " << timeMe.machineName << endl; 
    } 

    cout << "iterations: " << timeMe.numberOfIterations << endl; 
    cout << "instruction time: " << timeMe.instructionTimeNanoSecond << endl; 
    cout << "function time: " << timeMe.functionTimeNanoSecond << endl; 
    cout << "trap time: " << timeMe.trapTimeNanoSecond << endl; 
    cout << "function/instruction ratio: " << timeMe.functionInstructionRatio << endl; 
    cout << "trap/instruction ratio: " << timeMe.trapInstructionRatio << endl; 
    return 0; 
} 

他被抛出时行:

OSM_NULLSYSCALL; 

被调用。我知道,所以不喜欢打印屏幕,但因为我没有一个OS X,这是显示它的唯一途径:

enter image description here

为什么我的catch块会失败?我该如何解决它?

注:

我不能修改在所有osm.h文件(作为我们工作的一部分)

+1

这不是一个C++异常,而是一个系统信号。猜测'int $ 0x80'不是在OSX上执行系统调用的方法。 – 2013-03-02 11:23:50

回答

3

我想你会发现C++异常被抓就好了你的代码。

但是,如果您开始讨论内联装配,并且装配不足,则所有投注都将关闭。

EXC_BAD_INSTRUCTION不是C++异常,这表示您的程序执行了某些非法操作。这发生在C++抽象层次之下。

+0

请注意,某些环境,例如Visual Studio有一个非标准扩展,允许机器异常在C++ catch块中被捕获,就好像它们是C++异常一样。我不知道Linux是否也支持这一点,但显然OS X不支持。 – 2013-03-02 11:22:25

+0

@PaulR,Linux没有:没有Unix信号用于这个目的(笨拙,因为他们可以)。 OSX大致基于BSD,它本身就是一个Unix。 – syam 2013-03-02 11:28:36

+0

@syam - C/C++支持信号。它们不是特定于Unix的。 – 2013-03-02 13:27:54