Arduino memory types, academic - c++

Dear Stackoverflow Users,
I have an interesting question and I wish to hear your opinions out, also please correct me at any part.
In a normal PC the memory adresses splits into 3 parts, stack, heap, globals, (lets forget peripherials now), so if I go ahead and make a bad recursive function which fills the stack with calls, the OS will send a message of stackoverflow, also if I make an infinite loop with a new keyword in it, it'll fill the heap with junk data, and get something like segfault, but what if I make such mistakes in an arduino project?
try / catch blocks are out of the game, so I tried to make my own realization of error handling in loop(), abusing the stupidity of the preprocessor:
#define THROW(errval) \
ERROR = errval; \
loop()
#define TRY \
if(ERROR == 0)
#define CATCH(err) \
else if(err == ERROR)
#define FINALLY \
if(ERROR != 0)
#define OUT_OF_MEMORY 1
int ERROR = 0;
void random_routine() {
if(/*something goes wrong*/) {
THROW(OUT_OF_MEMORY);
}
}
void start() { Serial.begin(9600); }
void loop() {
TRY {
random_routine();
} CATCH(OUT_OF_MEMORY) {
Serial.println("out of memory");
} FINALLY {
while(true);
}
}
Now you might not see the trick here instantly so this is what you get after the preprocessing:
void random_routine() {
if(/*something goes wrong*/) {
ERROR = 1;
//this call is the body of my exception handling solution
//and the question is about this as well
loop();
}
}
void start() { Serial.begin(9600); }
void loop() {
///TRY-s macro result
if(ERROR == 0) {
random_routine();
///chainable CATCH blocks
} else if(ERROR == 1) {
Serial.println("Out of memory");
}
///FINALLY block
if(ERROR != 0) {
while(true);
}
}
So my question is, what if the memory gets full for some reason, will a function call be able to get executed? Because the THROW macro will always call loop() that way my idea to 'escape' from the current context and get into an infinite loop
Sorry for my bad english

So, if you want to exit a function and get back to where you came from, you should leave the function, not call the original function! Either by returning from the function, or use setjmp and longjmp.
And in all cases, you also need to worry about "how does data get cleaned up". In other words, if you allocate memory, then you need to free it before leaving the function, of you have opened a file, you need to close it, etc.
These sort of things is where the RAII principle comes in very handy, but it assumes you leave the function under the knowledge of the compiler, and not that you just jump back to your main loop without cleaning up. It will sooner or later cause problems.
Note also that the behaviour with stack overflow is UNDEFINED BEHAVIOUR - it MAY crash the program immediately, or it may cause the heap to be overwitten, format your harddrive/SD Card, or it may cause daemons to fly out of your nose. Or anything else you can possibly imagine and then some. It is undefined, you can't rely on it doing anything in particular - just that "you're not supposed to do that".

Related

how to handle code that never executes

