[CPP] Handling segmentation faults

171 views
Skip to first unread message

Felipe Dienstmann Musse

unread,
Mar 3, 2016, 3:48:14 PM3/3/16
to Cukes
Hello,

I am trying to understand how Cucumber C++ behaves when the execution of the definition of a step yields a segmentation fault. 

Let's say I have the following feature file:

Feature: Understanding a segmentation fault
 
Scenario: we have a problem here
   
Given We have a segmentation fault
   
Then I think we should not be here

Whose steps are defined as:

#include <boost/test/unit_test.hpp>
#include <cucumber-cpp/defs.hpp>
GIVEN
("^We have a segmentation fault$") {
   
int *pointer = NULL;
   
*pointer = 42;
}
 
THEN
("^I think we should not be here$") {
    BOOST_CHECK
(true); // should not be executed?
}

Since the first step yields a segmentation fault, i thought the second one would not be executed. However:

./steps & cucumber features/seg_fault.feature
Feature: Understanding a segmentation fault

 
Scenario: we have a problem here     # features/seg_fault.feature:2
   
Given We have a segmentation fault # steps.cpp:4
   
Then I think we should not be here # steps.cpp:9

1 scenario (1 passed)
2 steps (2 passed)


I have compiled the steps definitions with -O0 to avoid optimizations which could remove the code yielding the segmentation fault.

Moreover, I tried running the tests with gdb; weirdly:

gdb steps
...
(gdb) handle SIGSEGV nostop (so that gdb does not catch the signal)
Signal        Stop      Print   Pass to program Description
SIGSEGV      
No        Yes     Yes             Segmentation fault
(gdb) run
Starting program: /path/to/steps
[Thread debugging using libthread_db enabled]

(Here I run cucumber in another terminal)

Program received signal SIGSEGV, Segmentation fault.


Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

And cucumber's output:

cucumber features/seg_fault.feature
Feature: Understanding a segmentation fault            
 
Scenario: we have a problem here     # features/seg_fault.feature:2
   
Given We have a segmentation fault # steps.cpp:4                
     
Remote Socket with localhost:3902 closed. (Cucumber::WireSupport::WireException)
      features
/seg_fault.feature:3:in 'Given We have a segmentation fault'            
Broken pipe (Errno::EPIPE)
(cucumber backtrace follows)

I tried taking a look at the code, but I didn't manage to understand how Cucumber C++ handles these cases neither why does running with gdb give a different result.

Could somebody enlighten me about this issue?

Thanks in advance.

Regards,
Felipe Musse

Paolo Ambrosio

unread,
Mar 3, 2016, 4:42:51 PM3/3/16
to cu...@googlegroups.com
Cucumber-Ruby communicates with your C++ steps through the wire
protocol, so when the C++ steps die because of a segmentation fault,
Cucumber-Ruby exits because the communication channel is broken.

The C++ steps create a socket server at startup, Cucumber-Ruby reads
where to reach that server from the .wire file, connects and start
sending JSON messages through the socket to match and run steps (more
details here if you are curious:
https://www.relishapp.com/cucumber/cucumber/docs/wire-protocol).

Felipe Dienstmann Musse

unread,
Mar 4, 2016, 3:43:10 AM3/4/16
to Cukes
Thanks for the answer. I had already read about how both these parts communicate with each other. The issue is that the C++ steps keep running even though we should have had a segmentation fault, as you can see in the first half of my previous message. If I try the same code outside of a step definition:

#include <iostream>
int main() {

   
int *pointer = NULL;
   
*pointer = 42;

   
return 0;
}

Then a segmentation fault is actually produced:

g++ test.cpp -o test -g -O0
./test
Segmentation fault (core dumped)

I am trying to understand why we don't have a segmentation fault when running normally the first C++ step described in my previous message (when running with gdb, we do have it). Do you have an idea as to why it is so?

Paolo Ambrosio

unread,
Mar 6, 2016, 3:22:11 AM3/6/16
to cu...@googlegroups.com
On Fri, Mar 4, 2016 at 8:43 AM, Felipe Dienstmann Musse
I think it might be something in Boost::Test since it does not happen
with GoogleTest steps, and AFAIK we don't explicitly intercept any
signal in Cucumber-CPP.


Paolo

Felipe Dienstmann Musse

unread,
Mar 7, 2016, 7:31:44 AM3/7/16
to Cukes
Indeed, I found it in Boost::Test's Execution Monitor. I managed to disable this behavior with the catch_system_errors parameter.
Thanks for the answers.

Felipe Musse



Paolo
Reply all
Reply to author
Forward
0 new messages