473,320 Members | 1,732 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Exception handling crashes or exits

Hi folks!

I'm using gcc 4.2.3 and glibc6 2.7.
I'm doing an exception handling implementation for a library. Although I
assume to have it done properly, with a handler set up, it exits the program
with a random exit value, and without a handler set up, it crashes with a
SIGSEGV, but as I have found out with gdb, at the same line of code:

__libc_siglongjmp (env=0xbfb935f0, val=1) at longjmp.c:29
29 {
31 _longjmp_unwind (env, val);
_longjmp_unwind (env=0xbfb935f0, val=1) at
../nptl/sysdeps/unix/sysv/linux/jmp-unwind.c:32
32 if (__libc_pthread_functions_init)
39 }
__libc_siglongjmp (env=0xbfb935f0, val=1) at longjmp.c:33
33 if (env[0].__mask_was_saved)
39 __longjmp (env[0].__jmpbuf, val ?: 1);
The types i use are:

typedef struct ExcType ExcType;
typedef struct ExcVal ExcVal;
typedef struct Exception Exception;
struct ExcType {
const char *name;
};
union ExcVal {
void* None;
int Int;
char* Char;
};
typedef enum {
NoneType,
IntType,
CharType
} Datatype;
struct Exception {
ExcType *tp;
ExcVal *val;
Datatype dt;
};
struct ExcEntry {
ExcEntry *prev,*next;
jmp_buf buf;
Exception *exc;
};
extern ExcEntry *currexc;
My macros for doing exception handling are as follows:

