Stepping up your debugging game: unveiling Blackfire’s new debug option to troubleshoot Segfaults

By Thomas di Luccio, on Aug 30, 2023

There’s no sugar-coating it–encountering fatal errors, like a segmentation fault (segfault), can leave any developer feeling lost. They are sporadic, hard to replicate, and even more challenging to troubleshoot. 

We believe that you can’t optimize what you can’t measure. Similarly, you can’t fix what you can’t understand. At Blackfire, we understand these moments of helplessness, we’ve all been there after all.

That’s why we are thrilled to introduce our new debug option: collecting logs on segfault for the PHP probe. We have your back and are committed to improving your developer experience.

One small step for man, one giant leap for the debug-kind

This feature captures logs immediately when a segmentation fault occurs, preserving crucial information before the thread crashes. This small but significant addition is akin to shining a  precious light on what could have been a black box for your code. It is offering you an invaluable tool to start your investigation into what went wrong.

We can now be in a situation in which the root cause of a bug can now leave a note in the logs saying, “Hi’ I’m the problem, it’s me”. Goodbye darkness, segfaults old friend. We knew you were trouble.

This new feature is disabled by default but, for each probe configuration, this debug option could be enabled by adding an environment variable or through the php.ini file. Note this option is currently inactive on Windows and Alpine.

# environment variable
BLACKFIRE_DEBUG_SIGSEGV_HANDLER=1

# php.ini
blackfire.debug.sigsegv_handler = 1

It’s not uncommon for developers to point fingers at third-party tools like us when a segfault arises, leading to an unproductive blame game. But with our latest debug option, you can let the logs talk. The feature aims to provide insights and precise data, eliminate guesswork, and help you get to the root of the problem quicker.

Who can it be now?

A detailed article on our support site guides you through collecting Blackfire logs for both the Probe and the Agent. Any information on segfaults will be collected in the probe logs. Those logs are located at /tmp/blackfire.log by default. Blackfire probe log file can be configured through an environment variable or in the php.ini file:

# environment variable
BLACKFIRE_LOG_FILE=/tmp/blackfire.log

# php.ini
blackfire.log_file = /tmp/blackfire.log

On a side note, be sure to check out this support article to gather as much information as possible when troubleshooting Blackfire’s installations.

Logs all-the-things when needed

If you need extra help, a good practice is to collect level 4 logs (BLACKFIRE_LOG_LEVEL=4) and share the logs for both Blackfire Probe and Agent with our support team. We will be happy to work with you and figure things out.

With this in mind, the BLACKFIRE_DEBUG_SIGSEGV_HANDLER option is your trusty sidekick when wrestling with a perplexing segfault. No need to assume and blame without proof. You can now let the logs talk. 

And it doesn’t stop there–there’s another challenge that many developers grapple with that’s worth discussing. It’s no secret that some scripts, affected by severe memory leaks or consuming excessive resources, can crash under the weight of profiling. 

The divide-and-conquer strategy

Blackfire profiler, while a robust and comprehensive tool, does add a significant overhead. Only the developer triggering the profile is affected. Yet, this extra load might tip the scales for scripts already teetering on the edge. 

For these tricky situations, a tactical approach to profiling can be the key. Don’t be discouraged if attempting a complete profile of your script or request in one go is impossible.

Break it down into more digestible segments, profiling parts of it separately. By applying this divide-and-conquer strategy, you’ll gradually piece together a comprehensive understanding of your script’s behavior.

This approach will help isolate memory leaks or other root causes you were looking for. It can turn what initially seemed like an insurmountable challenge into a manageable task.

Blackfire to the rescue

When a profile is triggered, Blackfire probe collects data as soon as the request is handled or a script is processed. Yet, if it encounters a $probe->enable(); call, it will start again, dropping what has been collected until then.

The probe collects data until the end of the process or until a $probe->disable(); is called. The simple trick can help you identify which part of the script is causing so much trouble. Here’s a snippet of code that you can use to narrow down the scope of your analysis. You will find more information in our documentation.

// Get the probe main instance
$probe = BlackfireProbe::getMainInstance();

// start profiling the code
$probe->enable();

... your code to profile

// stop the profiling
$probe->disable();

Let’s build anything together

Remember, improvements aren’t born in isolation. Join the conversation about our new debug option and other Blackfire features on dev.to, Reddit, Twitter, and Slack. Let’s learn, share, and grow to pursue more reliable, performant, and robust web applications.

Happy performance optimization!

Thomas di Luccio

Thomas is a Developer Relations Engineer at Platform.sh for Blackfire.io. He likes nothing more than understanding the users' needs and helping them find practical and empowering solutions. He’ll support you as a day-to-day user.