MEX File - Debugging LIBSVM in Visual Studio - visual-studio

I would like to debug a MEX file in Visual Studio (From MATLAB environment directly to C++ (Visual Studio 2012)).
I've understood that this it is possible by adding the -g option to the make file.
Attached you can find the makefile code I am using.
What changes should be applied to make it work?
Code:
# This Makefile is used under Linux
MATLABDIR ?= /usr/local/matlab
# for Mac
# MATLABDIR ?= /opt/local/matlab
CXX ?= g++
#CXX = g++-4.1
CFLAGS = -Wall -Wconversion -O3 -fPIC -I$(MATLABDIR)/extern/include -I..
MEX = $(MATLABDIR)/bin/mex
MEX_OPTION = CC\#$(CXX) CXX\#$(CXX) CFLAGS\#"$(CFLAGS)" CXXFLAGS\#"$(CFLAGS)"
# comment the following line if you use MATLAB on 32-bit computer
MEX_OPTION += -largeArrayDims
MEX_EXT = $(shell $(MATLABDIR)/bin/mexext)
OCTAVEDIR ?= /usr/include/octave
OCTAVE_MEX = env CC=$(CXX) mkoctfile
OCTAVE_MEX_OPTION = --mex
OCTAVE_MEX_EXT = mex
OCTAVE_CFLAGS = -Wall -O3 -fPIC -I$(OCTAVEDIR) -I..
all: matlab
matlab: binary
octave:
#make MEX="$(OCTAVE_MEX)" MEX_OPTION="$(OCTAVE_MEX_OPTION)" \
MEX_EXT="$(OCTAVE_MEX_EXT)" CFLAGS="$(OCTAVE_CFLAGS)" \
binary
binary: svmpredict.$(MEX_EXT) svmtrain.$(MEX_EXT) libsvmread.$(MEX_EXT) libsvmwrite.$(MEX_EXT)
svmpredict.$(MEX_EXT): svmpredict.c ../svm.h ../svm.o svm_model_matlab.o
$(MEX) $(MEX_OPTION) svmpredict.c ../svm.o svm_model_matlab.o
svmtrain.$(MEX_EXT): svmtrain.c ../svm.h ../svm.o svm_model_matlab.o
$(MEX) $(MEX_OPTION) svmtrain.c ../svm.o svm_model_matlab.o
libsvmread.$(MEX_EXT): libsvmread.c
$(MEX) $(MEX_OPTION) libsvmread.c
libsvmwrite.$(MEX_EXT): libsvmwrite.c
$(MEX) $(MEX_OPTION) libsvmwrite.c
svm_model_matlab.o: svm_model_matlab.c ../svm.h
$(CXX) $(CFLAGS) -c svm_model_matlab.c
../svm.o: ../svm.cpp ../svm.h
make -C .. svm.o
clean:
rm -f *~ *.o *.mex* *.obj ../svm.o

In general, you run the mex command with the -g option, and depending on your OS, either attach to MATLAB (Visual Studio in Windows) or start the debugger with the matlab startup script (e.g. matlab -Dgdb in Linux). Use these detailed instructions for your own MEX files.
However, for LIBSVM, you are provided with make.m, which can be used to build in any supported OS, and Makefile for use in Linux only. The Makefile is used for building the MEX files outside of MATLAB (i.e. without using mex.m, but instead a shell script in $(MATLABDIR)/bin/mex). In Windows, you need to edit make.m and add the -g option to each mex call:
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g libsvmread.c
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g libsvmwrite.c
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g svmtrain.c ../svm.cpp svm_model_matlab.c
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g svmpredict.c ../svm.cpp svm_model_matlab.c
Then, in MATLAB, run make (the modified make.m). Start Visual Studio, set one or more break points, and from the Debug menu, "Attach to Process...". Now you can run the MEX functions (e.g. svmtrain) and it will stop in Visual Studio when it hits the break points.
Just for completeness, if you were using Linux and wanted to go the Makefile route, just change the following line to build debug versions of the code:
MEX_OPTION += -largeArrayDims -g

First you have to compile the MEX-file with debugging information enabled. For instance use mex -g file.cpp or add the equivalent to your build system.
Next attach Visual Studio the the MATLAB process, open the C/C++ source file and place a breakpoint
Finally run the MEX function from MATLAB. VS will stop at that point and enter debugging mode.
Here is a page explaining the procedure.

Related

gcov and gcovr: no .gcno files are generated after compiling