#define try \
{\
Exception exc;\
ExcEntry excn;\
excn.exc=&exc; excn.prev=currexc;\
currexc = excn.prev->next = &excn;\
if ( setjmp(excn.buf)==0 )
#define catch(e) \
Exception *e = &exc;\
for (;0;currexc=currexc->prev)
#define exctype(et, action) \
if ( e->tp==&et ) { action; }
#define endtry }
#define throw(t,vl) \
{currexc->exc->tp=NULL;\
currexc->exc->tp=&t;\
currexc->exc->val->Char=(char*)vl;\
currexc->exc->dt=CharType;\
jmp_buf buf;\
memcpy((void*)&buf,(void*)currexc->buf, sizeof(jmp_buf));\
longjmp(buf,1);}
A sample program could be:

#include <stdio.h>
ExcType RuntimeError;
int main(int argc, char **argv)
{
try {
throw(RuntimeError,"test error");
} catch(e) {
fprintf(stderr,"foobar!\n");
exit(42);
} endtry;
}
I don't see where the problem is. Any professional here who can help me?

Greetings,
Fabiano
Sep 8 '08 #1
12 1679
On 2008-09-08, Fabiano Sidler <fa***********@my-mail.chwrote:
Hi folks!

I'm using gcc 4.2.3 and glibc6 2.7.
I'm doing an exception handling implementation for a library. Although I
assume to have it done properly, with a handler set up, it exits the program
with a random exit value, and without a handler set up, it crashes with a
SIGSEGV, but as I have found out with gdb, at the same line of code:

__libc_siglongjmp (env=0xbfb935f0, val=1) at longjmp.c:29
29 {
31 _longjmp_unwind (env, val);
_longjmp_unwind (env=0xbfb935f0, val=1) at
../nptl/sysdeps/unix/sysv/linux/jmp-unwind.c:32
32 if (__libc_pthread_functions_init)
39 }
__libc_siglongjmp (env=0xbfb935f0, val=1) at longjmp.c:33
33 if (env[0].__mask_was_saved)
39 __longjmp (env[0].__jmpbuf, val ?: 1);
The types i use are:

typedef struct ExcType ExcType;
typedef struct ExcVal ExcVal;
typedef struct Exception Exception;
struct ExcType {
const char *name;
};
union ExcVal {
void* None;
int Int;
char* Char;
};
typedef enum {
NoneType,
IntType,
CharType
} Datatype;
struct Exception {
ExcType *tp;
ExcVal *val;
Datatype dt;
};
struct ExcEntry {
ExcEntry *prev,*next;
jmp_buf buf;
Exception *exc;
};
extern ExcEntry *currexc;
Where is this defined? You appear to use it without ever
defining it. Does this program link successfully?
>
My macros for doing exception handling are as follows:

#define try \
{\
Exception exc;\
ExcEntry excn;\
excn.exc=&exc; excn.prev=currexc;\
currexc = excn.prev->next = &excn;\
if ( setjmp(excn.buf)==0 )
#define catch(e) \
Exception *e = &exc;\
for (;0;currexc=currexc->prev)
#define exctype(et, action) \
if ( e->tp==&et ) { action; }
#define endtry }
#define throw(t,vl) \
{currexc->exc->tp=NULL;\
currexc->exc->tp=&t;\
currexc->exc->val->Char=(char*)vl;\
currexc->exc->dt=CharType;\
jmp_buf buf;\
memcpy((void*)&buf,(void*)currexc->buf, sizeof(jmp_buf));\
longjmp(buf,1);}
A sample program could be:

#include <stdio.h>
ExcType RuntimeError;
int main(int argc, char **argv)
{
try {
throw(RuntimeError,"test error");
} catch(e) {
fprintf(stderr,"foobar!\n");
exit(42);
} endtry;
}
I don't see where the problem is. Any professional here who can help me?

Greetings,
Fabiano

--
Andrew Poelstra ap*******@wpsoftware.com
To email me, use the above email addresss with .com set to .net
Sep 8 '08 #2
On 2008-09-08, Andrew Poelstra <ap*******@supernova.homewrote:
Where is this defined?
jmp_buf is defined in setjmp.h which is, in turn, an ANSI C header.
Maybe i should have written this...in my program, it is included.
Does this program link successfully?
<setjmp.hmust be included and the definitions (and the declaration)
must be done before main(), but then it does, otherwise it couldn't SEGSEGV
here...;)

Greetings,
Fabiano
Sep 8 '08 #3
On 2008-09-08, Fabiano Sidler <fa***********@my-mail.chwrote:
On 2008-09-08, Andrew Poelstra <ap*******@supernova.homewrote:
>Where is this defined?

jmp_buf is defined in setjmp.h which is, in turn, an ANSI C header.
Maybe i should have written this...in my program, it is included.
Sure, but jmp_buf is just a member of the currexc object, for
which storage is never allocated (since this object is not
defined, as far as I can tell).
>Does this program link successfully?

<setjmp.hmust be included and the definitions (and the declaration)
must be done before main(), but then it does, otherwise it couldn't SEGSEGV
here...;)
--
Andrew Poelstra ap*******@wpsoftware.com
To email me, use the above email addresss with .com set to .net
Sep 8 '08 #4
Andrew Poelstra <ap*******@supernova.homewrites:
On 2008-09-08, Fabiano Sidler <fa***********@my-mail.chwrote:
>On 2008-09-08, Andrew Poelstra <ap*******@supernova.homewrote:
>>Where is this defined?

jmp_buf is defined in setjmp.h which is, in turn, an ANSI C header.
Maybe i should have written this...in my program, it is included.

Sure, but jmp_buf is just a member of the currexc object, for
which storage is never allocated (since this object is not
defined, as far as I can tell).
Here's the relevant code from the original article:
| struct ExcEntry {
| ExcEntry *prev,*next;
| jmp_buf buf;
| Exception *exc;
| };
| extern ExcEntry *currexc;

jmp_buf is a type, declared in the standard header <setjmp.h>. The
point is simply that you can't refer to the name "jmp_buf" unless you
have a "#include <setjmp.h>".

buf, on the other hand, is a member of the type struct ExcEntry; that
member is of type jmp_buf. And currexc is a pointer to struct
ExcEntry. So buf (not jmp_buf) is a member of *currexc (not currexc).

[...]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '08 #5
On 2008-09-09, Keith Thompson <ks***@mib.orgwrote:
Andrew Poelstra <ap*******@supernova.homewrites:
>On 2008-09-08, Fabiano Sidler <fa***********@my-mail.chwrote:
>>On 2008-09-08, Andrew Poelstra <ap*******@supernova.homewrote:
Where is this defined?

jmp_buf is defined in setjmp.h which is, in turn, an ANSI C header.
Maybe i should have written this...in my program, it is included.

