Tom
Tom

Reputation: 9653

c++ catch all exception fails on Os X

Under my ubuntu 32bit computer everything works great. But when my friend tries the code below the program is aborted and the try catch block fails. This is weird since it's a catch all block.

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

He is thrown when the line:

OSM_NULLSYSCALL;

is called. I know SO doesn't like print screens but since I don't have an OS X this is the only way to show it:

enter image description here

Why does my catch block fail? How can I fix it?

Note:

I can't modify the osm.h file at all (as a part of our exercise)

Upvotes: 0

Views: 365

Answers (1)

paxdiablo
paxdiablo

Reputation: 882048

I think you'll find that C++ exceptions are caught just fine by your code.

However, if you start messing about with inline assembly, and your assembly is deficient, all bets are off.

EXC_BAD_INSTRUCTION is not a C++ exception, it's an indication that your program did something illegal. This happens well underneath the C++ abstraction level.

Upvotes: 3

Related Questions