30 May 2021
The weirdest bug I've ever encountered
I am responsible for the reliability of the firmware updates on our devices and this work never gets boring. The thing about firmware updates is that by definition, every bug is caused by the updater because before installing the affected version, the bug was not present. You could say that updates are the cause and the solution of all software problems. So, a lot of update bug reports that find their way to me have nothing to do with the updater per se, they just manifest themselves immediately, giving the impression that the updater is broken. But I'm getting ahead of myself, so let's start from the beginning.
A new bug comes in: Update failed from version X to version Y, error getting log files from sensor. After that, the user manually rebooted the machine and it worked again.
I connect to the machine and download all the logfiles. In the logs, I see that the update installed successfully. After the reboot which starts the newly installed firmware, there were some minor problems: Some processes took a bit longer to start than expected. Other than that, the log looks clean, no errors that could explain this behaviour.
I try to install the affected Firmware version Y on various devices. The problem does not appear. But as luck has it, a co-worker encountered the problem and had the presence of mind to recognize it and leave the system undisturbed for analysis. Connecting to the system is difficult because it is laggy and slow. The device can barely handle simple commands. Weird. Let's run top.
60 processes; 646 threads;
CPU states: 16.0% user, 35.0% kernel
CPU 0 Idle: 55.4%
CPU 1 Idle: 42.4%
Memory: 0 total, 543M avail, page size 4K
PID TID PRI STATE HH:MM:SS CPU COMMAND
1 12 10 Run 1:51:21 17.72% kernel
1 5 10 Run 2:13:10 17.04% kernel
602168 1 10 Rdy 3:30:01 13.98% ps
229398 1 21 Rcv 0:09:32 0.67% smb-tunnelcreek
778301 1 10 Rply 0:00:00 0.62% top
253978 2 21 NSlp 0:05:43 0.40% devi-tsc2007
1 6 10 Rcv 2:08:09 0.25% kernel
7 2 21 Rcv 0:01:41 0.07% io-pkt-v4-hc
581675 15 10 CdV 0:00:17 0.07% telescope
8200 9 21 Rcv 0:00:35 0.05% io-usb
Min Max Average
CPU 0 idle: 55% 55% 55%
CPU 1 idle: 42% 42% 42%
Mem Avail: 543MB 543MB 543MB
Processes: 60 60 60
Threads: 646 646 646
Okay, we immediately have some clues here. The QNX kernel is doing a lot of stuff and so is ps. We see that the CPU load of the two cores is about 50%. But we know that the system has hyperthreading and only has one physical core, so the real load is actually more like 100%. To me, it looks like ps is saturating the core completely, the kernel load is probably caused by whatever ps is doing.
Who is calling ps? With ps -ef we can see the PPID, the parent process id, to track down who spawned this process. Ironically, we use ps to debug this ps problem. Like this, I find that it was spawned by the shell sh, which in turn was spawned by one of our proprietary processes. Equipped with the knowledge of which process is affected and analysing the logs to find out where this process got stuck, I quickly find the offending line of code. It looks like this: int rc = system( "ps -e | grep Foo" ); where Foo is some program whose presence we need to check. Not the prettiest way to implement it, but it is legacy code that worked for many years. I also see that this code only gets executed on certain old hardwares. This explains why the problem never reproduced on most systems, they have newer hardware. Even on the old hardware, it is exceedingly rare and hard to reproduce. Killing the offending ps process, which loops infinitely otherwise, unblocks the system and restores normal operation.
We now know a lot about this problem, but what is the root cause? The ps program causes 100% CPU load... What is this? We use QNX 6.6 and ps is supplied as a closed source binary. To understand this problem, we need to analyse the ps utility itself. We can already do that at the assembly level. The QNX Momentics IDE has an option "Attach to Remote Process via QConn" with which I can tap right into the running process. We see that it is stuck in a loop that calls devctl() over and over again. The return value of this devctl() is 3 which is ESRCH: No such process. This error comes straight from MsgSendv_r which returned -3. It documents that ESRCH means The server died while the calling thread was SEND-blocked or REPLY-blocked..
Okay, so, ps gets stuck in an infinite loop. Dare I say it: Do we have a ps bug on our hands? The QNX ecosystem is generally quite robust. In the past, it almost always ended up being my own mistake when I suspected problems in QNX and its utilities. But how can the infinite loop seen in live assembly debugging be explained with a user error of ps?
At this point, an intermezzo with some QNX history is in order. A bit more than a decade ago, the QNX source code was available to the public. Back then, QNX had a vibrant open source community. People would experiment with the kernel, write various useful utilities and help each other in forums. QNX even had a fully featured Desktop GUI, ran Firefox and was self-hosting, so you could develop for QNX right on QNX itself with full IDE and compiler support. It was beautiful. Then QNX was bought, source code access was revoked and the community largely withered away. Questions were increasingly asked via private support tickets directly to QNX, locked away from the public. QNX know-how becomes harder and harder to acquire, open source software for modern QNX releases is essentially non-existent and the driver situation is a catastrophe. The QNX kernel is the most beautiful and interesting kernel I have ever had the pleasure of working with, but it lies in the shackles of corporate ownership.
Back to the bug. So there is old QNX source code lying around. Do you think anyone has modified the source code of the ps utility throughout the last 15 years? Me neither! Let's dive right into the old code.
The old ps utility compiles for QNX 6.6 on the first try. Nice! It works just like the closed source binary we have. I install my newly compiled ps, write some software to automatically test reboots in a loop overnight and am able to reproduce the problem with this custom ps binary. Perfect! Now we can use the "Attach to Remote Process via QConn" feature again, but this time we have the source code of our ps. I already read the source code of the old ps before I did all of this, and I already had my suspicions as to which devctl() call was being repeated endlessly in the loop, so it comes as no surprise when the debugger points me to the following line:
if (devctl (fd, DCMD_PROC_TIDSTATUS, &tinfo, sizeof (tinfo), 0) == EOK)
The root cause of the bug is the following. For every process in the /proc directory, ps opens a file descriptor to this process' address space (as) file to read the process information to be displayed. For each process, it loops through all the threads of this process, and the bug is that this loop has insufficient termination criteria (in other words, in some cases, it loops infinitely). The problem occurs when the process whose threads we want to inspect terminates right before ps enters this loop. In that case, the devctl() call fails and as you can see in the following simplified snippet, it will never terminate because the if-clause is never entered.
while (1)
{
if (devctl (fd, DCMD_PROC_TIDSTATUS, &tinfo, sizeof (tinfo), 0) == EOK)
{
//[...]
tcount++;
// stop when we have gone through each thread, or when
// the user only want process info
if ((usingThreads == 0) || (tcount == info.num_threads))
break;
}
tinfo.tid++;
}
I also verify this hypothesis by halting the ps process in the debugger, killing the process whose threads we are about to inspect and resuming ps and it hangs in precisely the same way. This is what it looks like in the QNX Momentics IDE:
After this analysis, I'm quite sure that this 15 years old bug is still alive and well in our closed source binary.
Why did this problem suddenly appear in our firmware? We can only speculate, it must have been changes in the scheduling order or timing at boot time. The bug is a race condition, so it can rear its ugly head whenever it wants. The affected code was old and deployed in production for many years.
How did I fix it? I briefly considered shipping our own ps utility, but I was still unsure about other bugs that might potentially be fixed in the latest closed source binary, those fixes would be lost again if I revert to the old open source version. At the end of the day, I decided to comb through our code base and just eliminate the usage of ps in non-interactive code, there weren't that many instances. Our ps utility remains buggy as it is, but it's pretty much impossible to reproduce this bug in an interactive terminal, and our firmware no longer uses it. Needless to say, this particular update problem never occurred again after that.
Does the ps bug still exist in QNX ecosystems more recent than QNX 6.6? Most likely, yes. If it was open source, I would fix it and send a pull request. Because it's not, they have to deal with the issue themselves. Maybe in a decade, an unfortunate soul runs into this bug again. Let's hope this blog post will save them some trouble.
What do we learn?
- No matter how battle-tested and old the code and how reputable the distributor - the code contains bugs.
- Old bugs can manifest themselves seemingly out of nowhere, caused by subtle changes in timing or memory layout.
- Whenever the file system is involved, there is a significant danger that bugs are caused by race conditions.
- Closed source operating systems and ecosystems are a pain to debug. Even old open source releases help.
- Do not use interactive shell utilities in non-interactive code. Avoid
system()whenever possible. Not only is the performance terrible, it can give rise to bugs like this one. - Make sure your loops terminate. Bounded loop variants that increase or decrease strictly monotonically guarantee loop termination. Don't be too clever with loops!
Post comment
Comments
Good card management can make All Rummy easier to understand. At the beginning of a round, examine all cards and identify obvious combinations. Separate cards that already form sequences from cards that might form sets. Next, consider which cards have limited possibilities. A card sitting alone in the hand may be less useful than a card connected to several possible combinations. Players should also avoid changing their entire plan after every draw. Instead, make decisions based on the complete hand and the current situation. With consistent practice, card management becomes faster and more natural. Learn additional All Rummy concepts at **https://sites.google.com/view/all-rummy-rummy/**.
reply
Rummy has a long association with card-game culture in India. Traditional versions have been played socially for generations, while online platforms have introduced digital ways to experience similar concepts.
Rummy Noble is a term associated with online rummy searches. Readers interested in exploring the subject can visit https://sites.google.com/view/rummy-noblee/
The basic concepts remain familiar: players organize cards into sequences and sets and attempt to complete a valid hand according to the applicable rules.
However, online versions can introduce different formats, interfaces, scoring systems, and account procedures. Therefore, users should always read the specific rules instead of assuming that an online format exactly matches a traditional game.
For anyone interested in digital rummy, learning the fundamentals first is a sensible approach. It allows players to understand the game mechanics and make informed decisions about whether they want to participate.
reply
Sometimes users may experience technical problems while accessing a digital gaming application. Teen Patti Master users can encounter issues such as login errors, slow loading, application crashes, installation problems, or network failures.
The first step is to identify whether the problem is related to the device, internet connection, application, or account. Checking the network connection and restarting the device can resolve some basic problems.
Users should also check available storage and application compatibility. If an application is outdated, users should look for an update through a trusted distribution channel rather than downloading random APK files.
For account-related problems, the official recovery or support process should be used. Users should never give passwords or OTPs to people claiming they can fix an account.
For additional Teen Patti Master information and troubleshooting topics, visit https://sites.google.com/view/teenpattimaster51/.
reply
thanks for the useful article about sharing a weird bug.
reply
This is a helpful resource for readers interested in online video chat and digital communication platforms.
reply
There’s a quiet, reflective quality to this post that makes it worth reading. The way the ideas are presented feels genuine rather than overly structured.
reply
The topic here is presented in a thoughtful and personal way. I like how the post leaves room for readers to consider the subject from their own perspective.
reply
This post has a thoughtful and personal feel to it. It’s interesting to see the subject explored through the writer’s own perspective and experiences. <a href="https://hollywoodpavingfl.com">brick pavers</a>
reply
interesting blog, thank you very much!! <a href="https://www.hoge-hakken.eu">hakken</a>
reply
This is a great write-up. The takeaway about avoiding system() in non-interactive code is something I keep coming back to in my own work too — I lean heavily on open source tooling precisely for situations like this, where being able to read the source saves you from bugs that would otherwise be completely opaque.
reply
Thanks for sharing this weird bug story! I found it interesting that update bugs always seem to come from the updater, even when they're not really its fault. The example about failing to get log files from the sensor was a neat peek into your work.
reply
Rummy Perfect is a rummy-related title that may attract users searching for online card-game options. Rummy remains popular because it combines traditional card-game concepts with strategic decision-making.
Before using any rummy platform, beginners should understand the basic rules. They should learn how sequences and sets are formed, how points are calculated, and how a valid declaration works according to the specific format.
An all rummy app can provide convenient access to different games, but convenience should not replace careful research. Users should check platform information, privacy practices, terms, support details, and applicable laws before participating.
Rummy 51 and other related keywords can refer to different services or formats, so users should not assume that every platform follows identical rules.
Promotional bonuses can sometimes be available, but users should carefully read their conditions and restrictions.
A sensible approach is to learn first, practice responsibly, protect personal information, and set clear limits. No strategy or promotional offer should be treated as a guarantee of winning.
My Links —
https://allrummyap.com/all-rummy-apps/
https://allrummyap.com/all-yono-app/
https://allrummyap.com/all-rummy-apps/
https://allrummyap.com/boss-rummy/
https://allrummyap.com/rummy-334/
https://allrummyap.com/rummy-apple/
https://allrummyap.com/rummy-pride/
https://allrummyap.com/royally-rummy/
https://allrummyap.com/rummy-most/
https://allrummyap.com/rummy-ola/
https://allrummyap.com/teen-patti-joy/
https://allrummyap.com/teen-patti-master/
https://allrummyap.com/rummy-golds/
https://allrummyap.com/rummy-nabob/
https://allrummyap.com/rummy-modern/
https://allrummyap.com/holy-rummy/
https://allrummyap.com/rummy-noble/
https://allrummyap.com/rummy-ares/
https://allrummyap.com/rummy-wealth/
https://allrummyap.com/rummy-glee/
https://allrummyap.com/rummy-east/
https://allrummyap.com/rummy-bloc/
https://allrummyap.com/rummy-grand/
https://allrummyap.com/yono-hot/
https://allrummyap.com/bingo-101/
https://allrummyap.com/spin-101/
https://allrummyap.com/yn-777/
https://allrummyap.com/ind-bingo/
https://allrummyap.com/jaiho-slots/
https://allrummyap.com/joy-rummy/
https://allrummyap.com/rummy-77/
https://allrummyap.com/jaiho-arcade/
https://allrummyap.com/slots-spin/
https://allrummyap.com/diwa-777/
https://allrummyap.com/ok-rummy/
https://allrummyap.com/yes-spin/
https://allrummyap.com/bet-51/
https://allrummyap.com/svip-777/
https://allrummyap.com/rummy-91/
https://allrummyap.com/abc-rummy/
https://allrummyap.com/ind-club/
https://allrummyap.com/spin-winner/
https://allrummyap.com/yono-slots/
https://allrummyap.com/spin-gold/
https://allrummyap.com/hi-rummy/
https://allrummyap.com/spin-crush/
https://allrummyap.com/en-365/
https://allrummyap.com/my-777/
https://allrummyap.com/yono-vip/
https://allrummyap.com/rummy-365/
https://allrummyap.com/bet-213/
https://allrummyap.com/567-slots/
https://allrummyap.com/yono-777/
https://allrummyap.com/mdm-bet/
https://allrummyap.com/ind-slots/
https://allrummyap.com/gogo-rummy/
https://allrummyap.com/yono-rummy/
https://allrummyap.com/rummy-420/
https://allrummyap.com/789-jackpots/
https://allrummyap.com/rummy-loot/
https://allrummyap.com/rummy-tour/
https://allrummyap.com/rummy-star/
https://allrummyap.com/rummy-best/
https://allrummyap.com/rummy-master/
https://allrummyap.com/rummy-yes/
https://allrummyap.com/hello-rummy/
https://allrummyap.com/rummy-vip/
https://allrummyap.com/rummy-perfect/
https://allrummyap.com/rainbow-rummy/
https://allrummyap.com/rummy-mate/
https://allrummyap.com/teen-patti-dhani/
https://allrummyap.com/teen-patti-fun/
https://allrummyap.com/teen-patti-go/
https://allrummyap.com/teen-patti-gold/
https://allrummyap.com/teen-patti-royal/
https://allrummyap.com/teen-patti-cash/
https://allrummyap.com/teen-patti-vip/
https://allrummyap.com/teen-patti-yes/
https://allrummyap.com/ludo-empire/
https://allrummyap.com/ludo-gaint/
https://allrummyap.com/ludo-guru/
https://allrummyap.com/ludo-hind/
https://allrummyap.com/rummy-51-bonus/
https://allrummyap.com/all-teen-patti-app-list/
https://allrummyap.com/rummy-good/
https://allrummyap.com/teen-patti-boss/
https://allrummyap.com/aviator-tt-games/
https://allrummyap.com/teen-patti-bliss/
https://allrummyap.com/teen-patti-play/
reply
http://sites.google.com/view/all-rummy-apps-all-rummy-apk/home
http://sites.google.com/view/all-rummy-apps-all-rummy-apk/all-yono-game
http://sites.google.com/view/all-rummy-apps-all-rummy-apk/rummy-wealth
http://sites.google.com/view/all-rummy-apps-all-rummy-apk/rummy-east
http://sites.google.com/view/all-rummy-apps-all-rummy-apk/rummy-golds
reply
I really enjoyed this peek into firmware update bugs. The idea that every bug is caused by the updater before installing the affected version is a clever way to frame it. It must be a challenging but interesting role.
reply
Good to read the details about the weirdest bug you've ever encountered and it is so motivational that you did it. When I come to know that the people need help and it is bringing amazing results to us. We can try it out when we need the right information.
reply
Een discovloer huren door heel Nederland voor de aller scherpste tarieven en met de beste service.
reply
Really enjoyed this post - the deep dive into the devctl race was fascinating. Your point about closed-source making debugging painful resonates strongly, and it's a good reminder to keep leaning on open codebases whenever possible. Also agree on avoiding system() in non-interactive code; we hit similar traps in our own pipeline work.
reply
This is a great debugging write-up. The point about closed-source ecosystems being hostile to debugging really resonates - we tend to default to open source for the same reason, being able to just read the code makes everything tractable. The lesson about not shelling out to interactive utilities from non-interactive code is one I'll be carrying into my own firmware work.
reply
Love posts like this. The way you traced a 15-year-old race condition in ps all the way back to the old open source tree is genuinely impressive debugging. The lesson about not shelling out to interactive utilities from non-interactive code is one I keep coming back to in my own projects. Thanks for sharing the full investigation.
reply
I have learn a few just right stuff here. Certainly
price bookmarking for revisiting. I surprise how so much effort you put
to make this kind of great informative website.
reply
This is an incredibly fascinating and detailed account of a truly peculiar bug! The way you traced the issue through logs, system behavior, and even diving into assembly-level debugging is impressive. It’s amazing how such a seemingly simple problem—like an infinite loop in `ps`—could stem from such a nuanced edge case involving process termination timing. The historical context about QNX and its transition from open-source to corporate ownership adds a layer of depth to the story, highlighting how changes in software ecosystems can impact debugging and development. Your persistence in compiling the old `ps` source code and reproducing the issue is a testament to thorough debugging skills. This kind of deep dive into system-level behavior is both educational and inspiring for anyone working in firmware or low-level software. Great read!
reply
I really love your website.. Pleasant colors & theme.
Did you build this amazing site yourself?
Please reply back as I'm attempting to create my own personal website and would love to learn where you got this from
or what the theme is named. Kudos!
reply
I am a real person, why is every comment here spam? I guess the captcha isn't good enough.
reply
Today, I went to the beach with my kids. I found a sea shell and gave it to my 4 year old daughter and said "You can hear the ocean if you put this to your ear." She put the shell
to her ear and screamed. There was a hermit crab inside and it pinched her
ear. She never wants to go back! LoL I know this is completely off topic but I had to tell someone!
reply
Woah! I'm really digging the template/theme of this website.
It's simple, yet effective. A lot of times it's difficult
to get that "perfect balance" between usability and appearance.
I must say you've done a amazing job with this.
reply
I am really impressed with your writing skills and also with the layout on your blog.
Is this a paid theme or did you modify it yourself?
Anyway keep up the nice quality writing, it is rare to
see a great blog like this one nowadays.
reply