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:
- Why this error occurs
- When it happens
- How to fix it cleanly
❓ 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
Mistake | Fix |
---|---|
Using printf() with no system | Stub write() or use nosys.specs |
Not including libc properly | Always link with newlib or minimal libc |
Missing startup code | Ensure 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! 🔧👇