I am using the library Function ConnectToTCPServer. This function times out when the host is not reachable. In that case the application crashes with the following error:
"NON-FATAL RUN-TIME ERROR: "MyClient.c", line 93, col 15, thread id 0x000017F0: Library function error (return value == -11 [0xfffffff5]). Timeout error"
The Errorcode 11 is a Timeout error, so this could happen quite often in my application - however the application crashes - i would like to catch this error rather than having my application crash.
How can i catch this runtime error in Ansi C90?
EDIT:
Here is a Codesnippet of the current use:
ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
with
int HPMClientCb(UINT handle, int xType, int errCode, void *transData){
printf("This was never printed\n");
return errCode;
}
The Callbackfunction is never called. My Server is not running, so ConnectToTCPServer will timeout. I would suspect that the callback is called - but it never is called.
EDIT 2: The Callback function is actually not called, the Returnvalue of ConnectToTCPServer contains the same error information. I think it might be a bug that ConnectToTCPServer throws this error. I just need to catch it and bin it in C90. Any Ideas?
EDIT 3: I tested the Callbackfunction, on the rare occaision that my server is online the callback function is actually called - this does not help though because the callback is not called when an error occurs.
Looking in NI documentation, I see this:
"Library error breakpoints -- You can set an option to break program execution whenever a LabWindows/CVI library function returns an error during run time. "
I would speculate they have a debug option to cause the program to stop on run-time errors, which you need to disable in configuration, in compile time or in run-time.
My first guess would have been configuration value or compilation flag, but this is the only option I found, which is a run-time option:
// If debugging is enabled, this function directs LabWindows/CVI not
// to display a run-time error dialog box when a National Instruments
// library function reports an error.
DisableBreakOnLibraryErrors();
Say if it helped.
Theres no such thing as a general case of "catching" an error (or an 'exception') in standard C. Thats up to your library to decide what to do with it. Likely its logging its state and then simply calling abort(). In Unix, that signals SIGABRT which can be handled and not just exit()ed. Or their library may just be logging and then calling exit().
You could run your application under a utility like strace to see what system calls are being performed and what signals are being asserted.
I'd work with your vendor if you can't make any headway otherwise.
From the documentation, it seems you should get a call to your clientCallbackFunction when an error occurs. If you don't, you should edit your question to clarify that.
I'm not sure I understand you.
I looked at the documentation for the library function ConnectToTCPServer(). It returns an int; 0 means success, negative numbers are the error codes.
EDIT: Here is a Codesnippet of the
current use:
ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
If that's really the current use, you don't seem to be trying to tell whether ConnectToTCPServer() succeeds. To do that, you'd need
int err_code;
...
err_code = ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
and then test err_code.
The documentation for ConnectToTCPServer()implies that your callback function won't be called unless there's a message from a TCP server. No server, no message. In that case,
ConnectToTCPServer() should return a negative number.
You should check the return value of ConnectToTCPServer().
Finding a negative number there, you should do something sensible.
Did I understand the documentation correctly?
Normally, you should be able to simply check the return value. The fact that your application exits implies that something is already catching the error and asserting (or something similar). Without seeing any context (i.e. code demonstrating how you're using this function), it's difficult to be any more precise.
The documentation states that ConnectToTCPServer will return the error code. The callback is only called if the connection is established, disconnected or when there is data ready to be read.
The message you get states that the error is NON-FATAL, hence it shouldn't abort. If you're sure the code doesn't abort later it seems indeed like a bug in the library.
I'm not familiar with CVI, but there might be a (compile-/runtime-) option to abort even on non-fatal errors (for debugging purposes). If you can reproduce this in a minimal example you should report it to NI.
Related
I am currently studying libcurl multi API.
I am curious about what will happen if I skip checking CURLM_CALL_MULTI_PERFORM return code from curl_multi_perform().
According to https://linux.die.net/man/3/curl_multi_perform
If you receive CURLM_CALL_MULTI_PERFORM, this basically means that you should call curl_multi_perform again, before you select() on more actions. You don't have to do it immediately, but the return code means that libcurl may have more data available to return or that there may be more data to send off before it is "satisfied". Do note that curl_multi_perform(3) will return CURLM_CALL_MULTI_PERFORM only when it wants to be called again immediately. When things are fine and there is nothing immediate it wants done, it'll return CURLM_OK and you need to wait for "action" and then call this function again.
Does anyone have any idea? I am using libcurl version 7.65.3 and my driver code is in C language. Thanks!
CURLM_CALL_MULTI_PERFORM is deprecated since curl 7.20 and will never be returned, as documented 10 years ago.
The reason of the deprecation was rare proper use of that feature, there were numerous mistakes and misunderstandings. So since 7.20.0 CURLM_CALL_MULTI_PERFORM is no more existing.
I recommend that you consult the official manual curl_multi_perform instead of 3rd party man pages.
Here is the interesting part of curl_multi_perform():
data = multi->easyp;
while(data) {
CURLMcode result;
SIGPIPE_VARIABLE(pipe_st);
sigpipe_ignore(data, &pipe_st);
result = multi_runsingle(multi, &now, data);
sigpipe_restore(&pipe_st);
if(result)
returncode = result;
data = data->next; /* operate on next handle */
}
As it says there is data which will not be processed (via multi_runsingle()) and what that is depends on what you have in flight.
Is this the correct way to do error handling in OpenSSL?
And what is the difference between SSL_get_error and ERR_get_error?
The docs are quite vague in this regard.
int ssl_shutdown(SSL *ssl_connection)
{
int rv, err;
ERR_clear_error();
rv = SSL_shutdown(ssl_connection);
if (rv == 0)
SSL_shutdown(ssl_connection);
if (rv < 0)
{
err = SSL_get_error(ssl_connection, rv);
if (err == SSL_ERROR_SSL)
fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
fprintf(stderr, "%s\n", SSL_state_string(ssl_connection));
return 1;
}
SSL_free(ssl_connection);
return 0;
}
SSL_get_error:
SSL_get_error() returns a result code (suitable for the C "switch"
statement) for a preceding call to SSL_connect(), SSL_accept(),
SSL_do_handshake(), SSL_read(), SSL_peek(), or SSL_write() on ssl. The
value returned by that TLS/SSL I/O function must be passed to
SSL_get_error() in parameter ret.
ERR_get_error:
ERR_get_error() returns the earliest error code from the thread's
error queue and removes the entry. This function can be called
repeatedly until there are no more error codes to return.
So the latter is for more general use and those shouldn't be used together, because:
The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably.
So you have to read all of the errors using ERR_get_error and handle them (or ignore them by removal as you did in your code sample with ERR_clear_error) and then perform the IO operation. Your approach seems to be correct, although I can't check all aspects of it by myself at the moment.
Refer to this answer and this post for more information.
EDIT: according to this tutorial, BIO_ routines may generate an error and affect error queue:
The third field is the name of the package that generated the error,
such as "BIO routines" or "bignum routines".
And what is the difference between SSL_get_error and ERR_get_error?
There are two logical parts to OpenSSL. First is the SSL library, libssl.a (and libssl.so), and it includes the communication related stuff. Second is the cryptography library, libcrypto.a (and libcrypto.so), and it includes big numbers, configuration, input/output, etc.
libssl.a depends upon libcrypto.a, and its why the link command is ordered as -lssl -lcrypto.
You use SSL_get_error to retrieve most errors from the SSL portion library, and you use ERR_get_error to retrieve errors not in the SSL portion of the library.
Is this the correct way to do error handling in OpenSSL?
The code you showed is closer to "how do you shutdown a SSL socket". Ultimately, the gyrations control two cases. First is a half open connection, when the client shutdowns without sending the close notify message. The second is your program's behavior when sending the close notify message.
Its hard to answer "is it correct" because we don't know the behavior you want. If you don't care if the close notify is sent, then I believe you only need to call SSL_shutdown once, regardless of what the client does.
When writing code I often have checks to see if errors occurred. An example would be:
char *x = malloc( some_bytes );
if( x == NULL ){
fprintf( stderr, "Malloc failed.\n" );
exit(EXIT_FAILURE);
}
I've also used strerror( errno ) in the past.
I've only ever written small desktop appications where it doesn't matter if the program exit()ed in case of an error.
Now, however, I'm writing C code for an embedded system (Arduino) and I don't want the system to just exit in case of an error. I want it to go to a particular state/function where it can power down systems, send error reports and idle safely.
I could simply call an error_handler() function, but I could be deep in the stack and very low on memory, leaving error_handler() inoperable.
Instead, I'd like execution to effectively collapse the stack, free up a bunch of memory and start sorting out powering down and error reporting. There is a serious fire risk if the system doesn't power down safely.
Is there a standard way that safe error handling is implemented in low memory embedded systems?
EDIT 1:
I'll limit my use of malloc() in embedded systems. In this particular case, the errors would occur when reading a file, if the file was not of the correct format.
Maybe you're waiting for the Holy and Sacred setjmp/longjmp, the one who came to save all the memory-hungry stacks of their sins?
#include <setjmp.h>
jmp_buf jumpToMeOnAnError;
void someUpperFunctionOnTheStack() {
if(setjmp(jumpToMeOnAnError) != 0) {
// Error handling code goes here
// Return, abort(), while(1) {}, or whatever here...
}
// Do routinary stuff
}
void someLowerFunctionOnTheStack() {
if(theWorldIsOver)
longjmp(jumpToMeOnAnError, -1);
}
Edit: Prefer not to do malloc()/free()s on embedded systems, for the same reasons you said. It's simply unhandable. Unless you use a lot of return codes/setjmp()s to free the memory all the way up the stack...
If your system has a watchdog, you could use:
char *x = malloc( some_bytes );
assert(x != NULL);
The implementation of assert() could be something like:
#define assert (condition) \
if (!(condition)) while(true)
In case of a failure the watchdog would trigger, the system would make a reset. At restart the system would check the reset reason, if the reset reason was "watchdog reset", the system would goto a safe state.
update
Before entering the while loop, assert cold also output a error message, print the stack trace or save some data in non volatile memory.
Is there a standard way that safe error handling is implemented in low memory embedded systems?
Yes, there is an industry de facto way of handling it. It is all rather simple:
For every module in your program you need to have a result type, such as a custom enum, which describes every possible thing that could go wrong with the functions inside that module.
You document every function properly, stating what codes it will return upon error and what code it will return upon success.
You leave all error handling to the caller.
If the caller is another module, it too passes on the error to its own caller. Possibly renames the error into something more suitable, where applicable.
The error handling mechanism is located in main(), at the bottom of the call stack.
This works well together with classic state machines. A typical main would be:
void main (void)
{
for(;;)
{
serve_watchdog();
result = state_machine();
if(result != good)
{
error_handler(result);
}
}
}
You should not use malloc in bare bone or RTOS microcontroller applications, not so much because of safety reasons, but simple because it doesn't make any sense whatsoever to use it. Apply common sense when programming.
Use setjmp(3) to set a recovery point, and longjmp(3) to jump to it, restoring the stack to what it was at the setjmp point. It wont free malloced memory.
Generally, it is not a good idea to use malloc/free in an embedded program if it can be avoided. For example, a static array may be adequate, or even using alloca() is marginally better.
to minimize stack usage:
write the program so the calls are in parallel rather than function calls sub function that calls sub function that calls sub function.... I.E. top level function calls sub function where sub function promptly returns, with status info. top level function then calls next sub function... etc
The (bad for stack limited) nested method of program architecture:
top level function
second level function
third level function
forth level function
should be avoided in embedded systems
the preferred method of program architecture for embedded systems is:
top level function (the reset event handler)
(variations in the following depending on if 'warm' or 'cold' start)
initialize hardware
initialize peripherals
initialize communication I/O
initialize interrupts
initialize status info
enable interrupts
enter background processing
interrupt handler
re-enable the interrupt
using 'scheduler'
select a foreground function
trigger dispatch for selected foreground function
return from interrupt
background processing
(this can be, and often is implemented as a 'state' machine rather than a loop)
loop:
if status info indicates need to call second level function 1
second level function 1, which updates status info
if status info indicates need to call second level function 2
second level function 2, which updates status info
etc
end loop:
Note that, as much as possible, there is no 'third level function x'
Note that, the foreground functions must complete before they are again scheduled.
Note: there are lots of other details that I have omitted in the above, like
kicking the watchdog,
the other interrupt events,
'critical' code sections and use of mutex(),
considerations between 'soft real-time' and 'hard real-time',
context switching
continuous BIT, commanded BIT, and error handling
etc
For example, if it failed to invoke msgsnd/msgrcv:
How to handle the errno – what is the best way?
What principle is applying to business product?
Shall I have to cover all of them?
What kinds of error must be handled? Do I have to write a signal handler for EINTR or something like this?
Here's my straw-man code:
RetVal = msgrcv(... );
if( RetVal == -1 )
{
switch (errno)
{
case E2BIG:
...
case EAGAIN:
...
case EFAULT:
...
case EIDRM:
...
case EINTR:
...
case EINVAL:
...
case ENOMEM:
...
default:
...
}
This depends on the coding standards you want to apply, and how you might reasonably respond to the failures.
You should always check errors, but you might commonly only handle one or two of them such as EINTR. I would at least try to print some kind of diagnostic last-gasp message before violently exiting in the case of unexpected errors.
The more critical the software, the more carefuly-designed it needs to be, and more comprehensive error handling is part of that.
Since your tags are "C" and "Linux" I assume you're using GCC, in which case have a look at the handy %m in printf.
Obviously this too simple for some cases, but until your program is finished something like this is a good stub to have.
if(RetVal == -1) {
perror("message receive");
exit(1);
}
Typically, one only looks at the exact error if a specific recovery is called for in that case. Until you have some code that you need to make conditional on exactly the type of error, you should simply decide between...
Silently ignore the error
Warn, and then continue
Complain, and then exit
See also...
the nonstandard-but-useful err(3).
setjmp, longjmp, sigsetjmp, et al
It depends on your code and what you can do (similar to exception) and what error you have received. For example EAGAIN is not a strictly an error (it denotes that you tried non-blocking operation and it would block).
If it is a quick program you may do nothing (say - you just playing with API). If it has GUI it might display a message (say "disk is full" or "cannot connect to network") etc.
If the question had an ultimate answer there would be no need for errno - system call could do it as well.
The basic Linux system calls almost universally return -1 on error, and 0 or positive value on success. Also, the errno is set to one of the predefined values. So, checking failure of system calls is pretty easy and should be done consistently. Checking the errno for what type of error occurs should be done for the errors you can handle in your program itself. For other errors, it is best to inform the user that he made an error and notify him with the error. The strerror() in the string.h takes erroro as the parameter and returns a pointer to string describing the error.
#include<string.h>
char* strerror(int errno);
After telling the error, it is on the severity of the error whether to continut running the program or exit the program by
exit(1);
How can I efficiently catch and handle segmentation faults from C in an OSX Carbon application?
Background: I am making an OSX Carbon application. I must call a library function from a third party. Because of threading issues, the function can occasionally crash, usually because it's updating itself from one thread, and it's got some internally stale pointer or handle as I query it from another. The function is a black box to me. I want to be able to call the function but be able to "catch" if it has crashed and supply an alternative return.
In Windows, I can use the simple Visual C and Intel C compiler's __try{} and __except.
/* Working Windows Example */
__try { x=DangerousFunction(y);}
__except(EXCEPTION_EXECUTE_HANDLER) {x=0.0;} /* whups, func crashed! */
I am trying to make the same kind of crash-catcher for OSX. I am using pure C on a very large application. I call the function millions of times per second, so efficiency is very important too. (Impressively, the Windows __try() overhead is immeasurably small!)
Here's what I have experimented with:
1) C++ exceptions. I am not sure if C++ exceptions catch the segfault crashes. And my app is currently C. I could try wrappers and #ifdefs to make it C++ but this is a lot of work for the app, and I don't think C++ exceptions will catch the crash.
2) signal + setjump + longjmp. I thought this would work... it's what it's designed for. But I set up my SEGV error handler [in fact I set it up for every signal!] and it's never called during the crash. I can manually test (and succeed) when calling raise(SEGV). But the crashes don't seem to actually call it. My thoughts are that CFM applications do NOT have access to the full BSD signals, only a subset, and that Mach applications are necessary for the Real Thing.
3) MPSetExceptionHandler. Not well documented. I attempted to set a handler. It compiled and ran, but did not catch the segfault.
Are you sure you're not getting a SIGBUS rather then a SIGSEGV?
The below catches SIGBUS as caused by trying to write at memory location 0:
cristi:tmp diciu$ cat test.c
#include <signal.h>
static void sigac(int sig)
{
printf("sig action here, signal is %d\n", sig);
exit(1);
}
int main()
{
(void)signal(SIGSEGV, sigac);
(void)signal(SIGBUS, sigac);
printf("Raising\n");
strcpy(0, "aaksdjkajskd|");
}
cristi:tmp diciu$ ./a.out
Raising
sig action here, signal is 10