Back in 2012, I got a rather unusual task.
I had to build a small application for a specialized fingerprint device from a company I remember as AFIS-Cogent.
I may be remembering the company or model incorrectly — it has been more than ten years. 😄
But I still remember the device.
It was thick.
It was heavy.
It had a fingerprint reader, a touchscreen, and a little stylus that you used to poke the screen.
Yes, poke.
Not swipe.
Not pinch-to-zoom.
Definitely not the smooth touchscreen experience we have today.
I would guess the device weighed around 1 kg.
Unfortunately, back then I was still using a feature phone, so I didn't take a photo.
I've tried searching for the device again recently, but I couldn't find one that looked like the machine I remember.
Maybe it's just too old now.
Or maybe my memory has become a little less reliable after ten years. 😄
The interesting part: it ran Windows CE 5.0
The device was running Windows CE 5.0.
If I remember correctly, it had around 128 MB of RAM.
There was also a cable for transferring data between the device and a computer.
The device supported C++ and had a graphical interface, so our team decided to use MFC.
At the time, that seemed like a reasonable choice.
We weren't trying to build anything fancy.
The main job of the application was roughly:
Fingerprint
↓
Fingerprint Reader
↓
Manufacturer SDK
↓
Compare with local fingerprints
↓
Result
The device already had a set of fingerprints loaded locally.
When someone put their finger on the reader, we used the manufacturer's library to process the fingerprint and perform the matching.
The manufacturer provided DLLs and documentation describing the functions we needed to call.
And the documentation was... let's say...
not short. 😄
So I spent quite a lot of time reading the documentation to figure out which function did what, what data it expected, and what the result actually meant.
If the fingerprint couldn't be matched locally, the application would call a server-side service and send the required data to the server for recognition.
So far, so good.
Until the application started disappearing.
Click a button → application gone
This was the part I remember most clearly.
Sometimes I clicked a button and...
the application just disappeared.
No nice exception message.
No modern debugger telling me:
"Hey buddy, this line is probably your problem."
Nothing.
It was there.
I clicked the button.
And then it wasn't.
😂
At first, I had no idea what was happening.
So I started debugging in the most sophisticated way available to me at the time.
I wrote messages to a text file.
Something like:
step 1
step 2
step 3
step 4
step 5
Then I ran the application.
If the file contained:
step 1
step 2
step 3
but never reached step 4, I knew the problem was somewhere between those two points.
Very scientific.
Very advanced.
Very 2012. 😄
But writing to a file for every step was getting annoying.
So I changed my approach.
I started using alerts.
alert("step 1");
alert("step 2");
alert("step 3");
Run the application.
Click the button.
See step 1.
See step 2.
See step 3.
And then...
Nothing.
Okay.
At least now I knew where to start digging.
Eventually, I found the real problem
The problem turned out to be related to memory/resource management.
There were places where I had forgotten to release allocated resources properly.
On a modern development machine, a small mistake like that might take a while to become visible.
On a small embedded device with very limited resources, it was a completely different story.
You didn't have gigabytes of RAM sitting there waiting for you.
You had a very limited budget.
And if your application kept holding resources it no longer needed, eventually the system had enough.
Or rather, it didn't have enough.
😄
That experience changed the way I thought about memory.
Before that, memory was something I knew I had to manage because C++ said so.
After working on that device, memory became something I could actually feel.
You made a mistake.
You ran the application.
It worked.
You ran it again.
Maybe it still worked.
You did a little more.
And eventually:
Bye.
Your application was gone.
Debugging without fancy tools
Looking back, the interesting thing isn't really the bug.
It's how I had to find it.
Today, if an application crashes, we have an incredible collection of tools:
debuggers
stack traces
profilers
memory analyzers
sanitizers
crash reporting
logs
remote debugging
and, of course, AI assistants
Back then, I didn't have most of those things available in the environment I was working with.
So I had to reduce the problem manually.
Does step 1 work?
↓
Does step 2 work?
↓
Does step 3 work?
↓
Where does it stop?
↓
What resource is being used there?
↓
Who allocated it?
↓
Who releases it?
It was slow.
But it worked.
And after doing this several times, something interesting happened.
I became faster.
Not because the device became easier.
I simply started recognizing the patterns.
The lesson I still remember
That little Windows CE project wasn't a huge system.
It wasn't a revolutionary piece of software.
It was just a small application running on a specialized fingerprint device.
But it taught me two things that stayed with me.
The first one is:
Resources are not infinite.
Sometimes you work on a machine with 64 GB of RAM and start thinking memory is basically free.
It isn't.
It's just somebody else's problem until you move to a device where it isn't. 😄
The second lesson is more important:
A difficult problem doesn't necessarily need a complicated solution.
When I couldn't figure out why the application was disappearing, I didn't have a magical debugging tool.
So I made one.
Not a real one.
Just:
step 1
step 2
step 3
...
Then I kept narrowing the problem until I found it.
After a few rounds, the whole thing became much less scary.
That's probably one of the most useful things I've learned from working in software.
You don't always need to know the answer before you start.
Sometimes you just need to find the next thing you can prove.
Then another.
Then another.
Eventually, the problem gets smaller.
And when the problem is small enough, you can solve it.
One more thing
English isn't my strongest language.
I've been working in software for many years, and I've probably accumulated quite a few strange production cases like this one.
But because I'm not very good at English, I haven't shared much of that experience with the wider developer community.
I'm using my AI assistant to help translate and express what I actually want to say in English.
The experience, debugging, and technical conclusions are mine.
AI just helps me communicate them.
Maybe my English isn't perfect, but I figured it was better to start sharing these stories than to keep them in my head. 🙂
And if anyone actually remembers those old fingerprint devices running Windows CE...
I'd love to hear from you.
Top comments (0)