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 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
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
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
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"
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
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
I _do_ include setjmp.h, this is not the problem...i don't get errors
due to that, anyway! ;)
Greetings,
Fabiano
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
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
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
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
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
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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?
...
|
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...
|
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...
|
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...
|
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...
|
by: junw2000 |
last post by:
Is C++ Exception handling useful? think it is too complicated. What
kinds of project need to use it? Thanks.
|
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,...
|
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...
|
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...
|
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...
|
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...
|
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)...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
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
|
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...
|
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...
| |