I am trying to get code coverage in my unit test project in windows system.
Description
After compiling with -fprofile-arcs -ftest-coverage, I found out the execution file is generated and works fine. However there's no any .gcno files in the folder. So I cannot output the coverage report properly by gcovr.
Software version
gcc 8.1.0/gcov 8.1.0/gcovr 5.1/python 3.10.2
Steps
Here's what I've done during the whole process. Please help me if there's something wrong.
There are only .c and .h files in one folder
Compile my project using gcc
gcc -Wall -Wno-unknown-pragmas -fcompare-debug-second -fprofile-arcs -ftest-coverage -DUTEST AllTests.c CuTest.c BZR2.c BZR2_test.c -o beta.exe
Then I got beta.exe in the folder.
After runing beta.exe, there's my test result(All tests are passed.) showing in the command line window. Besides there're .gcda files with the same filename as my .c files.
Then I run gcovr -r ., the result is showing below. I think the reson why gcovr can't show the coverage information is there's no any .gcno files generated after compiling my project. But I don't understand why and how to solve this.
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL 0 0 --%
------------------------------------------------------------------------------
Thanks for your time!
Remove the -fcompare-debug-second option. It is used for debugging the compiler itself, and causes the compiler
to silence warnings, and omitting other options that would cause the compiler to produce output to files or to standard output as a side effect.
(see: https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Developer-Options.html)
Creation of gcno files is such a side effect.
General tips:
Instead of -fprofile-arcs -test-coverage you can simply use the --coverage option.
When you compile multiple source files in one go, then GCC tries to figure out file names for intermediate files, and also automatically derives some name for secondary outputs like gcno files. This used to be somewhat unintuitive, at least until reasonable behaviour was implemented in GCC 11.
To compile all of the files individually, we would use the structure:
OPTIONS="-Wall -Wno-unknown-pragmas --coverage -DUTEST"
# compile the individual compilation units
gcc -c $OPTIONS AllTests.c -o AllTests.o
gcc -c $OPTIONS BZR2.c -o BZR2.o
gcc -c $OPTIONS BZR2_test.c -o BZR2_test.o
# we should now have three gcno files
ls *.gcno
# link the final executable
gcc $OPTIONS CuTest.o BZR2.o BZR2_test.o -o beta.exe
At this point, it's typically appropriate to use a build system, for example by writing a Makefile:
CFLAGS += -Wall -Wno-unknown-pragmas --coverage -DUTEST
SOURCES = AllTests.c BZR2.c BZR2_tests.c
OBJECTS = $(SOURCES:.c=.o)
beta.exe: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#

Compiling in gfortran with makefile

I have received a bunch of .f95 files to be compiled. The only info included regarding its compilation is the order in which these has to be compiled and that the files are in free-form. Besides that there is a Makefile but it is a Makefile made for Intel Fortran Compiler. I know nothing about Fortran and just need to make use of the code. I do not have access to Intel Fortran Compiler and gfortran in macosx is my only available choice. I compiled similar code previously in a similar way and it worked fine. Nevertheless I get multiple errors and nothing happens.
As I said the MakeFile is not complex and is split in three main sections. How could I "translate" this to gfortran syntaxis and compile the code. Is there an equivalence of options between the two? I enclose an abridged version of the MakeFile.
Mine
% ifort -o BIN1.exe -O3 -diag-disable 8291 file1.f90 file2.f90 ....
% ifort -g -check bounds -o BIN1n.exe -O3 file1.f90 file2.f90 ....
% ifort -g -debug full -traceback -check bounds -check uninit -check pointers -check output_conversion -check format -warn alignments -warn truncated_source -warn usage -ftrapuv -fp-stack-check -fpe0 -fpconstant -vec_report0 -diag-disable 8291 -warn unused -o BIN.exe -O3 file1.f90 file2.f90 ....
You need to convert the ifort flags to gfortran flags. To the best of my knowledge this can only be done by reading the documentation of ifort and gfortran. I'm no expert but:
maybe -fpconstant can be replaced by -fdefault-real-8 (if I understand correctly this gfortran flag has the effect of the ifort flags -r8 and -fpconstant),
maybe -fpe0 can be replaced by using -ffpe-trap=XXX.
PS: You can find some equivalence at the page Compiling with gfortran instead of ifort

How can a segfault happen at runtime only because of linking unused modules?