Sure, but jmp_buf is just a member of the currexc object, for
which storage is never allocated (since this object is not
defined, as far as I can tell).

Here's the relevant code from the original article:
| struct ExcEntry {
| ExcEntry *prev,*next;
| jmp_buf buf;
| Exception *exc;
| };
| extern ExcEntry *currexc;

jmp_buf is a type, declared in the standard header <setjmp.h>. The
point is simply that you can't refer to the name "jmp_buf" unless you
have a "#include <setjmp.h>".

buf, on the other hand, is a member of the type struct ExcEntry; that
member is of type jmp_buf. And currexc is a pointer to struct
ExcEntry. So buf (not jmp_buf) is a member of *currexc (not currexc).

[...]
But currexc is declared as extern and never defined, so when is
storage set aside for the pointer itself?

(But you are right, I missed that currexc was a pointer.)

--
Andrew Poelstra ap*******@wpsoftware.com
To email me, use the above email addresss with .com set to .net
Sep 9 '08 #6
Fabiano Sidler <fabianosid...@my-mail.chwrote:
I'm doing an exception handling implementation for a
library. ...

The types i use are:

typedef struct ExcType ExcType;
typedef struct ExcVal ExcVal;
typedef struct Exception Exception;
struct ExcType {
* * * * const char *name;};

union ExcVal {
* * * * void* None;
* * * * int Int;
* * * * char* Char;};

typedef enum {
* * * * NoneType,
* * * * IntType,
* * * * CharType} Datatype;

struct Exception {
* * * * ExcType *tp;
* * * * ExcVal *val;
* * * * Datatype dt;};

struct ExcEntry {
* * * * ExcEntry *prev,*next;
* * * * jmp_buf buf;
* * * * Exception *exc;};

extern ExcEntry *currexc;

My macros for doing exception handling are as follows:

#define try \
* * * * {\
* * * * * * * * Exception exc;\
* * * * * * * * ExcEntry excn;\
* * * * * * * * excn.exc=&exc; excn.prev=currexc;\
Are you sure currexc is not a null pointer?
* * * * * * * * currexc = excn.prev->next = &excn;\
If it is, this line is problematic.
* * * * * * * * if ( setjmp(excn.buf)==0 )
#define catch(e) \
* * * * * * * * Exception *e = &exc;\
Seems to be missing an 'else' for the above 'if'. Also,
I prefer to insert the { } blocks directly (split across
the macros,) rather than relying on the user to supply
them.
* * * * * * * * for (;0;currexc=currexc->prev)
#define exctype(et, action) \
* * * * * * * * * * * * if ( e->tp==&et ) { action; }
#define endtry *}
#define throw(t,vl) \
* * * * {currexc->exc->tp=NULL;\
* * * * currexc->exc->tp=&t;\
* * * * currexc->exc->val->Char=(char*)vl;\
* * * * currexc->exc->dt=CharType;\
* * * * jmp_buf buf;\
* * * * memcpy((void*)&buf,(void*)currexc->buf, sizeof(jmp_buf));\
* * * * longjmp(buf,1);}

A sample program could be:

#include <stdio.h>
ExcType RuntimeError;
int main(int argc, char **argv)
{
* * * * try {
* * * * * * * * throw(RuntimeError,"test error");
* * * * } catch(e) {
* * * * * * * * fprintf(stderr,"foobar!\n");
* * * * * * * * exit(42);
* * * * } endtry;

}

I don't see where the problem is. Any professional here who can help me?

Greetings,
Fabiano
Sep 9 '08 #7
I _do_ include setjmp.h, this is not the problem...i don't get errors
due to that, anyway! ;)

Greetings,
Fabiano
Sep 9 '08 #8
On 2008-09-09, Peter Nilsson <ai***@acay.com.auwrote:
Are you sure currexc is not a null pointer?
currexc is initialized as follows:

ExcEntry *currexc = &(ExcEntry) {
NULL,
NULL,
{0},
&(Exception) {
NULL,
&(ExcVal) { 0 },
0
}
};

And yes, this is valid C, C99! ;)
Your other points i'm working on right now...:)

Thanks in advance,
Fabiano
Sep 9 '08 #9
Here is the complete demo program:

--- snip ---
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>

