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;
}