www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does a switch break cause a segmentation fault

reply adamgoldberg <adamgoldberg airmail.cc> writes:
Hey, I just happened to be writing a program in D an stumbled 
upon a bug, that causes it to terminate after receiving a SEGV 
signal, nothing wierd so far but it looks everything I tried 
shows it is the break statement inside of a switch.
It seems to have a relatively random chance of occuring, and also 
somewhat dependant on the compiler, and build mode used.
I'm short on time so instead of rewriting my SO post I will just 
link it.

Here! 
https://stackoverflow.com/questions/57153617/random-segmentation-fault-in-d-lang-on-switch-break

Hope someone can help!
Jul 22 2019
next sibling parent reply Exil <Exil gmall.com> writes:
On Monday, 22 July 2019 at 22:05:17 UTC, adamgoldberg wrote:
 Hey, I just happened to be writing a program in D an stumbled 
 upon a bug, that causes it to terminate after receiving a SEGV 
 signal, nothing wierd so far but it looks everything I tried 
 shows it is the break statement inside of a switch.
 It seems to have a relatively random chance of occuring, and 
 also somewhat dependant on the compiler, and build mode used.
 I'm short on time so instead of rewriting my SO post I will 
 just link it.

 Here! 
 https://stackoverflow.com/questions/57153617/random-segmentation-fault-in-d-lang-on-switch-break

 Hope someone can help!
Could be the statement in the actual switch(), which is accessing a pointer "codecpar". switch (stream.codecpar.codec_type) ^^^^^ This could be null and you aren't checking for it. I find that D sometimes doesn't have the correct line numbers for debug info, even when not doing an optimized build. So it could really be anything in that function. The root cause could be a lot of things though, some bad codegen or otherwise. Could add a check to make sure though.
Jul 22 2019
parent reply adamgoldberg <adamgoldberg airmail.cc> writes:
On Tuesday, 23 July 2019 at 00:01:09 UTC, Exil wrote:
 On Monday, 22 July 2019 at 22:05:17 UTC, adamgoldberg wrote:
 Hey, I just happened to be writing a program in D an stumbled 
 upon a bug, that causes it to terminate after receiving a SEGV 
 signal, nothing wierd so far but it looks everything I tried 
 shows it is the break statement inside of a switch.
 It seems to have a relatively random chance of occuring, and 
 also somewhat dependant on the compiler, and build mode used.
 I'm short on time so instead of rewriting my SO post I will 
 just link it.

 Here! 
 https://stackoverflow.com/questions/57153617/random-segmentation-fault-in-d-lang-on-switch-break

 Hope someone can help!
Could be the statement in the actual switch(), which is accessing a pointer "codecpar". switch (stream.codecpar.codec_type) ^^^^^ This could be null and you aren't checking for it. I find that D sometimes doesn't have the correct line numbers for debug info, even when not doing an optimized build. So it could really be anything in that function. The root cause could be a lot of things though, some bad codegen or otherwise. Could add a check to make sure though.
I ran the program after adding enforce (stream.codecpar != null); and nothing changed, and by nothing I mean that DMD in debug mode still doesnt crash but DMD in release does (like 70% of the time), I think its more important to address that issue because I can't seem to find any explenation of this behaviour, yet it occurs.
Jul 23 2019
parent Boris Carvajal <boris2.9 gmail.com> writes:
On Tuesday, 23 July 2019 at 08:04:07 UTC, adamgoldberg wrote:
 On Tuesday, 23 July 2019 at 00:01:09 UTC, Exil wrote:
 On Monday, 22 July 2019 at 22:05:17 UTC, adamgoldberg wrote:
 Hey, I just happened to be writing a program in D an stumbled 
 upon a bug, that causes it to terminate after receiving a 
 SEGV signal, nothing wierd so far but it looks everything I 
 tried shows it is the break statement inside of a switch.
 It seems to have a relatively random chance of occuring, and 
 also somewhat dependant on the compiler, and build mode used.
 I'm short on time so instead of rewriting my SO post I will 
 just link it.

 Here! 
 https://stackoverflow.com/questions/57153617/random-segmentation-fault-in-d-lang-on-switch-break

 Hope someone can help!
