2013-03-02 73 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