在我的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,这是显示它的唯一方法:
为什么我的捕获块失败?我该如何解决?
注意:
我根本无法修改osm.h文件(作为练习的一部分)
答案 0 :(得分:3)
我认为您会发现代码可以很好地捕获C ++异常。
但是,如果你开始搞乱内联装配,而你的装配不足,那么所有的赌注都会关闭。
EXC_BAD_INSTRUCTION
不是C ++异常,它表明您的程序执行了非法操作。这恰好发生在C ++抽象级别下面。