Preventing too many LoadLibrary/FreeLibrary - c

I'm writing a proxy library (called Library A) that is just an interface to another DLL (called Library B) that may be present or not on the system.
The idea is that a program would link to this library A instead of the original library B ; and Library A would handle the errors if Library B wasn't installed on the system.
So a typical proxy function would look like this:
int function(int arg1, int arg2)
{
HINSTANCE hinstLib;
UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
SetErrorMode (errormode);
if (hinstLib != NULL)
{
ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
if (NULL != ProcAdd)
{
return (ProcAdd) (arg1, arg2);
}
FreeLibrary(hinstLib);
}
return ERROR;
}
Now, I would do this for all original entries in Library B. There could be a lot of calls to it.
So loading / unloading the DLL so frequently is certainly going to have an impact speed-wise.
I was wondering if it would be acceptable to use a global variable hinstLib ; something like
HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
int function(int arg1, int arg2)
{
if (hinstLib != NULL)
{
ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
if (NULL != ProcAdd)
{
return (ProcAdd) (arg1, arg2);
}
}
return ERROR;
}
And let Windows automatically unload the DLL when the program exits (assuming it does unload it).
Thanks in advance for your wise remarks...
Jean-Yves

Unless the unloading is particular use case, then this is fine. However I would implement some thread safety to ensure that there are no race conditions through this code using a Critical Section.
This is simillar example to the one from the wikipedia article
/* Sample C/C++, Windows, link to kernel32.dll */
#include <windows.h>
static CRITICAL_SECTION cs;
static HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
/* Initialize the critical section before entering multi-threaded context. */
InitializeCriticalSection(&cs);
void f() {
/* Enter the critical section -- other threads are locked out */
__try {
EnterCriticalSection(&cs);
if (hinstLib != NULL) {
ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
} __finally {
LeaveCriticalSection(&cs);
}
if (NULL != ProcAdd) {
return (ProcAdd) (arg1, arg2);
}
}
.
.
.
/* Release system object when all finished -- usually at the end of the cleanup code */
DeleteCriticalSection(&cs);

Related

Can I check a pthread_t to see if it was initialized by pthread_create, because pthread_join segfaults if pthread_t has not been initialized [duplicate]

I would like to call pthread_join for a given thread id, but only if that thread has been started. The safe solution might be to add a variable to track which thread where started or not. However, I wonder if checking pthread_t variables is possible, something like the following code.
pthread_t thr1 = some_invalid_value; //0 ?
pthread_t thr2 = some_invalid_value;
/* thread 1 and 2 are strated or not depending on various condition */
....
/* cleanup */
if(thr1 != some_invalid_value)
pthread_join(&thr1);
if(thr2 != some_invalid_value)
pthread_join(&thr2);
Where some_invalid_value could be 0, or an implementation dependant 'PTHREAD_INVALID_ID' macro
PS :
My assumption is that pthread_t types are comparable and assignable, assumption based on
PPS :
I wanted to do this, because I thought calling pthread_join on invalid thread id was undefinde behaviour. It is not. However, joining a previously joined thread IS undefined behaviour. Now let's assume the above "function" is called repeatedly.
Unconditionnally calling pthread_join and checking the result might result in calling pthread_join on a previously joined thread.
Your assumption is incorrect to start with. pthread_t objects are opaque. You cannot compare pthread_t types directly in C. You should use pthread_equal instead.
Another consideration is that if pthread_create fails, the contents of your pthread_t will be undefined. It may not be set to your invalid value any more.
My preference is to keep the return values of the pthread_create calls (along with the thread IDs) and use that to determine whether each thread was started correctly.
As suggested by Tony, you can use pthread_self() in this situation.
But do not compare thread_ts using == or !=. Use pthread_equal.
From the pthread_self man page:
Therefore, variables of type pthread_t can't portably be compared using the C equality operator (==); use pthread_equal(3) instead.
I recently ran into this same issue. If pthread_create() failed, I ended up with a undefined, invalid value stored in my phtread_t structure. As a result, I keep a boolean associated with each thread that gets set to true if pthread_create() succeeded.
Then all I need to do is:
void* status;
if (my_thread_running) {
pthread_join(thread, &status);
my_thread_running = false;
}
Unfortunately, on systems where pthread_t is a pointer, pthread_equal() can return equality even though the two args refer to different threads, e.g. a thread can exit and a new thread can be created with the same pthread_t pointer value.
I was porting some code that used pthreads into a C++ application, and I had the same question. I decided it was easier to switch to the C++ std::thread object, which has the .joinable() method to decide whether or not to join, i.e.
if (t.joinable()) t.join();
I found that just calling pthead_join on a bad pthread_t value (as a result of pthread_create failing) caused a seg fault, not just an error return value.
Our issue was that we couldn't know if a pthread had been started or not, so we make it a pointer and allocate/de-allocate it and set it to NULL when not in use:
To start:
pthread_t *pth = NULL;
pth = malloc(sizeof(pthread_t));
int ret = pthread_create(pth, NULL, mythread, NULL);
if( ret != 0 )
{
free(pth);
pth = NULL;
}
And later when we need to join, whether or not the thread was started:
if (pth != NULL)
{
pthread_join(*pth, NULL);
free(pth);
pth = NULL;
}
If you need to respawn threads quickly then the malloc/free cycle is undesirable, but it works for simple cases like ours.
This is an excellent question that I really wish would get more discussion in C++ classes and code tests.
One option for some systems-- which may seem like overkill to you, but has come in handy for me-- is to start a thread which does nothing other than efficiently wait for a tear-down signal, then quit. This thread stays running for the life of the application, going down very late in the shutdown sequence. Until that point, the ID of this thread can effectively be used as an "invalid thread" value-- or, more likely, as an "uninitialized" sentinel-- for most purposes. For example, my debug libraries typically track the threads from which mutexes were locked. This requires initialization of that tracking value to something sensible. Because POSIX rather stupidly declined to require that platforms define an INVALID_THREAD_ID, and because my libraries allow main() to lock things (making the pthread_self checks that are a good solution pthread_create unusable for lock tracking), this is the solution I have come to use. It works on any platform.
Note, however, that you have a little more design work to do if you want this to be able to initialize static thread references to invalid values.
For C++ (not really sure what language the OP was asking about) another simple option (but I think this one is still the simplest as long as you don't need to treat pthread_self() as valid anywhere) would be to use std::optional<pthread_t> (or boost's version if you can't swing C++17 or later, or implement something similar yourself).
Then use .has_value() to check if values are valid, and be happy:
// so for example:
std::optional<pthread_t> create_thread (...) {
pthread_t thread;
if (pthread_create(&thread, ...))
return std::optional<pthread_t>();
else
return thread;
}
// then:
std::optional<pthread_t> id = create_thread(...);
if (id.has_value()) {
pthread_join(id.value(), ...);
} else {
...;
}
You still need to use pthread_equal when comparing valid values, so all the same caveats apply. However, you can reliably compare any value to an invalid value, so stuff like this will be fine:
// the default constructed optional has no value
const std::optional<pthread_t> InvalidID;
pthread_t id1 = /* from somewhere, no concept of 'invalid'. */;
std::optional<pthread_t> id2 = /* from somewhere. */;
// all of these will still work:
if (id1 == InvalidID) { } // ok: always false
if (id1 != InvalidID) { } // ok: always true
if (id2 == InvalidID) { } // ok: true if invalid, false if not.
if (id2 != InvalidID) { } // ok: true if valud, false if not.
Btw, if you also want to give yourself some proper comparison operators, though, or if you want to make a drop-in replacement for a pthread_t (where you don't have to call .value()), you'll have to write your own little wrapper class to handle all the implicit conversions. It's pretty straightforward, but also getting off-topic, so I'll just drop some code here and give info in the comments if anybody asks. Here are 3 options depending on how old of a C++ you want to support. They provide implicit conversion to/from pthread_t (can't do pthread_t* though), so code changes should be minimal:
//-----------------------------------------------------------
// This first one is C++20 only:
#include <optional>
struct thread_id {
thread_id () =default;
thread_id (const pthread_t &t) : t_(t) { }
operator pthread_t () const { return value(); }
friend bool operator == (const thread_id &L, const thread_id &R) {
return (!L.valid() && !R.valid()) || (L.valid() && R.valid() && pthread_equal(L.value(), R.value()));
}
friend bool operator == (const pthread_t &L, const thread_id &R) { return thread_id(L) == R; }
bool valid () const { return t_.has_value(); }
void reset () { t_.reset(); }
pthread_t value () const { return t_.value(); } // throws std::bad_optional_access if !valid()
private:
std::optional<pthread_t> t_;
};
//-----------------------------------------------------------
// This works for C++17 and C++20. Adds a few more operator
// overloads that aren't needed any more in C++20:
#include <optional>
struct thread_id {
// construction / conversion
thread_id () =default;
thread_id (const pthread_t &t) : t_(t) { }
operator pthread_t () const { return value(); }
// comparisons
friend bool operator == (const thread_id &L, const thread_id &R) {
return (!L.valid() && !R.valid()) || (L.valid() && R.valid() && pthread_equal(L.value(), R.value()));
}
friend bool operator == (const thread_id &L, const pthread_t &R) {return L==thread_id(R);}
friend bool operator == (const pthread_t &L, const thread_id &R) {return thread_id(L)==R;}
friend bool operator != (const thread_id &L, const thread_id &R) {return !(L==R);}
friend bool operator != (const thread_id &L, const pthread_t &R) {return L!=thread_id(R);}
friend bool operator != (const pthread_t &L, const thread_id &R) {return thread_id(L)!=R;}
// value access
bool valid () const { return t_.has_value(); }
void reset () { t_.reset(); }
pthread_t value () const { return t_.value(); } // throws std::bad_optional_access if !valid()
private:
std::optional<pthread_t> t_;
};
//-----------------------------------------------------------
// This works for C++11, 14, 17, and 20. It replaces
// std::optional with a flag and a custom exception.
struct bad_pthread_access : public std::runtime_error {
bad_pthread_access () : std::runtime_error("value() called, but !valid()") { }
};
struct thread_id {
thread_id () : valid_(false) { }
thread_id (const pthread_t &t) : thr_(t), valid_(true) { }
operator pthread_t () const { return value(); }
friend bool operator == (const thread_id &L, const thread_id &R) {
return (!L.valid() && !R.valid()) || (L.valid() && R.valid() && pthread_equal(L.value(), R.value()));
}
friend bool operator == (const thread_id &L, const pthread_t &R) { return L==thread_id(R); }
friend bool operator == (const pthread_t &L, const thread_id &R) { return thread_id(L)==R; }
friend bool operator != (const thread_id &L, const thread_id &R) { return !(L==R); }
friend bool operator != (const thread_id &L, const pthread_t &R) { return L!=thread_id(R); }
friend bool operator != (const pthread_t &L, const thread_id &R) { return thread_id(L)!=R; }
bool valid () const { return valid_; }
void reset () { valid_ = false; }
pthread_t value () const { // throws bad_pthread_access if !valid()
if (!valid_) throw bad_pthread_access();
return thr_;
}
private:
pthread_t thr_;
bool valid_;
};
//------------------------------------------------------
/* some random notes:
- `std::optional` doesn't let you specify custom comparison
functions, which would be convenient here.
- You can't write `bool operator == (pthread_t, pthread_t)`
overloads, because they'll conflict with default operators
on systems where `pthread_t` is a primitive type.
- You have to write overloads for all the combos of
pthread_t/thread_id in <= C++17, otherwise resolution is
ambiguous with the implicit conversions.
- *Really* sloppy but thorough test: https://godbolt.org/z/GY639ovzd

How call function in lua library with dlsym

I am trying call a lua library runtime, so I made a lua lib in C
static int my_new(lua_State *L) {
printf("test_new");
}
LUALIB_API int luaopen_my(lua_State *L) {
static const luaL_Reg R[] =
{
{ "new", my_new },
{ NULL, NULL }
};
luaL_newmetatable(L,myNAME);
luaL_setfuncs(L,R,0);
lua_pushliteral(L,"version"); /** version */
lua_pushliteral(L,MYVERSION);
lua_settable(L,-3);
lua_pushliteral(L,"__index");
lua_pushvalue(L,-2);
lua_settable(L,-3);
return 1;
}
So I built it as a dynamic library, and I tried call doing it:
void *handle;
lua_CFunction fnc_call;
handle = dlopen("mylib.so", RTLD_LOCAL | RTLD_LAZY);
if (!handle) {
printf("error call lib");
exit(-1);
}
fnc_call = (lua_CFunction) dlsym(handle, "luaopen_my");
if (fnc_call == NULL) {
printf("error call func");
exit(-1);
}
luaL_requiref(L, "my", fnc_call, 1);
lua_pop(L, 1);
But when I call the Lua code that uses that I have a segmentation fault.
test = my.new()
How should I call a lib lua in my program, I know that is possible put my lib in some lua path and lua api call my libs, but I need to call it using dlopen.
Thanks,
I wager that since you are not returning a value from my_new, the function is returning a random value which tells Lua that there is some (random, possibly very high) number of objects returned on the stack. Since this is not true, when Lua clears that stack from return values it removes objects from the stack although none were added, likely removing more objects than there are on the stack, thus corrupting memory.
Add return 0 to my_new.

implement errno analogue using pthread

As $ man errno says, "errno is defined by the ISO C standard to be a modifiable lvalue of type int, and must not be explicitly declared; errno may be a macro. errno is thread-local; setting it in one thread does not affect its value in any other thread".
I'm developing a C library which will work both in POSIX and Windows, so instead of using errno and GetLastError/SetLastError I've decided to stick to my own error type. Every my function returns error code as cg_error object, where cg_error is just a typedef. However, for some functions like custom allocators it is still better to use something like errno, but with my own cg_error type.
AFAIK errno in glibc is implemented this way:
#define errno (*__errno_location ())
I'm trying to implement a similar function using pthreads on Linux and TlsAlloc and friends for Windows. Here is what I have now (yet only POSIX, seems to be a Solaris implementation from article "Thread-Specific Storage pattern" found on the Web):
cg_error * CG_ERRNO_TLS(void)
{
#if CG_FEATURE_POSIX
static int once;
static pthread_key_t key;
static pthread_mutex_t lock;
cg_error * error = NULL;
if (once)
{
pthread_mutex_lock(&lock);
if (once)
{
(void) pthread_key_create(&key, cg_free);
once = 1;
}
pthread_mutex_unlock(&lock);
}
error = pthread_getspecific(key);
if (!error)
{
error = cg_malloc(sizeof(*error));
(void) pthread_setspecific(key, error);
}
return error;
#endif
}
#define cg_errno (*CG_ERRNO_TLS())
However, when I try to set or get cg_errno, its int value is 6344768, which is not what I want. What am I doing wrong? What's the right way to define something like errno? Thanks in advance!
P.S. I know that I could use __thread and __declspec(thread), but such things are compiler-specific (and probably system specific; I've heard that __thread doesn't work e.g. for MacOSX with gcc).
P.P.S. Base value of cg_error is CG_ERROR_NONE, which is always 0.
UPDATE:
#if CG_FEATURE_POSIX
static pthread_key_t cg_errno_key;
static pthread_once_t cg_errno_once = PTHREAD_ONCE_INIT;
static void cg_errno_init(void)
{ (void) pthread_key_create(&cg_errno_key, cg_free); }
cg_error * cg_errno_storage(void)
{
cg_error * error = NULL;
(void) pthread_once(&cg_errno_once, cg_errno_init);
error = pthread_getspecific(cg_errno_key);
if (!error)
{
error = cg_malloc(sizeof(*error));
(void) pthread_setspecific(cg_errno_key, error);
}
return error;
}
#define cg_errno (*cg_errno_storage())
#endif
Your condition on once is wrong. It should be !once.
But using an int for that is not guaranteed to work. There is a special type pthread_once_t with function pthread_once for the task that you are trying to achieve.
Also, lock should have an initializer, PTHREAD_MUTEX_INITIALIZER.
A use of pthread_once_t would look like this:
static pthread_key_t key;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static
void init_error_key_once(void) {
pthread_key_create(&key, cg_free);
}
cg_error * CG_ERRNO_TLS_POSIX(void)
{
cg_error * error = NULL;
pthread_once(&once, init_error_key_once);
...
}

Try catch statements in C

I was thinking today about the try/catch blocks existent in another languages. Googled for a while this but with no result. From what I know, there is not such a thing as try/catch in C. However, is there a way to "simulate" them?
Sure, there is assert and other tricks but nothing like try/catch, that also catch the raised exception. Thank you
C itself doesn't support exceptions but you can simulate them to a degree with setjmp and longjmp calls.
static jmp_buf s_jumpBuffer;
void Example() {
if (setjmp(s_jumpBuffer)) {
// The longjmp was executed and returned control here
printf("Exception happened here\n");
} else {
// Normal code execution starts here
Test();
}
}
void Test() {
// Rough equivalent of `throw`
longjmp(s_jumpBuffer, 42);
}
This website has a nice tutorial on how to simulate exceptions with setjmp and longjmp
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
You use goto in C for similar error handling situations.
That is the closest equivalent of exceptions you can get in C.
Ok, I couldn't resist replying to this. Let me first say I don't think it's a good idea to simulate this in C as it really is a foreign concept to C.
We can use abuse the preprocessor and local stack variables to give use a limited version of C++ try/throw/catch.
Version 1 (local scope throws)
#include <stdbool.h>
#define try bool __HadError=false;
#define catch(x) ExitJmp:if(__HadError)
#define throw(x) {__HadError=true;goto ExitJmp;}
Version 1 is a local throw only (can't leave the function's scope). It does rely on C99's ability to declare variables in code (it should work in C89 if the try is first thing in the function).
This function just makes a local var so it knows if there was an error and uses a goto to jump to the catch block.
For example:
#include <stdio.h>
#include <stdbool.h>
#define try bool __HadError=false;
#define catch(x) ExitJmp:if(__HadError)
#define throw(x) {__HadError=true;goto ExitJmp;}
int main(void)
{
try
{
printf("One\n");
throw();
printf("Two\n");
}
catch(...)
{
printf("Error\n");
}
return 0;
}
This works out to something like:
int main(void)
{
bool HadError=false;
{
printf("One\n");
{
HadError=true;
goto ExitJmp;
}
printf("Two\n");
}
ExitJmp:
if(HadError)
{
printf("Error\n");
}
return 0;
}
Version 2 (scope jumping)
#include <stdbool.h>
#include <setjmp.h>
jmp_buf *g__ActiveBuf;
#define try jmp_buf __LocalJmpBuff;jmp_buf *__OldActiveBuf=g__ActiveBuf;bool __WasThrown=false;g__ActiveBuf=&__LocalJmpBuff;if(setjmp(__LocalJmpBuff)){__WasThrown=true;}else
#define catch(x) g__ActiveBuf=__OldActiveBuf;if(__WasThrown)
#define throw(x) longjmp(*g__ActiveBuf,1);
Version 2 is a lot more complex but basically works the same way. It uses a
long jump out of the current function to the try block. The try block then
uses an if/else to skip the code block to the catch block which check the local
variable to see if it should catch.
The example expanded again:
jmp_buf *g_ActiveBuf;
int main(void)
{
jmp_buf LocalJmpBuff;
jmp_buf *OldActiveBuf=g_ActiveBuf;
bool WasThrown=false;
g_ActiveBuf=&LocalJmpBuff;
if(setjmp(LocalJmpBuff))
{
WasThrown=true;
}
else
{
printf("One\n");
longjmp(*g_ActiveBuf,1);
printf("Two\n");
}
g_ActiveBuf=OldActiveBuf;
if(WasThrown)
{
printf("Error\n");
}
return 0;
}
This uses a global pointer so the longjmp() knows what try was last run.
We are using abusing the stack so child functions can also have a try/catch block.
Using this code has a number of down sides (but is a fun mental exercise):
It will not free allocated memory as there are no deconstructors being called.
You can't have more than 1 try/catch in a scope (no nesting)
You can't actually throw exceptions or other data like in C++
Not thread safe at all
You are setting up other programmers for failure because they will likely not notice the hack and try using them like C++ try/catch blocks.
In C99, you can use setjmp/longjmp for non-local control flow.
Within a single scope, the generic, structured coding pattern for C in the presence of multiple resource allocations and multiple exits uses goto, like in this example. This is similar to how C++ implements destructor calls of automatic objects under the hood, and if you stick to this diligently, it should allow you for a certain degree of cleanness even in complex functions.
While some of the other answers have covered the simple cases using setjmp and longjmp, in a real application there's two concerns that really matter.
Nesting of try/catch blocks. Using a single global variable for your jmp_buf will make these not work.
Threading. A single global variable for you jmp_buf will cause all kinds of pain in this situation.
The solution to these is to maintain a thread-local stack of jmp_buf that get updated as you go. (I think this is what lua uses internally).
So instead of this (from JaredPar's awesome answer)
static jmp_buf s_jumpBuffer;
void Example() {
if (setjmp(s_jumpBuffer)) {
// The longjmp was executed and returned control here
printf("Exception happened\n");
} else {
// Normal code execution starts here
Test();
}
}
void Test() {
// Rough equivalent of `throw`
longjump(s_jumpBuffer, 42);
}
You'd use something like:
#define MAX_EXCEPTION_DEPTH 10;
struct exception_state {
jmp_buf s_jumpBuffer[MAX_EXCEPTION_DEPTH];
int current_depth;
};
int try_point(struct exception_state * state) {
if(current_depth==MAX_EXCEPTION_DEPTH) {
abort();
}
int ok = setjmp(state->jumpBuffer[state->current_depth]);
if(ok) {
state->current_depth++;
} else {
//We've had an exception update the stack.
state->current_depth--;
}
return ok;
}
void throw_exception(struct exception_state * state) {
longjump(state->current_depth-1,1);
}
void catch_point(struct exception_state * state) {
state->current_depth--;
}
void end_try_point(struct exception_state * state) {
state->current_depth--;
}
__thread struct exception_state g_exception_state;
void Example() {
if (try_point(&g_exception_state)) {
catch_point(&g_exception_state);
printf("Exception happened\n");
} else {
// Normal code execution starts here
Test();
end_try_point(&g_exception_state);
}
}
void Test() {
// Rough equivalent of `throw`
throw_exception(g_exception_state);
}
Again a more realistic version of this would include some way to store error information into the exception_state, better handling of MAX_EXCEPTION_DEPTH (maybe using realloc to grow the buffer, or something like that).
DISCLAIMER: The above code was written without any testing whatsoever. It is purely so you get an idea of how to structure things. Different systems and different compilers will need to implement the thread local storage differently. The code probably contains both compile errors and logic errors - so while you're free to use it as you choose, TEST it before using it ;)
This is another way to do error handling in C which is more performant than using setjmp/longjmp. Unfortunately, it will not work with MSVC but if using only GCC/Clang is an option, then you might consider it. Specifically, it uses the "label as value" extension, which allows you to take the address of a label, store it in a value and and jump to it unconditionally. I'll present it using an example:
GameEngine *CreateGameEngine(GameEngineParams const *params)
{
/* Declare an error handler variable. This will hold the address
to jump to if an error occurs to cleanup pending resources.
Initialize it to the err label which simply returns an
error value (NULL in this example). The && operator resolves to
the address of the label err */
void *eh = &&err;
/* Try the allocation */
GameEngine *engine = malloc(sizeof *engine);
if (!engine)
goto *eh; /* this is essentially your "throw" */
/* Now make sure that if we throw from this point on, the memory
gets deallocated. As a convention you could name the label "undo_"
followed by the operation to rollback. */
eh = &&undo_malloc;
/* Now carry on with the initialization. */
engine->window = OpenWindow(...);
if (!engine->window)
goto *eh; /* The neat trick about using approach is that you don't
need to remember what "undo" label to go to in code.
Simply go to *eh. */
eh = &&undo_window_open;
/* etc */
/* Everything went well, just return the device. */
return device;
/* After the return, insert your cleanup code in reverse order. */
undo_window_open: CloseWindow(engine->window);
undo_malloc: free(engine);
err: return NULL;
}
If you so wish, you could refactor common code in defines, effectively implementing your own error-handling system.
/* Put at the beginning of a function that may fail. */
#define declthrows void *_eh = &&err
/* Cleans up resources and returns error result. */
#define throw goto *_eh
/* Sets a new undo checkpoint. */
#define undo(label) _eh = &&undo_##label
/* Throws if [condition] evaluates to false. */
#define check(condition) if (!(condition)) throw
/* Throws if [condition] evaluates to false. Then sets a new undo checkpoint. */
#define checkpoint(label, condition) { check(condition); undo(label); }
Then the example becomes
GameEngine *CreateGameEngine(GameEngineParams const *params)
{
declthrows;
/* Try the allocation */
GameEngine *engine = malloc(sizeof *engine);
checkpoint(malloc, engine);
/* Now carry on with the initialization. */
engine->window = OpenWindow(...);
checkpoint(window_open, engine->window);
/* etc */
/* Everything went well, just return the device. */
return device;
/* After the return, insert your cleanup code in reverse order. */
undo_window_open: CloseWindow(engine->window);
undo_malloc: free(engine);
err: return NULL;
}
A quick google search yields kludgey solutions such as this that use setjmp/longjmp as others have mentioned. Nothing as straightforward and elegant as C++/Java's try/catch. I'm rather partial to Ada's exception handling myself.
Check everything with if statements :)
This can be done with setjmp/longjmp in C. P99 has a quite comfortable toolset for this that also is consistent with the new thread model of C11.
In C, you can "emulate" exceptions along with automatic "object reclamation" through manual use of if + goto for explicit error handling.
I often write C code like the following (boiled down to highlight error handling):
#include <assert.h>
typedef int errcode;
errcode init_or_fail( foo *f, goo *g, poo *p, loo *l )
{
errcode ret = 0;
if ( ( ret = foo_init( f ) ) )
goto FAIL;
if ( ( ret = goo_init( g ) ) )
goto FAIL_F;
if ( ( ret = poo_init( p ) ) )
goto FAIL_G;
if ( ( ret = loo_init( l ) ) )
goto FAIL_P;
assert( 0 == ret );
goto END;
/* error handling and return */
/* Note that we finalize in opposite order of initialization because we are unwinding a *STACK* of initialized objects */
FAIL_P:
poo_fini( p );
FAIL_G:
goo_fini( g );
FAIL_F:
foo_fini( f );
FAIL:
assert( 0 != ret );
END:
return ret;
}
This is completely standard ANSI C, separates the error handling away from your mainline code, allows for (manual) stack unwinding of initialized objects much like C++ does, and it is completely obvious what is happening here. Because you are explicitly testing for failure at each point it does make it easier to insert specific logging or error handling at each place an error can occur.
If you don't mind a little macro magic, then you can make this more concise while doing other things like logging errors with stack traces. For example:
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define TRY( X, LABEL ) do { if ( ( X ) ) { fprintf( stderr, "%s:%d: Statement '%s' failed! %d, %s\n", __FILE__, __LINE__, #X, ret, strerror( ret ) ); goto LABEL; } while ( 0 )
typedef int errcode;
errcode init_or_fail( foo *f, goo *g, poo *p, loo *l )
{
errcode ret = 0;
TRY( ret = foo_init( f ), FAIL );
TRY( ret = goo_init( g ), FAIL_F );
TRY( ret = poo_init( p ), FAIL_G );
TRY( ret = loo_init( l ), FAIL_P );
assert( 0 == ret );
goto END;
/* error handling and return */
FAIL_P:
poo_fini( p );
FAIL_G:
goo_fini( g );
FAIL_F:
foo_fini( f );
FAIL:
assert( 0 != ret );
END:
return ret;
}
Of course, this isn't as elegant as C++ exceptions + destructors. For example, nesting multiple error handling stacks within one function this way isn't very clean. Instead, you'd probably want to break those out into self contained sub functions that similarly handle errors, initialize + finalize explicitly like this.
This also only works within a single function and won't keep jumping up the stack unless higher level callers implement similar explicit error handling logic, whereas a C++ exception will just keep jumping up the stack until it finds an appropriate handler. Nor does it allow you to throw an arbitrary type, but instead only an error code.
Systematically coding this way (i.e. - with a single entry and single exit point) also makes it very easy to insert pre and post ("finally") logic that will execute no matter what. You just put your "finally" logic after the END label.
Warning: the following is not very nice but it does the job.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned int id;
char *name;
char *msg;
} error;
#define _printerr(e, s, ...) fprintf(stderr, "\033[1m\033[37m" "%s:%d: " "\033[1m\033[31m" e ":" "\033[1m\033[37m" " ‘%s_error’ " "\033[0m" s "\n", __FILE__, __LINE__, (*__err)->name, ##__VA_ARGS__)
#define printerr(s, ...) _printerr("error", s, ##__VA_ARGS__)
#define printuncaughterr() _printerr("uncaught error", "%s", (*__err)->msg)
#define _errordef(n, _id) \
error* new_##n##_error_msg(char* msg) { \
error* self = malloc(sizeof(error)); \
self->id = _id; \
self->name = #n; \
self->msg = msg; \
return self; \
} \
error* new_##n##_error() { return new_##n##_error_msg(""); }
#define errordef(n) _errordef(n, __COUNTER__ +1)
#define try(try_block, err, err_name, catch_block) { \
error * err_name = NULL; \
error ** __err = & err_name; \
void __try_fn() try_block \
__try_fn(); \
void __catch_fn() { \
if (err_name == NULL) return; \
unsigned int __##err_name##_id = new_##err##_error()->id; \
if (__##err_name##_id != 0 && __##err_name##_id != err_name->id) \
printuncaughterr(); \
else if (__##err_name##_id != 0 || __##err_name##_id != err_name->id) \
catch_block \
} \
__catch_fn(); \
}
#define throw(e) { *__err = e; return; }
_errordef(any, 0)
Usage:
errordef(my_err1)
errordef(my_err2)
try ({
printf("Helloo\n");
throw(new_my_err1_error_msg("hiiiii!"));
printf("This will not be printed!\n");
}, /*catch*/ any, e, {
printf("My lovely error: %s %s\n", e->name, e->msg);
})
printf("\n");
try ({
printf("Helloo\n");
throw(new_my_err2_error_msg("my msg!"));
printf("This will not be printed!\n");
}, /*catch*/ my_err2, e, {
printerr("%s", e->msg);
})
printf("\n");
try ({
printf("Helloo\n");
throw(new_my_err1_error());
printf("This will not be printed!\n");
}, /*catch*/ my_err2, e, {
printf("Catch %s if you can!\n", e->name);
})
Output:
Helloo
My lovely error: my_err1 hiiiii!
Helloo
/home/naheel/Desktop/aa.c:28: error: ‘my_err2_error’ my msg!
Helloo
/home/naheel/Desktop/aa.c:38: uncaught error: ‘my_err1_error’
Keep on mind that this is using nested functions and __COUNTER__. You'll be on the safe side if you're using gcc.
Redis use goto to simulate try/catch, IMHO it is very clean and elegant:
/* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success. */
int rdbSave(char *filename) {
char tmpfile[256];
FILE *fp;
rio rdb;
int error = 0;
snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());
fp = fopen(tmpfile,"w");
if (!fp) {
redisLog(REDIS_WARNING, "Failed opening .rdb for saving: %s",
strerror(errno));
return REDIS_ERR;
}
rioInitWithFile(&rdb,fp);
if (rdbSaveRio(&rdb,&error) == REDIS_ERR) {
errno = error;
goto werr;
}
/* Make sure data will not remain on the OS's output buffers */
if (fflush(fp) == EOF) goto werr;
if (fsync(fileno(fp)) == -1) goto werr;
if (fclose(fp) == EOF) goto werr;
/* Use RENAME to make sure the DB file is changed atomically only
* if the generate DB file is ok. */
if (rename(tmpfile,filename) == -1) {
redisLog(REDIS_WARNING,"Error moving temp DB file on the final destination: %s", strerror(errno));
unlink(tmpfile);
return REDIS_ERR;
}
redisLog(REDIS_NOTICE,"DB saved on disk");
server.dirty = 0;
server.lastsave = time(NULL);
server.lastbgsave_status = REDIS_OK;
return REDIS_OK;
werr:
fclose(fp);
unlink(tmpfile);
redisLog(REDIS_WARNING,"Write error saving DB on disk: %s", strerror(errno));
return REDIS_ERR;
}
If you're using C with Win32, you can leverage its Structured Exception Handling (SEH) to simulate try/catch.
If you're using C in platforms that don't support setjmp() and longjmp(), have a look at this Exception Handling of pjsip library, it does provide its own implementation
After studying the answers given above, I set up a system that automatically handles nested exceptions well. Here is the code I wrote to test my system:
#include "MyOtherTricks.h"
#include "Exceptions.h"
void Testing_InnerMethod();
void Testing_PossibleExceptionThrower();
void TestExceptionHandling()
{
try
{
Testing_InnerMethod();
Say("The inner method exited without an exception.");
}
catch (Exception)
{
Say("I caught an Exception that the inner method did not catch.");
}
end_try
}
void Testing_InnerMethod()
{
try
{
Say("I am in a try block.");
Testing_PossibleExceptionThrower();
Say("The possible exception thrower didn't throw an exception.");
}
catch (ExceptionSubtype1)
Say("I caught an exception, subtype 1.");
catch (ExceptionSubtype2)
{
Say("I caught an exception, subtype 2.");
Say("I will now rethrow it.");
throw(exception);
}
end_try
}
void Testing_PossibleExceptionThrower()
{
Say("Here is the possible exception thrower.");
throw(new(ExceptionSubtype2)); // To further test exception handling, replace ExceptionSubtype2 in this line with Exception or ExceptionSubtype1, or comment out this line entirely.
Say("No, I won't throw an exception!");
}
The example code relies on two files, Exceptions.h and Exceptions.c. Here is Exceptions.h:
#include <setjmp.h>
extern jmp_buf* Exception_Handler;
#define try do \
{ \
jmp_buf* outerExceptionHandler = Exception_Handler; \
jmp_buf exceptionHandler; \
Exception_Handler = &exceptionHandler; \
Exception exception = (Exception)setjmp(exceptionHandler); \
if (exception != 0) Exception_Handler = outerExceptionHandler; \
if (exception == 0) \
{ \
// The try block goes here. It must not include a return statement or anything else that exits the try...end_try block, because then the outer exception handler will not be restored.
#define catch(exceptionType) Exception_Handler = outerExceptionHandler; \
} \
else if (Object_IsSomeTypeOf(exception, exceptionType)) \
{
// The catch block goes here. It may include a return statement or anything else that exits the try...end_try block. A break statement will exit only the try...end_try block.
#define end_try } \
else \
throw(exception); \
} while(0);
void throw(Exception exception);
And here is Exceptions.c:
#include "MyOtherTricks.h"
#include "Exceptions.h"
jmp_buf* Exception_Handler = 0;
void throw(Exception exception)
{
if (Exception_Handler == 0) FailBecause("Uncaught exception.");
longjmp(*Exception_Handler, (int)exception);
}
Note that this code references some additional methods that I'm not including here (because class inheritance in C is off-topic). To make this code work for you, you'll have to understand this code well enough to replace a few things. In particular, if you want to distinguish between different types of exceptions, you'll need to realize that this code assumes that Object_IsSomeTypeOf(new(ExceptionSubtype1), Exception) returns true and Object_IsSomeTypeOf(new(ExceptionSubtype1), ExceptionSubtype2) returns false, and you'll need to either make your own version of my Object_IsSomeTypeOf macro or replace it with something else.
Perhaps not a major language (unfortunately), but in APL, theres the ⎕EA operation (stand for Execute Alternate).
Usage:
'Y' ⎕EA 'X'
where X and Y are either code snippets supplied as strings or function names.
If X runs into an error, Y (usually error-handling) will be executed instead.

Any good idioms for error handling in straight C programs?

Getting back in to some C work.
Many of my functions look like this:
int err = do_something(arg1, arg2, arg3, &result);
With the intent the result gets populated by the function, and the return value is the status of the call.
The darkside is you get something naive like this:
int err = func1(...);
if (!err) {
err = func2(...);
if (!err) {
err = func3(...);
}
}
return err;
I could macro it I suppose:
#define ERR(x) if (!err) { err = (x) }
int err = 0;
ERR(func1(...));
ERR(func2(...));
ERR(func3(...));
return err;
But that only works if I'm chaining function calls, vs doing other work.
Obviously Java, C#, C++ have exceptions that work very well for these kinds of things.
I'm just curious what other folks do and how other folks do error handling in their C programs nowadays.
If you have resources that need to be released at the end, then sometimes the old trusty goto can be handy!
int
major_func(size_t len)
{
int err;
char *buf;
buf = malloc(len);
if (err = minor_func1(buf))
goto major_func_end;
if (err = minor_func2(buf))
goto major_func_end;
if (err = minor_func3(buf))
goto major_func_end;
major_func_end:
free(buf);
return err;
}
Two typical patterns:
int major_func()
{
int err = 0;
if (err = minor_func1()) return err;
if (err = minor_func2()) return err;
if (err = minor_func3()) return err;
return 0;
}
int other_idea()
{
int err = minor_func1();
if (!err)
err = minor_func2();
if (!err)
err = minor_func3();
return err;
}
void main_func()
{
int err = major_func();
if (err)
{
show_err();
return;
}
happy_happy_joy_joy();
err = other_idea();
if (err)
{
show_err();
return;
}
happy_happy_joy_joy();
}
What are you doing in the else statements? If nothing, try this:
int err = func1(...);
if (err) {
return err;
}
err = func2(...);
if (err) {
return err;
}
err = func3(...);
return err;
This way you're short-circuiting the entire function, not even bothering with the following function calls.
EDIT
Going back and reading again, I realize that it doesn't matter what you do in your else statements. That sort of code can easily go immediately after the if blocks.
If error codes are boolean, then try the simpler code below:
return func1() && func2() && func3()
One approach which has been taken by OpenGL is to not return errors from functions at all but rather present an error state which can be examined after the function call. One nice thing about this approach is that when you have a function which you actually want to return something other than an error code, you can handle errors in the same way. Another thing which is nice about this is that if a user wants to call a number of functions and only succeed if all of them were successful, you can check for errors after the x amount of calls.
/* call a number of functions which may error.. */
glMatrixMode(GL_MODELVIEW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
/* ...check for errors */
if ((error = glGetError()) != GL_NO_ERROR) {
if (error == GL_INVALID_VALUE)
printf("error: invalid value creating view");
else if (error == GL_INVALID_OPERATION)
printf("error: invalid operation creating view");
else if (error == GL_OUT_OF_MEMORY)
printf("error: out of memory creating view");
}
Others have suggested good ideas. Here're the idioms I've seen
int err;
...
err = foo(...);
if (err)
return err;
...
You could macro this out to something like
#define dERR int err=0
#define CALL err =
#define CHECK do { if (err) return err } while(0)
...
void my_func(void) {
dERR;
...
CALL foo(...);
CHECK;
or, if you're feeling really motivated, fiddle with CALL and CHECK so they can be used like
CALL foo(...) CHECK;
or
CALL( foo(...) );
--
Often, functions which need to do cleanup on exit (e.g. free memory) are written like this:
int do_something_complicated(...) {
...
err = first_thing();
if (err)
goto err_out;
buffer = malloc(...);
if (buffer == NULL)
goto err_out
err = another_complicated(...);
if (err)
goto err_out_free;
...
err_out_free:
free(buffer);
err_out:
return err; /* err might be zero */
}
You could use that pattern, or try to simplify it with macros.
--
Finally, if you're feeling /really/ motivated, you can use setjmp/longjmp.
int main(int argc, char *argv[]) {
jmp_buf on_error;
int err;
if (err = setjmp(on_error)) {
/* error occurred, error code in err */
return 1;
} else {
actual_code(..., on_error);
return 0;
}
}
void actual_code(..., jmp_buf on_error) {
...
if (err)
longjmp(on_error, err);
}
Essentially, a declaration of a new jmp_buf and a setjmp function as setting up a try block. The case where setjmp returns non-zero is your catch, and calling longjmp is your throw. I wrote this with passing the jmp_buf around in case you want nested handlers (e.g. if you need to free stuff before signaling an error); if you don't need that, feel free to declare err and the jmp_buf as globals.
Alternately, you could use macros to simply the argument passing around. I'd suggest the way Perl's implementation does it:
#define pERR jmp_buf _err_handler
#define aERR _err_handler
#define HANDLE_ERRORS do { jmp_buf _err_handler; int err = setjmp(_err_handler);
#define END_HANDLE while(0)
#define TRY if (! err)
#define CATCH else
#define THROW(e) longjmp(_err_handler, e)
void always_fails(pERR, int other_arg) {
THROW(42);
}
void does_some_stuff(pERR) {
normal_call(aERR);
HANDLE_ERRORS
TRY {
always_fails(aERR, 23);
} CATCH {
/* err is 42 */
}
END_HANDLE;
}
int main(int argc, char *argv[]) {
HANDLE_ERRORS
TRY {
does_some_stuff(aERR);
return 0;
} CATCH {
return err;
}
DONE_ERRORS;
}
--
Phew. I'm done. (Crazy examples untested. Some details might be off.)
And now for something completely different...
Another approach is to use a struct to contain your error information, e.g:
struct ErrorInfo
{
int errorCode;
char *errorMessage;
#if DEBUG
char *functionName;
int lineNumber;
#endif
}
The best way to use this is to return your method's results as the return code (e.g. "FALSE for failed", or "a file pointer or NULL if it fails", or "size of the buffer or 0 if it fails", etc) and pass in an ErrorInfo as a parameter that the called function will fill in if something fails.
This gives rich error reporting: if the method fails, you can fill in more than a simple error code (e.g. error message, code line and file of the failure, or whatever). The nice thing about it being a struct is that if you think of something, anything, useful later, you can just add it - for example, in my struct above I've allowed for a debug build to include the location of the error (file/line), but you could add a dump of the whole call stack in there at any time without having to change any of the client code.
You can use a global function to fill in an ErrorInfo so the error return can be managed cleanly, and you can update the struct to provide more info easily:
if (error)
{
Error(pErrorInfo, 123, "It failed");
return(FALSE);
}
...and you can have variants of this function that return FALSE, 0, or NULL, to allow most error returns to be phrased as a single line:
if (error)
return(ErrorNull(pErrorInfo, 123, "It failed"));
This gives you a lot of the advantages of an Exception class in other languages (although the caller still needs to handle the errors - callers have to check for error codes and may have to return early, but they can do nothing or next-to-nothing and allow the error to propagate back up a chain of calling methods until one of them wishes to handle it, much like an exception.
In addition, you can go further, to create a chain of error reports (like "InnerException"s):
struct ErrorInfo
{
int errorCode;
char *errorMessage;
...
ErrorInfo *pInnerError; // Pointer to previous error that may have led to this one
}
Then, if you "catch" an error from a function that you call, you can create a new, higher-level error description, and return a chain of these errors. e.g. "Mouse speed will revert to the default value" (because) "Preference block 'MousePrefs' could not be located" (because) "XML reader failed" (because) "File not found".
i.e.
FILE *OpenFile(char *filename, ErrorInfo *pErrorInfo)
{
FILE *fp = fopen(filename, "rb");
if (fp == NULL)
return(ChainedErrorNull(pErrorInfo, "Couldn't open file"));
return(fp);
}
XmlElement *ReadPreferenceXml(ErrorInfo *pErrorInfo)
{
if (OpenFile("prefs.xml", pErrorInfo) == NULL)
return(ChainedErrorNull(pErrorInfo, "Couldn't read pref"));
...
}
char *ReadPreference(char *prefName, ErrorInfo *pErrorInfo)
{
XmlElement *pXml = ReadPreferenceXml(pErrorInfo);
if (pXml == NULL)
return(ChainedErrorNull(pErrorInfo, "Couldn't read pref"));
...
}
You should check out what DirectX has done with the HRESULT - it's basically this. There's a reason that the exception came into being. Alternatively, if you run on Win32, they have SEH which runs in C programs.
You can get really silly and do continuations:
void step_1(int a, int b, int c, void (*step_2)(int), void (*err)(void *) ) {
if (!c) {
err("c was 0");
} else {
int r = a + b/c;
step_2(r);
}
}
This probably isn't actually what you want to do, but it is how many functional programming languages are used, and even more often how they model their code for optimization.
Something I've recently seen is this idom:
int err;
do
{
err = func1 (...);
if (!err) break;
err = func2 (...);
if (!err) break;
err = func3 (...);
if (!err) break;
/* add more calls here */
} while (0);
if (err)
{
/* handle the error here */
return E_ERROR; /* or something else */
}
else
{
return E_SUCCESS;
}
Pro arguments:
It avoids the goto (abuses the while(0) / break combination for that). Why would you want to do this? It keeps the cyclomatic complexity down and will still pass most static code analyzer checks (MISRA anyone?). For projects that get tested against cyclomatic complexity this is a god sent because it keeps all the initialization stuff together.
Contra arguments:
The meaning of the do/while loop construct is not obvious because a loop-construct is used as a cheap goto replacement, and this can only be seen at the loop tail. I'm sure for the first time this construct will cause lots of "WTF"-moments.
At least a comment is necessary to explain why the code is written the way it is required.
Here's a quite informative article & test file by IBM Unix article series:
Errors: errno in UNIX programs
Working with the standard error mechanism
https://www.ibm.com/developerworks/aix/library/au-errnovariable/
Another good example of how to implement exit codes is the source code of curl (man 1 curl).
Provided you are working with a specific context, I think the following pattern is very nice. The basic idea is that operations on an error-set state are no-ops, so error checking can be postponed to when it is convenient!
A concrete example: A deserialization context. Decoding of any element can fail, but the function may continue without error checking because all the decode_* functions are no-ops when the serialization record is in an error state. It's a matter of convenience or opportunity or optimization to insert decode_has_error. In the example below, there is no error check, the caller will take care of that.
void list_decode(struct serialization_record *rec,
struct list *list,
void *(*child_decode)(struct serialization_record *)) {
uint32_t length;
decode_begin(rec, TAG);
decode_uint32(rec, &length);
for (uint32_t i = 0; i < length; i++) {
list_append(list, child_decode(rec));
}
decode_end(rec, TAG);
}

Resources