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