5

I'm working with an embedded system where the exit() call doesn't seem to exist.

I have a function that calls malloc and rather than let the program crash when it fails I'd rather exit a bit more gracefully.

My initial idea was to use goto however the labels seem to have a very limited scope (I'm not sure, I've never used them before "NEVER USE GOTO!!1!!").

I was wondering if it is possible to goto a section of another function or if there are any other creative ways of exiting a C program from an arbitrary function.

void main() {
  //stuff
  a();

  exit:
     return;
}

void a() {
   //stuff

   //if malloc failed
   goto exit;
}

Thanks for any help.

user1872099
  • 95
  • 2
  • 5
  • See if `_exit()` works, or `_Exit()`. – Kerrek SB Dec 03 '12 at 09:23
  • Doesn't a return value work? Say return -1 for malloc error from the function.. – Krishnabhadra Dec 03 '12 at 09:25
  • using goto is not a good option – knightrider Dec 03 '12 at 09:25
  • @knightrider normally YES.. but this is [one case where goto can be used](http://stackoverflow.com/questions/788903/valid-use-of-goto-for-error-management-in-c) – Krishnabhadra Dec 03 '12 at 09:26
  • Maybe you can just "return;" from a() anywhere you want to exit. – Vandhunden Dec 03 '12 at 09:28
  • 1
    It doesn't make sense to exit() from a freestanding program, that's probably why you don't have it. Embedded programs are supposed to handle errors gracefully, to enter a safe program mode. Embedded programs can't just run away crying, à la PC. – Lundin Dec 03 '12 at 10:44
  • 1
    And if what Lundin says applies to you, then returning from `main` isn't legitimate either. It's just another way for your program to abandon its responsibility for what happens next. Conversely if it makes sense on your system to return from `main` then in principle it should make about as much sense to `exit` from elsewhere in the program *except* that `exit` takes a status code as parameter. Your `void main()` signature suggests that the system doesn't expect a status code. – Steve Jessop Dec 03 '12 at 11:02
  • just create your own exit function and link it in. – old_timer Dec 03 '12 at 14:34

4 Answers4

9

Options:

  • since your system is non-standard (or perhaps is standard but non-hosted), check its documentation for how to exit.
  • try abort() (warning: this will not call atexit handlers).
  • check whether your system allows you to send a signal to yourself that will kill yourself.
  • return a value from a() indicating error, and propagate that via error returns all the way back to main.
  • check whether your system has setjmp/longjmp. These are difficult to use correctly but they do provide what you asked for: the ability to transfer execution from anywhere in your program (not necessarily including a signal/interrupt handler, but then you probably wouldn't be calling malloc in either of those anyway) to a specific point in your main function.
  • if your embedded system is such that your program is the only code that runs on it, then instead of exiting you could call some code that goes into an error state: perhaps an infinite loop, that perhaps flashes an LED or otherwise indicates that badness has happened. Maybe you can provoke a reboot.
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
3

Why dont you use return values

if malloc failed
  return 1;
else 
  return 0;


...........

if(!a())
   return;
knightrider
  • 2,063
  • 1
  • 16
  • 29
2

goto cannot possibly jump to another function.

Normally, you are advised please don't use goto! In this case what you are asking is not possible.

How to deal with this? There are few solutions.

  • Check return code or value of problematic functions and act accordingly.

  • Use setjmp/longjmp. This advice should be considered even more evil than using goto itself, but it does support jumping from one function to another.

mvp
  • 111,019
  • 13
  • 122
  • 148
2

Embedded systems rarely have any variation of exit(), as that function doesn't necessarily make any sense in the given context. Where does the controller of an elevator or a toaster exit to?

In multitasking embedded systems there could be a system call to exit or terminate a process, leaving only an idle process alive that does simply a busy loop: while (1); or in some cases call a privileged instruction to go to power saving mode: while (1) { asm("halt") };

In embedded systems one possible method to "recover" from error is to asm("trap #0"); or any equivalent of calling an interrupt vector, that implements graceful system shutdown with dumping core to flash drive or outputting an error code to UART.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57