0

在我的 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;
}

主文件

#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,这是显示它的唯一方法:

在此处输入图像描述

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

笔记:

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

4

1 回答 1

3

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

但是,如果您开始搞乱内联汇编,并且您的汇编有缺陷,那么所有的赌注都将失败。

EXC_BAD_INSTRUCTION不是 C++ 异常,它表明您的程序做了一些非法的事情。这发生在 C++ 抽象级别之下。

于 2013-03-02T11:20:25.163 回答