undefined reference to _exit” Error in ARM Toolchain (Easy Guide)

When compiling C code for embedded systems using the ARM GCC toolchain, you might encounter the following error:

undefined reference to `_exit`

This typically happens during the linking stage and leaves many developers scratching their heads—especially if they’re new to embedded development or cross-compilation.

This post explains:


❓ What Does the _exit Function Do?

_exit() is a low-level system call expected by the C runtime (newlib, libc, etc.) when a program terminates. In embedded systems, where there’s often no operating system, this function is expected to be defined manually or stubbed out.


🧱 Sample Error Scenario

You’re compiling a simple main.c using arm-none-eabi-gcc:

int main() {
    return 0;
}

And you compile with:

arm-none-eabi-gcc -o main.elf main.c

Error:

/usr/lib/gcc/arm-none-eabi/…/libc.a(lib_a-exit.o): in function `exit':
undefined reference to `_exit'

✅ Solution 1: Provide a Dummy _exit Implementation

Add this stub function to your code:

void _exit(int status) {
    while (1); // infinite loop or reset
}

You can place this in your startup.c, syscalls.c, or a new file called stub.c.

This tells the linker: “I don’t care what _exit does—just loop forever.”


✅ Solution 2: Link with Minimal Runtime Flags

Use the --specs=nosys.specs flag during linking:

arm-none-eabi-gcc -o main.elf main.c --specs=nosys.specs

This tells the toolchain:

“I’m not using an OS. Don’t expect system-level implementations like _exit, _kill, etc.”

Perfect for bare-metal development.


✅ Solution 3: Use --specs=rdimon.specs (for Semihosting)

If you’re using semihosting (for I/O to the host PC):

arm-none-eabi-gcc -o main.elf main.c --specs=rdimon.specs -lrdimon

But semihosting is only valid when:

  • You have a debugger attached
  • You want to printf to console

⚠️ Common Mistakes to Avoid

MistakeFix
Using printf() with no systemStub write() or use nosys.specs
Not including libc properlyAlways link with newlib or minimal libc
Missing startup codeEnsure you have crt0.o or equivalent startup

The _exit function error is a standard pitfall in bare-metal embedded C development. The fix is simple once you know what’s going on—it’s all about telling the compiler how to cleanly terminate a program in a world without an operating system.

Have you faced this error in your ARM or embedded toolchain setup?
Drop a comment with your toolchain version or share other linker issues you’d like help with! 🔧👇

Leave a Comment