typedef struct ExcType ExcType;
typedef union ExcVal ExcVal;
typedef struct Exception Exception;
typedef struct ExcEntry ExcEntry;
struct ExcType {
const char *name;
};
union ExcVal {
void* None;
int Int;
char* Char;
};
typedef enum {
NoneType,
IntType,
CharType
} Datatype;
struct Exception {
ExcType *tp;
ExcVal *val;
Datatype dt;
};
struct ExcEntry {
ExcEntry *prev,*next;
jmp_buf buf;
Exception *exc;
};
ExcEntry *currexc = &(ExcEntry) {
NULL,
NULL,
{0},
&(Exception) {
NULL, &(ExcVal){0}, 0
}
};
#define try \
{\
Exception exc;\
ExcEntry excn;\
excn.exc=&exc; excn.prev=currexc;\
currexc = excn.prev->next = &excn;\
if ( setjmp(excn.buf)==0 )
#define catch(e) \
Exception *e = &exc;\
for (;0;currexc=currexc->prev)
#define exctype(et, action) \
if ( e->tp==&et ) { action; }
#define endtry }
#define throw(t,vl) \
{currexc->exc->tp=NULL;\
currexc->exc->tp=&t;\
currexc->exc->val->Char=(char*)vl;\
currexc->exc->dt=CharType;\
jmp_buf buf;\
memcpy((void*)&buf,(void*)currexc->buf, sizeof(jmp_buf));\
longjmp(buf,1);}

ExcType RuntimeError;

int main(int argc, char **argv)
{
try {
throw(RuntimeError,"test error");
} catch(e) {
fprintf(stderr, "caught\n");
exit(0);
} endtry
fprintf(stderr, "uncaught\n");
return 42;
}
--- snap ---

Greetings,
Fabiano
Sep 9 '08 #10
Fabiano Sidler wrote:
Here is the complete demo program:

--- snip ---
int main(int argc, char **argv)
{
try {
throw(RuntimeError,"test error");
} catch(e) {
fprintf(stderr, "caught\n");
exit(0);
} endtry
fprintf(stderr, "uncaught\n");
return 42;
}
--- snap ---
The deliberate obfuscation of your code,
makes the solving your problem, much less interesting.

--
pete
Sep 9 '08 #11
Fabiano Sidler wrote:
Here is the complete demo program:

--- snip ---
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>

typedef struct ExcType ExcType;
typedef union ExcVal ExcVal;
typedef struct Exception Exception;
typedef struct ExcEntry ExcEntry;
struct ExcType {
const char *name;
};
union ExcVal {
void* None;
int Int;
char* Char;
};
typedef enum {
NoneType,
IntType,
CharType
} Datatype;
struct Exception {
ExcType *tp;
ExcVal *val;
Datatype dt;
};
struct ExcEntry {
ExcEntry *prev,*next;
jmp_buf buf;
Exception *exc;
};
ExcEntry *currexc = &(ExcEntry) {
NULL,
NULL,
{0},
&(Exception) {
NULL, &(ExcVal){0}, 0
}
};
#define try \
{\
Exception exc;\
ExcEntry excn;\
excn.exc=&exc; excn.prev=currexc;\
currexc = excn.prev->next = &excn;\
if ( setjmp(excn.buf)==0 )
I'm not sure what you try to accomplish in the "catch" macro. But do you
really want to execute the for-loop zero times?
#define catch(e) \
Exception *e = &exc;\
for (;0;currexc=currexc->prev)
#define exctype(et, action) \
if ( e->tp==&et ) { action; }
#define endtry }
#define throw(t,vl) \
{currexc->exc->tp=NULL;\
currexc->exc->tp=&t;\
Isn't currexc->exc->val a NULL pointer at this point. Thus giving you
the SIGSEGV?
currexc->exc->val->Char=(char*)vl;\
currexc->exc->dt=CharType;\
jmp_buf buf;\
memcpy((void*)&buf,(void*)currexc->buf, sizeof(jmp_buf));\
longjmp(buf,1);}

ExcType RuntimeError;

int main(int argc, char **argv)
{
try {
throw(RuntimeError,"test error");
} catch(e) {
fprintf(stderr, "caught\n");
exit(0);
} endtry
fprintf(stderr, "uncaught\n");
return 42;
}
--- snap ---

Greetings,
Fabiano
Sep 9 '08 #12
Fabiano Sidler <fa***********@my-mail.chwrites:
Here is the complete demo program:

--- snip ---
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>

typedef struct ExcType ExcType;
typedef union ExcVal ExcVal;
typedef struct Exception Exception;
typedef struct ExcEntry ExcEntry;
struct ExcType {
const char *name;
};
union ExcVal {
void* None;
int Int;
char* Char;
};
typedef enum {
NoneType,
IntType,
CharType
} Datatype;
struct Exception {
ExcType *tp;
ExcVal *val;
Datatype dt;
};
struct ExcEntry {
ExcEntry *prev,*next;
jmp_buf buf;
Exception *exc;
};
ExcEntry *currexc = &(ExcEntry) {
NULL,
NULL,
{0},
&(Exception) {
NULL, &(ExcVal){0}, 0
}
};
#define try \
{\
Exception exc;\
ExcEntry excn;\
excn.exc=&exc; excn.prev=currexc;\
You have not initialized exc.val to point to anything...
currexc = excn.prev->next = &excn;\
if ( setjmp(excn.buf)==0 )
#define catch(e) \
Exception *e = &exc;\
for (;0;currexc=currexc->prev)
#define exctype(et, action) \
if ( e->tp==&et ) { action; }
#define endtry }
#define throw(t,vl) \
{currexc->exc->tp=NULL;\
currexc->exc->tp=&t;\
currexc->exc->val->Char=(char*)vl;\
so it crashes here.

After fixing this it doesn't crash, but it still doesn't catch the
exception. I'm a bit suspicious of your linked list handling, since
the `next' pointers never seem to be used. I don't have the time to
trace through it now, but I'd recommend a careful look.

For debugging I found it helpful to do

gcc -E foo.c |grep -v '# [0-9]' |indent >foo.i
gcc -g foo.i

so that the macros are expanded onto multiple lines, making it easier
to single-step in a debugger.

currexc->exc->dt=CharType;\
jmp_buf buf;\
memcpy((void*)&buf,(void*)currexc->buf, sizeof(jmp_buf));\
longjmp(buf,1);}

ExcType RuntimeError;

int main(int argc, char **argv)
{
try {
throw(RuntimeError,"test error");
} catch(e) {
fprintf(stderr, "caught\n");
exit(0);
} endtry
fprintf(stderr, "uncaught\n");
return 42;
}
--- snap ---

Greetings,
Fabiano
Sep 9 '08 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Michael Zhang | last post by:
My project uses Python-2.3.4 + Tkinter + PIL-1.1.4 to retrieve images from server and display those images. I created a thread (also a separate toplevel window) for displaying images and another...
12
by: Ritz, Bruno | last post by:
hi in java i found that when a method has a throws clause in the definition, callers must either handle the exceptions thrown by the method they are calling or "forward" the exception to the...
9
by: Kevin Goodsell | last post by:
If I'm writing a class that will be used as an exception, what kinds of things do I need to watch out for? For example, is it necessary to make sure that the members of the class don't throw? ...
6
by: Daniel Wilson | last post by:
I am having exception-handling and stability problems with .NET. I will have a block of managed code inside try...catch and will still get a generic ..NET exception box that will tell me which...
1
by: linq936 | last post by:
Hi, I am using gcc3.2.3 on Red Hat Linux. I just find a strange thing of exception handling:if I compile the code in debug level, then the exception can be caught; if I compile it in optimized...
9
by: David B | last post by:
Why is it so difficult to report bugs to Microsoft? I have a documented bug and an small test example. I don't really see why I should have to pay to tell them about it... Anyway, the...
3
by: HairlipDog58 | last post by:
I have a VC++6 project where I need to delay load a DLL. I used a structured exception handling frame and all seems to work when I build the debug version and run it (either in or out of the...
13
by: junw2000 | last post by:
Is C++ Exception handling useful? think it is too complicated. What kinds of project need to use it? Thanks.
20
by: joseph_gallagher | last post by:
Hi, I've recently ported a .Net 1.1 application to .Net 2.0 and the one new feature that is getting on my nerves is that when there is an unhandled exception the application completely crashes,...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.