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;
}

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を持っていないので、これがそれを表示する唯一の方法です:

ここに画像の説明を入力

catch ブロックが失敗するのはなぜですか? どうすれば修正できますか?

ノート:

osm.h ファイルをまったく変更できません (演習の一環として)

4

1 に答える 1

3

C++ の例外がコードによって問題なくキャッチされることがわかると思います。

ただし、インライン アセンブリをいじり始め、アセンブリが不足していると、すべての賭けが無効になります。

EXC_BAD_INSTRUCTIONこれは C++ の例外ではなく、プログラムが不正なことを行ったことを示しています。これは、C++ 抽象化レベルのすぐ下で発生します。

于 2013-03-02T11:20:25.163 に答える