I get a segmentation fault from a memory allocation statement just because I have linked some unrelated procedures to the binary.
I have a very simple Fortran program:
program whatsoever
!USE payload_modules
double precision,allocatable:: Vmat(:,:,:)
allocate(Vmat(2,2,2))
Vmat=1
write(*,*) Vmat
deallocate (Vmat)
! some more lines of code using procedures from payload_module
end program whatsoever
Compiling this using gfortran whatsoever.f95 -o whatsoever leads to a program with the expected behaviour. Of course, this program is not made to print eight times 1.000 but to call the payload_modules, yet hidden in the comments. However, if I compile and link the program with the modules issuing
gfortran -c -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none payload_module1.f90 payload_module2.f90 whatsever.f95
gcc -g -nostdlib -v -Wl,--verbose -std=gnu99 -shared -Wl,-Bsymbolic-functions \
-Wl,-z,relro -o whatsoever whatsoever.o payload_module1.o payload_module2.o
the program whatsoever doesn't run any more. I get a segmentation fault at the allocate statement. I have not yet uncommented the lines related to the modules (however, uncommenting them leads to the same behaviour)!
I know that the payload modules' code is not buggy because I ran it before from R and wrapped this working code into a f90-module. There are no name collisions; nothing in the modules is called Vmat. There is only one other call to allocate in the modules. It never caused any trouble. There is still plenty of memory left. gdb didn't give me any hints expect a memory address.
How can linking routines that are actually not called crash a program?
Compiling your code with
gfortran whatsoever.f95 -o whatsoever
is working because you link against the system libraries, everything is in place. This would correspond to
gfortran whatsoever.f95 payload_module1.f90 payload_module2.f90 -o whatsoever
which would also work. The commands you used instead omit the system libraries, and the code fails at the first time you call a function from there (the allocation). You don't see that you are missing the libraries, because you create a shared object (which is typically linked against the libraries later on).
You chose to separate compiling the objects and linking them into an executable. Doing this for Fortran program using gcc you need to specify the Fortran libraries, so there's a -lgfortran missing.
I'm not sure about that particular choice of compile options... -shared is usually used for libraries, are you sure you want a shared binary (whatever that is)?
With -nostdlib you tell the compiler not to link against the system libraries. You would then need to specify those libraries (which you don't).
For the main program test.F90 and a module payload.F90, I run
gfortran -c -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none payload.F90 test.F90
gcc -g -v -Wl,--verbose -std=gnu99 -Wl,-Bsymbolic-functions \
-Wl,-z,relro -lgfortran -o whatsoever test.o payload.o
This compiles and executes correctly.
It might be easier to use the advance options with gfortran:
gfortran -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none -Wl,-Bsymbolic-functions -Wl,-z,relro \
payload.F90 test.F90 -o whatsoever
The result is the same.

how to debug fortran program with multiple object files?

I have a fortran program that calls some dependent .o object files. I would like to be able to step across files when debugging, is this possible?
the compilation routine goes something like this:
gfortran -g -o analyze.x analyze.o active.o analysis.o angles.o attach.o basefile.o beeman.o bicubic.o
where analyze.x is the executable. All of the .o files have been compiled using the -g flag as well.
When i do (gdb) break main and then attempt to step through the program, most of the subroutines take place in the object files. I was wondering if it is possible to be able to step through the object file code as well.
This will work only if the object files linked into the executable have debug information in them, i.e. have been compiled with the -g option. So, this should work:
# Compile all Fortran and C files with debug info
gfortran -g -c *.f90
gcc -g -c *.c
# Link everything together
gfortran -g -o myexe *.o

Compilation error while porting from gfortran to ifort

I'm trying to port a program from gfortran to ifort (Intel Fortran Compiler 11). I'm stuck with two files that only compile with gfortran:
gfortran -x f77 -c daedrid.ff
gfortran -x f77-cpp-input -c daedris.ff
when I try to run intel fortran compiler with these files, I get:
ifort -fpp -c daedrid.ff
ifort: warning #10147: no action performed for specified file(s)
ifort -fpp -c daedris.ff
ifort: warning #10147: no action performed for specified file(s)
and no object files are created.
Now, how can I solve this problem o_O?
EDIT: Renaming the file extensions from ff to fpp
cp daedrid.ff daedrid.fpp
cp daedrid.ff daedrid.fpp
helps:
ifort -fpp -c daedrid.fpp
daedrid.fpp(1483): (col. 9) remark: LOOP WAS VECTORIZED.
daedrid.fpp(1490): (col. 11) remark: LOOP WAS VECTORIZED.
daedrid.fpp(1499): (col. 13) remark: LOOP WAS VECTORIZED.
ifort -fpp -c daedris.fpp
daedris.fpp(1626): (col. 9) remark: LOOP WAS VECTORIZED.
http://www.rcac.purdue.edu/userinfo/resources/black/userguide.cfm#compile_fortran_cpp
UPDATE: Is there a way to make the intel fortran compiler work without having to rename the files?
The options you're looking for are -Tf and -fpp (and optionally -fixed or -free. From ifort -help, the relevant lines are:
-Tf<file> compile file as Fortran source
-fpp[n] run Fortran preprocessor on source files prior to compilation
n=0 disable running the preprocessor, equivalent to no fpp
n=1,2,3 run preprocessor
-[no]fixed,-FI specifies source files are in fixed format
-[no]free, -FR specifies source files are in free format
So, all in all, if you have fixed-form source which needs preprocessing, you would use:
ifort -fpp -fixed -Tfa.ff
to compile file a.ff.

Resources