Bug: MATLAB crashes when mexifying the official `timestwo.c`
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Zaikun Zhang
le 17 Fév 2022
Réponse apportée : Zaikun Zhang
le 3 Mar 2022
Update (20220225): Here is the latest update received from the supporting team of MathWorks.
```
Got the confirmation that the crash is actually considered as "undefined behavior" ... But still we are seeking for a way to avoid such crashes, e.g. we can throw an error message ... Many thanks for reporting this issue with detailed reproducing steps. The developers are now aware of it and will have it fixed in a future release (but we can't reveal develop plans to customers so I'm afraid there won't be any specific information about when and how they're gonna fix it).
```
Below is the original post.
This is a bug of MATLAB. MATLAB crashes when executing crash.m shown below. It has been reported to MathWorks and confirmed on the following versions, all under Linux (but not under macOS or Windows).
- R2018b Update 3 (9.5.0.1049112) 64-bit (glnxa64
- R2019b Update 5 (9.7.0.1319299) 64-bit (glnxa64)
- R2020a (9.8.0.1323502) 64-bit (glnxa64)
- R2021a Update 5 (9.10.0.1739362) 64-bit (glnxa64)
- R2021b Update 1 (9.11.0.1809720) (glnxa64) [check how the crash look like on GitHub Actions]
If you are a Linux user and you want to see how the bug looks like, you can copy crash.m given below, and run
crash
in the MATLAB command window. Then MATLAB will crash. The bug does not affect macOS or Windows: on Windows, MATLAB will raise an error (which is fine) but not crash; on macOS, MATLAB will handle everything nicely without any abnormalty.
The code is also available on GitHub, where you can find much more information, including why does MATLAB crash in this case and how to circumvent the bug before MathWorks fixes it.
Here is crash.m.
function crash(crash_type, crash_indicator, language)
%CRASH is a script to crash MATLAB provided that MEX is configured for `language` and
% `crash_indicator` is absent or set to true. There are two types of crashes:
% 1. if crash_type == 'setup', then `mex('-setup', language)` crashes;
% 2. if crash_type == 'mex', then `mex(timestwo_src, '-outdir', build_dir)` crashes.
% Parse the input.
if nargin < 1 || ~(isa(crash_type, 'char') || isa(crash_type, 'str'))
crash_type = 'setup';
end
cind = (nargin < 2 || crash_indicator);
if nargin < 3 || ~(isa(language, 'char') || isa(language, 'str'))
language = 'C';
end
% Locate the official example for MEX provided by MathWorks.
if strcmpi(language, 'Fortran')
timestwo_src_name = 'timestwo.F';
elseif strcmpi(language, 'C') || strcmpi(language, 'C++')
timestwo_src_name = 'timestwo.c';
else
error('Unknown language: %s', language);
end
official_timestwo_src = fullfile(matlabroot, 'extern', 'examples', 'refbook', timestwo_src_name);
% Directories.
% The test directory.
test_dir = pwd();
% The source directory.
src_dir = fullfile(test_dir, 'src');
if exist(src_dir, 'dir')
rmdir(src_dir, 's');
elseif exist(src_dir, 'file')
delete(src_dir);
end
% The build directory.
build_dir = fullfile(test_dir, 'build');
if exist(build_dir, 'dir')
rmdir(build_dir, 's');
elseif exist(build_dir, 'file')
delete(build_dir);
end
% Conduct the tests.
for itest = 1 : 2
fprintf('\n************************* Test %d starts. *************************\n', itest);
mkdir(src_dir);
fprintf('\nCopy the official `%s` to the source directory ... ', timestwo_src_name);
timestwo_src = fullfile(src_dir, timestwo_src_name);
copyfile(official_timestwo_src, timestwo_src, 'f');
fileattrib(timestwo_src, '+w');
fprintf('Done.\n');
if cind
% Create in the source directory a file with the same name as the mexified `timestwo`.
fake_mex_file_name = ['timestwo.', mexext];
fake_mex_file = fullfile(src_dir, fake_mex_file_name);
fprintf('\nCreate a fake %s file in the source directory ... ', fake_mex_file_name);
fclose(fopen(fake_mex_file, 'w'));
fprintf('Done.\n');
end
compile(src_dir, build_dir, timestwo_src_name, crash_type);
fprintf('\nWhich `timestwo`?\n');
which('timestwo')
fprintf('\nEvaluate `timestwo(1)` ... ');
timestwo(1)
fprintf('************************** Test %d ends. **************************\n\n', itest);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function compile(src_dir, build_dir, timestwo_src_name, crash_type)
%COMPILE is a script that copies the source files from src_dir to build_dir and then compile them.
% Decide the language being tested.
if endsWith(timestwo_src_name, 'F')
language = 'Fortran';
elseif endsWith(timestwo_src_name, 'c')
language = 'C';
else
error('Unknown source file name %s', timestwo_src_name)
end
% Copy the source files and set up MEX. The order decides what kind of crash will occur.
switch crash_type
case 'setup' % First copy the source files from `src_dir` to `build_dir`, and then set up MEX.
fprintf('\nCopy the source directory to the build directory ... ');
copy_src(src_dir, build_dir);
fprintf('Done.\n');
fprintf('\nConfigure MEX for compiling %s ...\n', language);
mex('-setup', language);
fprintf('Done.\n');
case 'mex' % First set up MEX, and then copy the source files from `src_dir` to `build_dir`.
fprintf('\nConfigure MEX for compiling %s ...\n', language);
mex('-setup', language);
fprintf('Done.\n');
fprintf('\nCopy the source directory to the build directory ... ');
copy_src(src_dir, build_dir);
fprintf('Done.\n');
otherwise
error('Unknown crash type %s', crash_type);
end
% Compilation.
fprintf('\nCompile `%s` ... \n', timestwo_src_name);
timestwo_src = fullfile(build_dir, timestwo_src_name);
mex(timestwo_src, '-outdir', build_dir);
addpath(build_dir);
fprintf('Done.\n');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function copy_src(src_dir, build_dir)
%restoredefaultpath; % `restoredefaultpath` or `rmpath(build_dir)` alone can NOT fix the crash
%clear('timestwo'); % This line alone can fix the crash
%delete(fullfile(src_dir, ['timestwo.', mexext])); % This line alone can fix the crash
%if exist(build_dir, 'dir'); delete(fullfile(build_dir, ['timestwo.', mexext])); end % This line alone can fix the crash
copyfile(src_dir, build_dir, 'f');
%clear('timestwo') % This line alone can NOT fix the crash
%delete(fullfile(src_dir, ['timestwo.', mexext])); % This line alone can NOT fix the crash
%delete(fullfile(build_dir, ['timestwo.', mexext])); % This line alone can NOT fix the crash
end
I look forward to this bug fixed. Thanks.
6 commentaires
Réponse acceptée
Plus de réponses (0)
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!