I have some code that looks like this and I'm unsure how to handle the part which will never get executed since a part of this code runs in infinite loop while waiting for connections and when I terminate the program, it exits from there only.
main(){
// do some stuff....
while(1) {
int newFD =
accept(sockFD, (struct sockaddr *)&client_addr, &client_addr_size);
if(newFD == -1) {
std::cerr << "Error while Accepting on socket" << std::endl;
continue;
}
if(!fork()) {
close(sockFD); // close child's sockfd - not needed here
// lalala do stuff send message here
close(newFD); // finally close its newFD - message sent, no use
return 0;
}
close(newFD); // close parent's newFD - no use here
}
// now execution never reaches here
close(sockFD); // so how to handle this?
freeaddrinfo(res); // and this?
return 0;
}
You can, and probably should add a exit handler if your code is to be used by other people or you yourself just want it cleaner. In your exit handler you can toggle a flag that makes the while() loop terminate. The following code will work 100% fine for this use case and is reliable and cross platform, but if you want to do more complicated things you should use proper thread safe OS specific functions or something like Boost or C++11
First declare two global variables, make them volatile so the compiler will always force us to read or write its actually memory value. If you we do not declare it volatile then it is possible the compiler can put its value in a register which will make this not work. With volatile set it will read the memory location on every loop and work correctly, even with multiple threads.
volatile bool bRunning=true;
volatile bool bFinished=false;
and instead of your while(1) {} loop, change it to this
while(bRunning)
{
dostuff
}
bFinished=true;
In your exit handler simply set bRunning=false;
void ExitHandler()
{
bRunning=false;
while(bFinished==false) { Sleep(1); }
}
You didn't specify an operating system but it looks like you are Linux based, to set a handler on Linux you need this.
void ExitHandler(int s)
{
bRunning=false;
}
int main()
{
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = ExitHandler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
while(bRunning)
{
dostuff
}
...error_handling...
}
And on Windows when you are a console app its the following.
BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
switch (CEvent)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
bRunning = false;
while (bFinished == false) Sleep(1);
break;
}
return TRUE;
}
int main()
{
SetConsoleCtrlHandler(ConsoleHandler, TRUE);
while(bRunning()
{
dostuff
}
...error_handling...
}
Notice the need to test and wait for bFinished here. If you don't do this on Windows your app may not have enough time to shutdown as the exit handler is called by a separate OS specific thread. On Linux this is not necessary and you need to exit from your handler for your main thread to continue.
Another thing to note is by default Windows only gives you ~5 seconds to shut down before it terminates you. This is unfortunate in many cases and if more time is needed you will need to change the registry setting (bad idea) or implement a service which has better hooks into such things. For your simple case it will be fine.
For these things, the OS will take care of properly releasing the resources on shutdown. However, more generally, you still need to make sure that allocated resources don't pile up during program execution, even if they are reclaimed by the OS automatically, because such a resource leak will still influence behaviour and performance of your program.
Now, concerning the resources at hand, there's no reason not to treat them like all resources in C++. The accepted rule is to bind them to an object that will release them in their destructor, see also the RAII idiom. That way, even if at some later stage someone added a break statement the code would still behave correctly.
BTW: The more serious problem I see here is the lack of proper error handling in general.

std::queue::empty() not working?

I'm going crazy with this piece of code. I have a thread that calls regularly to this method:
void deliverMsgQ() {
if(delMsgQ_mutex.try_lock() == false){
return;
}
while(delMsgQ.empty() == false){
std::vector<unsigned char> v = delMsgQ.front();
delMsgQ.pop();
}
delMsgQ_mutex.unlock();
}
void processInMsgQ() {
if(inMsgQ_mutex.try_lock()){
if(delMsgQ_mutex.try_lock() == false){
inMsgQ_mutex.unlock();
}
}else{
return;
}
while(!inMsgQ.empty()){
std::vector<unsigned char> msg;
inMsgQ.front()->getData(msg);
std::cout << "Adding to del-msg-q: " << msg.size() << std::endl;
delMsgQ.push(msg);
delete inMsgQ.front();
inMsgQ.pop();
}
inMsgQ_mutex.unlock();
delMsgQ_mutex.unlock();
}
I have another thread pushing vector to the queue also periodically. These two threads are the only ones that touch the queue delMsgQ.
My problems comes in the first function posted, for some reason delMsgQ.empty() at some point returns false even though it has no vectors in it, and therefore I end up calling pop twice. This causes the size function to become a huge unrealistic number and then the program goes into segmentation fault. I can fix this if I add an additional check right before calling pop, but I would expect that checking once would be enough since I'm also using mutexes. So the other alternative would be that maybe I'm using mutexes wrong, but as far as I know this is the proper way to use them in this case. So I was hoping that maybe someone smarter could let me know if there is something I'm missing? I hope this code is enough, I can provide with more code if necessary although no other function touch the queue that is failing.
best regards
Your code in processInMsgQ() (spaced out a little better but functionally identical) is problematic:
if (inMsgQ_mutex.try_lock()) {
if (delMsgQ_mutex.try_lock() == false) {
// Point A
inMsgQ_mutex.unlock();
// Point B.
}
} else {
return;
}
// Point C.
In the case where it locks inMsgQ_mutex but fails to lock delMsgQ_mutex (point A), it will free the first and then drop through to point C. This means you will be doing stuff that requires both locks without either lock, and that's unlikely to end well :-)
As a solution, you could put another return at point B but the following code is probably cleaner:
// If either lock fails, return ensuring that neither is locked.
if (! inMsgQ_mutex.try_lock()) {
return;
}
if (! delMsgQ_mutex.try_lock() {
inMsgQ_mutex.unlock();
return;
}
// At this point, you have both locks. Carry on ...
You'll notice I've also changed your some_boolean == false to the more usual ! some_boolean. That's the more accepted way of doing that particular check.

Stop program flow in the middle without using an exception

I need to stop the program flow in the middle, and I am currently using an exception for this. This flow is the legal flow and I want to know if I can do it without using an exception.
This is an example of my code, and I cannot change func_2 and func_1:
#include "stdio.h"
void func_3()
{
printf("i am func_3\n");
throw 20;
printf("i am not supposed to be here\n");
}
void func_2()
{
printf("i am func_2\n");
func_3();
printf("i am not supposed to be here\n");
}
void func_1()
{
printf("i am func_1\n");
func_2();
printf("i am not supposed to be here\n");
}
int main()
{
try
{
func_1();
}
catch (int e)
{
printf("i am supposed to be here\n");
}
catch (...)
{
printf("i am not supposed to be here\n");
}
}
I assume that you want to handle an exceptional case and are looking for an alternative to exceptions. I.e. I hope you don't want to continue with the program "normally" after handling your exceptional case, which is possible but not recommended to implement with exceptions.
Possible but not recommended alternatives to exceptions are:
When you want to stop your whole application, then you can use std::exit(0);. You can implement your "catch"-code in a function which you call instead of your "throw"-statement, and call std::exit(0); at the end of that function (or use another exit code to indicate an "unsuccessful" exit). Or you implement an exit handler and register it using std::atexit(&handle_exit);.
Alternative to std::exit(<something>); is abort(); which throws the POSIX signal "SIGABRT" to indicate abnormal termination (which is the default behavior if your program throws and doesn't catch an exception). Your "catch"-code would then go in a signal handler which you register using the POSIX functions. Note that this requires a POSIX system and is thus not as portable as other solutions.
Another (similar) option is to use the "terminate" mechanism: Call std::terminate(); when you would normally throw your exception. Put your "catch"-code in a "terminate handler" function with signature void(*)(), i.e. no parameters and no return value, let's call the function void handle_terminate(). Install a terminate handler using std::set_terminate(&handle_terminate);. I didn't try that one, however, and it sounds damn ugly.
You could implement an exception-like behavior using assembly instructions, but please do not try this at home, as the behavior of such code is highly implementation defined (if not undefined), and way too ugly to implement.
In short, you can't (well ... you could, by using jumps instead, but then you would have two problems to solve).
The exception solution is the one to use, but do not throw a number (a number - especially a magical number in this case doesn't tell you anything).
Instead, define a struct func_3_interrupted {}; minimalistic structure, whose type name tells you it is an "interruption" of func_3, and catch that instead; The structure should be empty (or close to empty) and it should probably not inherit from the std::exception hierarchy.
Return can be used to return to the caller and stop the function being executed
int GLOBAL_FLAG = 1;
function called_function(){
printf("Inside Function")
if(/*some condition*/)
{
GLOBAL_FLAG = 0;
return;
}
/*Normal function code*/
}
int main(){
{
called_function();
if(GLOBAL_FLAG == 1)/*continue program execution*/
printf("Function had been executed.Back to normal flow")
}
So once the return statement is encountered it goes back to the caller that is main here and continues executing rest of the statements in main function.

Restoring the environment by sigsetjmp and longsetjmp

I'm using the couple sigsetjmp and singlongjmp with SIGALARM for interrupting a system call, which is illustrated in the following code
//data of Alarm_interrupter
void (TClass::*fpt)(const char*); // pointer to member function
TClass* pt2Object; // pointer to object
===================================================
//for timeout processing
static sigjmp_buf jmpbuf;
static void recvfrom_alarm(int) {
siglongjmp(jmpbuf, 1);
}
======================================================
void Alarm_interrupter::start_timeout() {
signal(SIGALRM, recvfrom_alarm);
alarm(timeout);
(*pt2Object.*fpt)("timeouted before sigsetjmp"); //this call works OK
if (sigsetjmp(jmpbuf,1) != 0) {
//at this point, pt2Object is still OK,
//but fpt seems to point to nothign.
(*pt2Object.*fpt)("timeouted after sigsetjmp");
}
return;
}
==============================================================
Before sigsetjmp returnn 1, the call using object and the method pointer: *pt2Object.*fpt("timeouted before sigsetjmp") is OK, but after sigsetjmp return 1, this call failed.
After examining the state of variables, I noticed that the object pointer "pt2Object" is still Ok, but the method pointer "fpt" seems to different.
I think that one possible reasons for this is that sigsetjmp cannot restore the whole earlier environment, which includes the method pointer "fpt".
Could you guys help me fix this problem. Thanks so much!
As Potatoswatter points out, using the alarm to delay the longjmp is too clever to rely upon. You have to call 'sigsetjmp' first. It has to happen before you try to return there.
The only way sigsetjmp or setjmp will work is following this pseudocode.
if (sigsetjmp(...) != 0) {
// Error handling code
}
// code that might call siglongjmp to bail out to Error handling code
You see, it has to be executed once to perform the save of the context. This initializes the jmpbuf. If you call longjmp without having called setjmp earlier in the execution, the behavior cannot be predicted.
Also, longjmp will tend to obliterate any local variables you might try to use.
int var = 3;
var = 2;
if (sigsetjmp(...) != 0) {
// Error handling code
printf("%d", var); // could print 2, 3 or even "potato". Local vars get trashed.
}
// code that might call siglongjmp to bail out to Error handling code
So you really want to do everything interesting after the *setjmp.
int var = 3;
if (sigsetjmp(...) != 0) {
// Error handling code
var = 2;
printf("%d", var); // now you know it's 2
}
// code that might call siglongjmp to bail out to Error handling code
For any hope of it surviving across the *longjmp, it needs to be marked volatile.
volatile int var = 3;
var = 2;
if (sigsetjmp(...) != 0) {
// Error handling code
printf("%d", var); // probably 2
}
// code that might call siglongjmp to bail out to Error handling code
And even this may not be enough. It may need to be something called a sigatomic_t or something similar. But try not to need crazy stuff like that.
int var = 3;
memcpy(var, (int *){2}); //memcpy is pretty reliable (C99ism: immediate pointer))
if (sigsetjmp(...) != 0) {
// Error handling code
printf("%d", var); // probably 2
}
// code that might call siglongjmp to bail out to Error handling code

Use of goto for cleanly exiting a loop

I have a question about use of the goto statement in C++. I understand that this topic is controversial, and am not interested in any sweeping advice or arguments (I usually stray from using goto). Rather, I have a specific situation and want to understand whether my solution, which makes use of the goto statement, is a good one or not. I would not call myself new to C++, but would not classify myself as a professional-level programmer either. The part of the code which has generated my question spins in an infinite loop once started. The general flow of the thread in pseudocode is as follows:
void ControlLoop::main_loop()
{
InitializeAndCheckHardware(pHardware) //pHardware is a pointer given from outside
//The main loop
while (m_bIsRunning)
{
simulated_time += time_increment; //this will probably be += 0.001 seconds
ReadSensorData();
if (data_is_bad) {
m_bIsRunning = false;
goto loop_end;
}
ApplyFilterToData();
ComputeControllerOutput();
SendOutputToHardware();
ProcessPendingEvents();
while ( GetWallClockTime() < simulated_time ) {}
if ( end_condition_is_satisified ) m_bIsRunning = false;
}
loop_end:
DeInitializeHardware(pHardware);
}
The pHardware pointer is passed in from outside the ControlLoop object and has a polymorphic type, so it doesn't make much sense for me to make use of RAII and to create and destruct the hardware interface itself inside main_loop. I suppose I could have pHardware create a temporary object representing a sort of "session" or "use" of the hardware which could be automatically cleaned up at exit of main_loop, but I'm not sure whether that idea would make it clearer to somebody else what my intent is. There will only ever be three ways out of the loop: the first is if bad data is read from the external hardware; the second is if ProcessPendingEvents() indicates a user-initiated abort, which simply causes m_bIsRunning to become false; and the last is if the end-condition is satisfied at the bottom of the loop. I should maybe also note that main_loop could be started and finished multiple times over the life of the ControlLoop object, so it should exit cleanly with m_bIsRunning = false afterwards.
Also, I realize that I could use the break keyword here, but most of these pseudocode function calls inside main_loop are not really encapsulated as functions, simply because they would need to either have many arguments or they would all need access to member variables. Both of these cases would be more confusing, in my opinion, than simply leaving main_loop as a longer function, and because of the length of the big while loop, a statement like goto loop_end seems to read clearer to me.
Now for the question: Would this solution make you uncomfortable if you were to write it in your own code? It does feel a little wrong to me, but then I've never made use of the goto statement before in C++ code -- hence my request for help from experts. Are there any other basic ideas which I am missing that would make this code clearer?
Thanks.
Avoiding the use of goto is a pretty solid thing to do in object oriented development in general.
In your case, why not just use break to exit the loop?
while (true)
{
if (condition_is_met)
{
// cleanup
break;
}
}
As for your question: your use of goto would make me uncomfortable. The only reason that break is less readable is your admittance to not being a strong C++ developer. To any seasoned developer of a C-like language, break will both read better, as well as provide a cleaner solution than goto.
In particular, I simply do not agree that
if (something)
{
goto loop_end;
}
is more readable than
if (something)
{
break;
}
which literally says the same thing with built-in syntax.
With your one, singular condition which causes the loop to break early I would simply use a break. No need for a goto that's what break is for.
However, if any of those function calls can throw an exception or if you end up needing multiple breaks I would prefer an RAII style container, this is the exact sort of thing destructors are for. You always perform the call to DeInitializeHardware, so...
// todo: add error checking if needed
class HardwareWrapper {
public:
HardwareWrapper(Hardware *pH)
: _pHardware(pH) {
InitializeAndCheckHardware(_pHardware);
}
~HardwareWrapper() {
DeInitializeHardware(_pHardware);
}
const Hardware *getHardware() const {
return _pHardware;
}
const Hardware *operator->() const {
return _pHardware;
}
const Hardware& operator*() const {
return *_pHardware;
}
private:
Hardware *_pHardware;
// if you don't want to allow copies...
HardwareWrapper(const HardwareWrapper &other);
HardwareWrapper& operator=(const HardwareWrapper &other);
}
// ...
void ControlLoop::main_loop()
{
HardwareWrapper hw(pHardware);
// code
}
Now, no matter what happens, you will always call DeInitializeHardware when that function returns.
UPDATE
If your main concern is the while loop is too long, then you should aim at make it shorter, C++ is an OO language and OO is for split things to small pieces and component, even in general non-OO language we generally still think we should break a method/loop into small one and make it short easy for read. If a loop has 300 lines in it, no matter break/goto doesn't really save your time there isn't it?
UPDATE
I'm not against goto but I won't use it here as you do, I prefer just use break, generally to a developer that he saw a break there he know it means goto to the end of the while, and with that m_bIsRunning = false he can easily aware of that it's actually exit the loop within seconds. Yes a goto may save the time for seconds to understand it but it may also make people feel nervous about your code.
The thing I can imagine that I'm using a goto would be to exit a two level loop:
while(running)
{
...
while(runnning2)
{
if(bad_data)
{
goto loop_end;
}
}
...
}
loop_end:
Instead of using goto, you should use break; to escape loops.
There are several alternative to goto: break, continue and return depending on the situation.
However, you need to keep in mind that both break and continue are limited in that they only affect the most inner loop. return on the other hand is not affected by this limitation.
In general, if you use a goto to exit a particular scope, then you can refactor using another function and a return statement instead. It is likely that it will make the code easier to read as a bonus:
// Original
void foo() {
DoSetup();
while (...) {
for (;;) {
if () {
goto X;
}
}
}
label X: DoTearDown();
}
// Refactored
void foo_in() {
while (...) {
for (;;) {
if () {
return;
}
}
}
}
void foo() {
DoSetup();
foo_in();
DoTearDown();
}
Note: if your function body cannot fit comfortably on your screen, you are doing it wrong.
Goto is not good practice for exiting from loop when break is an option.
Also, in complex routines, it is good to have only one exit logic (with cleaning up) placed at the end. Goto is sometimes used to jump to the return logic.
Example from QEMU vmdk block driver:
static int vmdk_open(BlockDriverState *bs, int flags)
{
int ret;
BDRVVmdkState *s = bs->opaque;
if (vmdk_open_sparse(bs, bs->file, flags) == 0) {
s->desc_offset = 0x200;
} else {
ret = vmdk_open_desc_file(bs, flags, 0);
if (ret) {
goto fail;
}
}
/* try to open parent images, if exist */
ret = vmdk_parent_open(bs);
if (ret) {
goto fail;
}
s->parent_cid = vmdk_read_cid(bs, 1);
qemu_co_mutex_init(&s->lock);
/* Disable migration when VMDK images are used */
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vmdk", bs->device_name, "live migration");
migrate_add_blocker(s->migration_blocker);
return 0;
fail:
vmdk_free_extents(bs);
return ret;
}
I'm seeing loads of people suggesting break instead of goto. But break is no "better" (or "worse") than goto.
The inquisition against goto effectively started with Dijkstra's "Go To Considered Harmful" paper back in 1968, when spaghetti code was the rule and things like block-structured if and while statements were still considered cutting-edge. ALGOL 60 had them, but it was essentially a research language used by academics (cf. ML today); Fortran, one of the dominant languages at the time, would not get them for another 9 years!
The main points in Dijkstra's paper are:
Humans are good at spatial reasoning, and block-structured programs capitalise on that because program actions that occur near each other in time are described near each other in "space" (program code);
If you avoid goto in all its various forms, then it's possible to know things about the possible states of variables at each lexical position in the program. In particular, at the end of a while loop, you know that that loop's condition must be false. This is useful for debugging. (Dijkstra doesn't quite say this, but you can infer it.)
break, just like goto (and early returns, and exceptions...), reduces (1) and eliminates (2). Of course, using break often lets you avoid writing convoluted logic for the while condition, getting you a net gain in understandability -- and exactly the same applies for goto.