c ++在Os X上捕获所有异常失败

时间:2013-03-02 11:16:47

标签: c++ exception

在我的ubuntu 32位电脑下,一切都很棒。但是当我的朋友尝试下面的代码时程序被中止并且try catch块失败。这很奇怪,因为它是一个捕获所有块。

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;

被调用。我知道SO不喜欢打印屏幕,但由于我没有OS X,这是显示它的唯一方法:

enter image description here

为什么我的捕获块失败?我该如何解决?

注意:

我根本无法修改osm.h文件(作为练习的一部分)

1 个答案:

答案 0 :(得分:3)

我认为您会发现代码可以很好地捕获C ++异常。

但是,如果你开始搞乱内联装配,而你的装配不足,那么所有的赌注都会关闭。

EXC_BAD_INSTRUCTION不是C ++异常,它表明您的程序执行了非法操作。这恰好发生在C ++抽象级别下面。