Could be the statement in the actual switch(), which is accessing a pointer "codecpar". switch (stream.codecpar.codec_type) ^^^^^ This could be null and you aren't checking for it. I find that D sometimes doesn't have the correct line numbers for debug info, even when not doing an optimized build. So it could really be anything in that function. The root cause could be a lot of things though, some bad codegen or otherwise. Could add a check to make sure though.
I ran the program after adding enforce (stream.codecpar != null); and nothing changed, and by nothing I mean that DMD in debug mode still doesnt crash but DMD in release does (like 70% of the time), I think its more important to address that issue because I can't seem to find any explenation of this behaviour, yet it occurs.
The struct AVStream is different on the D side (avformat.d) than the original C header, at least on my PC using ffmpeg 4.1.4. So instead of getting codecpar member we get some unrelated data and dereferencing it can crash the program. I tried using the DPP project, it errors out but the generated file is almost there, just commenting 1 line and changing some not found type pointer member to void pointer I got a working example with your same code. Here is the updated struct part, the program will run fine with this layout. struct AVStream { int index; int id; AVCodecContext* codec; void* priv_data; AVRational time_base; c_long start_time; c_long duration; c_long nb_frames; int disposition; AVDiscard discard; AVRational sample_aspect_ratio; AVDictionary* metadata; AVRational avg_frame_rate; AVPacket attached_pic; AVPacketSideData* side_data; int nb_side_data; int event_flags; AVRational r_frame_rate; char* recommended_encoder_configuration; AVCodecParameters* codecpar; static struct _Anonymous_9 { c_long last_dts; c_long duration_gcd; int duration_count; c_long rfps_duration_sum; double[399]** duration_error; c_long codec_info_duration; c_long codec_info_duration_fields; int frame_delay_evidence; int found_decoder; c_long last_duration; c_long fps_first_dts; int fps_first_dts_idx; c_long fps_last_dts; int fps_last_dts_idx; } _Anonymous_9 _anonymous_10; auto last_dts() property nogc pure nothrow { return _anonymous_10.last_dts; } void last_dts(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.last_dts = val; } auto duration_gcd() property nogc pure nothrow { return _anonymous_10.duration_gcd; } void duration_gcd(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.duration_gcd = val; } auto duration_count() property nogc pure nothrow { return _anonymous_10.duration_count; } void duration_count(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.duration_count = val; } auto rfps_duration_sum() property nogc pure nothrow { return _anonymous_10.rfps_duration_sum; } void rfps_duration_sum(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.rfps_duration_sum = val; } auto duration_error() property nogc pure nothrow { return _anonymous_10.duration_error; } void duration_error(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.duration_error = val; } auto codec_info_duration() property nogc pure nothrow { return _anonymous_10.codec_info_duration; } void codec_info_duration(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.codec_info_duration = val; } auto codec_info_duration_fields() property nogc pure nothrow { return _anonymous_10.codec_info_duration_fields; } void codec_info_duration_fields(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.codec_info_duration_fields = val; } auto frame_delay_evidence() property nogc pure nothrow { return _anonymous_10.frame_delay_evidence; } void frame_delay_evidence(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.frame_delay_evidence = val; } auto found_decoder() property nogc pure nothrow { return _anonymous_10.found_decoder; } void found_decoder(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.found_decoder = val; } auto last_duration() property nogc pure nothrow { return _anonymous_10.last_duration; } void last_duration(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.last_duration = val; } auto fps_first_dts() property nogc pure nothrow { return _anonymous_10.fps_first_dts; } void fps_first_dts(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.fps_first_dts = val; } auto fps_first_dts_idx() property nogc pure nothrow { return _anonymous_10.fps_first_dts_idx; } void fps_first_dts_idx(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.fps_first_dts_idx = val; } auto fps_last_dts() property nogc pure nothrow { return _anonymous_10.fps_last_dts; } void fps_last_dts(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.fps_last_dts = val; } auto fps_last_dts_idx() property nogc pure nothrow { return _anonymous_10.fps_last_dts_idx; } void fps_last_dts_idx(_T_)(auto ref _T_ val) property nogc pure nothrow { _anonymous_10.fps_last_dts_idx = val; } _Anonymous_9* info; int pts_wrap_bits; c_long first_dts; c_long cur_dts; c_long last_IP_pts; int last_IP_duration; int probe_packets; int codec_info_nb_frames; AVStreamParseType need_parsing; AVCodecParserContext* parser; AVPacketList* last_in_packet_buffer; AVProbeData probe_data; c_long[17] pts_buffer; AVIndexEntry* index_entries; int nb_index_entries; uint index_entries_allocated_size; int stream_identifier; int program_num; int pmt_version; int pmt_stream_idx; c_long interleaver_chunk_size; c_long interleaver_chunk_duration; int request_probe; int skip_to_keyframe; int skip_samples; c_long start_skip_samples; c_long first_discard_sample; c_long last_discard_sample; int nb_decoded_frames; c_long mux_ts_offset; c_long pts_wrap_reference; int pts_wrap_behavior; int update_initial_durations_done; c_long[17] pts_reorder_error; ubyte[17] pts_reorder_error_count; c_long last_dts_for_order_check; ubyte dts_ordered; ubyte dts_misordered; int inject_global_side_data; AVRational display_aspect_ratio; AVStreamInternal* internal; }
Jul 23 2019
prev sibling parent eric makechip.com writes:
Shouldn't (stream == null) be (stream is null)? 

-Eric 


From: "adamgoldberg via Digitalmars-d-learn"
<digitalmars-d-learn puremagic.com> 
To: digitalmars-d-learn puremagic.com 
Sent: Monday, July 22, 2019 3:05:17 PM 
Subject: Why does a switch break cause a segmentation fault 

Hey, I just happened to be writing a program in D an stumbled 
upon a bug, that causes it to terminate after receiving a SEGV 
signal, nothing wierd so far but it looks everything I tried 
shows it is the break statement inside of a switch. 
It seems to have a relatively random chance of occuring, and also 
somewhat dependant on the compiler, and build mode used. 
I'm short on time so instead of rewriting my SO post I will just 
link it. 

Here! 
https://stackoverflow.com/questions/57153617/random-segmentation-fault-in-d-
ang-on-switch-break 

Hope someone can help! 
Jul 22 2019