EmbeddedRelated.com
Blogs
The 2026 Embedded Online Conference

Your Unit Tests Won't Find the Wolves: Why Embedded Developers Should Be Fuzzing

Ryan TorvikApril 18, 2026

There's only one thing I hate more than testing: someone else telling me they found a bug in my stuff. And when that happens, my instinct is to hide, ignore it, maybe pretend it's a feature. But here's the uncomfortable truth: 137% of the bugs in production are found by other people. (Okay, I made that number up. But it feels right, doesn't it?)

If you're doing testing today, you're probably doing unit tests, functional tests, integration tests. You're thinking about happy paths: well-formatted packets, correct checksums, inputs arriving in the right order. And that's good. That's not nothing.

But then real users show up. They don't read manuals. They don't watch training videos. They just mash buttons and send garbage data and generally do things you never thought to test for. And if you're lucky, the magic blue smoke stays inside the enclosure.

This article is available in PDF format for easy printing

The Forest and the Wolves

Think of your firmware as a forest. Data is trying to get through that forest, following paths you've built and tested. You checked those paths. No wolves. Ship it.

Then a real user enters the forest and immediately gets eaten.

The problem is that you can't possibly test all the paths data can take through your system. There are billions of combinations. Did you test 128? What about 129? What about 127 followed by a null byte followed by your grandmother's phone number? No. You didn't. Nobody did.

So instead of trying to test every path by hand, you send in a robot. The robot wanders through the forest randomly, and it finds the wolves you didn't even think to look for.

That's fuzzing.

Randomized testing: keep the trees, wipe out the wolves

What Fuzzing Actually Is

Fuzzing is conceptually simple. You take your code that accepts some kind of input (a serial protocol, a network packet, a sensor reading, a file) and you throw randomized data at it. Lots of it. Millions of test cases. Then you watch what happens.

A fuzzer has four basic components: a mutator that creates or modifies inputs, instrumentation built into your code so you can see what's actually executing, an observer that tracks code coverage and crashes during runtime, and a runner that handles the jobs.

Anatomy of a fuzzer: mutator, instrumentor, observer, runner

The cycle is: generate an input, run it, see what happens, repeat. If a new input hits a code path that hasn't been exercised before, that's interesting, so the fuzzer saves it and mutates it further. If it causes a crash, even more interesting.

Coverage-based fuzzers like LibFuzzer (which is built right into Clang) are especially clever about this. They don't just spray random bytes. They look at your if statements and learn which byte values might get them deeper into your code. They can even stumble through CRC checks given enough iterations.

This Isn't Just for Security Researchers

Fuzzing has historically been an offensive cybersecurity tool. Companies like Google, Microsoft, Apple, and Meta fuzz their software heavily. It's one of the reasons your phone is as reliable as it is. DARPA has funded fuzzing research. Zephyr RTOS has fuzzing capabilities built in.

But here's the thing: fuzzing isn't just for finding exploitable vulnerabilities. For embedded developers, it's about robustness. Your device is going to sit in the field for months or years, parsing packet after packet after packet. Are you going to write individual unit tests for every possible malformed input? For every weird byte sequence that could arrive over UART? For two years of continuous random data?

No. But a fuzzer will happily do that for you over a weekend.

What This Looks Like in Practice

The setup is less painful than you might think. If you're using Clang, you write a test function that looks a lot like a unit test. Instead of hardcoding the input, you accept a buffer of random bytes and a size from the fuzzer. You feed those bytes to your parser or protocol handler. Compile with -fsanitize=fuzzer, and you've got an executable that will generate inputs, run them, and report crashes.

For embedded specifically, you have a few options. Software-in-the-loop testing (abstract away the hardware, fuzz on your desktop) is the most practical. You can also do hardware-in-the-loop or emulator-in-the-loop fuzzing, though you'll lose some of the coverage-guided benefits.

The key insight for embedded developers: anything that takes an input can and should be fuzzed. Inputs from above (user interfaces, network traffic) and inputs from below (board support packages, peripheral responses). I had a colleague who was focused on fuzzing a communication protocol from above, and it turned out the actual bug was in the board support package throwing an undocumented exception from below.

Going Deeper

In my presentation at the Embedded Online Conference 2026, I walk through the full implementation: building fuzz tests with LibFuzzer and CMake, fuzzing a real serial messaging protocol with state machines and checksums, analyzing crash reports, debugging the failures, and handling crash deduplication. I also show how to structure your fuzz tests to be smarter than pure random noise by crafting valid packets with randomized fields, so you can get past the framing and checksum checks and actually fuzz the interesting parts of your protocol.

If you've ever shipped a device and then spent weeks chasing down weird field failures caused by inputs you never thought to test, fuzzing is worth your time. Check out the session and stop finding your bugs in production.


The 2026 Embedded Online Conference

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: