A Silent Crash: Debugging Slack on Ubuntu
Slack on Ubuntu Linux had developed a nasty habit: it would vanish without warning. No dialog box, no error message—just gone, typically after locking and unlocking the screen. A web search turned up nothing, so it was time to dig in with the usual tracing toolkit.
The initial assumption was that the app was core dumping and Ubuntu's apport was swallowing the evidence. Redirecting core dumps to the file system as root seemed like a logical first step, but no core file appeared, likely due to ulimit restrictions. Rather than diving into startup scripts, tracing tools were the next option.
exitsnoop, an eBPF/bcc tool, was the first to provide a lead. It caught a SIGABRT signal sent to Slack around the time of a crash. The next attempt, killsnoop, came up empty, which was no surprise given its age; it was written in 2015 using kprobes, which are not a stable tracepoint interface. This resulted in a filed issue to update the tool.
A perf trace one-liner confirmed the tgkill(2) syscall was delivering the SIGABRT. Still, the goal was to get a stack trace. The signals.bt bpftrace tool was able to trace the signal:signal_generate tracepoint and confirmed the SIGABRT for Slack, but a follow-up bpftrace one-liner designed to print kernel and user stack traces produced only a broken user stack, showing a single address like 0x7f4a2e2e2f95.
Searching the Logs
With the stack trace path leading to a rabbit hole, the focus shifted to application logs. Checking for Slack's log output with lsof initially pointed to the wrong process. Looking at the grandparent process revealed a trove of logs in ~/config/Slack/logs, but browsing them and searching for "errors" didn't expose a smoking gun.
The `STDERR` Mystery
The next question was where Slack was writing its STDERR. The answer was a common but frustrating one: /dev/null. That wasn't going to stop the investigation. The shellsnoop(8) tool from eBPF/bcc was pressed into service to trace writes to STDERR anyway.
This is where the breakthrough happened. The very last message Slack printed before crashing was an error referencing a .png file and a .so file. This crucial message was nowhere in the application's logs—it was only visible because the trace intercepted the write to /dev/null.
Further inspection revealed the missing file was the .so library, not the .png image. Interestingly, a similar .so file existed with a slightly different path. This suggested a versioning or packaging mismatch.
The Fix and a Final Lead
The workaround was a classic, if hacky, solution: the old directory version of the library appeared to be a stale link from a snap build, so linking the newer library version to the old path resolved the crash. Slack stopped crashing immediately.
For future reference, running opensnoop(8) to trace failed opens would have been a faster path to the same answer. It showed that Slack's last failed open attempt was for the missing .so file, a solid lead in itself. But the definitive clue was the secret STDERR messages, which Slack was diligently sending to /dev/null, rescued from the void by shellsnoop(8).



