gcov: cannot open graph file - c

I am trying to use gcov. I have this simple file a.c:
int main() {
return 0;
}
So I do
gcc -fprofile-arcs -ftest-coverage a.c -o a
./a
gcov a.c
and I get
a.gcno:cannot open graph file
Am I doing something wrong? I'm under Mac OS X Lion.

By default on Lion, "gcc" is not gcc. It's LLVM. And it doesn't support generating test coverage data.
If you run gcc-4.2 -fprofile-arcs -ftest-coverage a.c -o a instead that will use a real gcc, and it'll probably work.

Are you sure you are running the command from the same directory as the source file? You must be in the same directory, unless you specify the -o flag. Try:
gcov -o a.c

Try using clang instead of gcc. I had the same problem, and using clang fixed it for me.

Often this happens when the version of gcov you're running doesn't match the version of GCC used to compile the application. On some systems, package managers have odd practices in how they link GCC and gcov. For example on many systems gfortran is the same as gfortran-5 but gcov might be something old and crusty.

I used the following on Mac 10.8.4:
Installed via xcode the command line tools:
wrote this example code from the gcc website:
#include <stdio.h>
main()
{
int i, total; total = 0;
for (i = 0; i < 10; i++)
total += i;
if (total != 45)
printf ("Failure\n");
else
printf ("Success\n");
}
Compiling using the real GCC gcc-mp-4.7 -fprofile-arcs -ftest-coverage tmp.c
And using GCC's gcov: gcov-mp-4.7 -b tmp.c will give you this output:
File 'tmp.c'
Lines executed:87.50% of 8
Branches executed:100.00% of 4
Taken at least once:75.00% of 4
Calls executed:50.00% of 2
Creating 'tmp.c.gcov'

Related

gcc linking two files not working in macOS

For my compiler course, I'm following the Incremental Approach to Compiler Construction by Abdulaziz Ghuloum with the accompanying tutorial. At some point, we have the following two .c files:
runtime.c
#include <stdio.h>
int main(int argc, char** argv) {
printf("%d\n", entry_point());
return 0;
}
ctest.c
int entry_point() {
return 7;
}
The author then runs the following commands:
$ gcc -Wall ctest.c runtime.c -o test
[bunch of warnings]
$ ./test
7
$
But when I run $ gcc -Wall ctest.c runtime.c -o test I get the following error:
runtime.c:9:20: error: implicit declaration of function 'entry_point' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
printf("%d\n", entry_point());
I want to be able to compile and link my two .c files the same way the author did using gcc, but it keeps throwing me that error. I've been doing some research but the same command ($ gcc file1.c file2.c -o combined) keeps coming up. Help would be appreciated.
I'm running this on MacOS Monterey 12.6 and doing gcc --version displays:
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Thanks in advance
On macOS, the default compiler is clang, not gcc. The later is just a symlink to clang so that's something to keep in mind.
Clang sees the call to entry_point() in runtime.c and doesn't know it yet. Traditional C for such an undefined function is to assume it returns int and does not accept arguments. But Clang goes the safe route by default and instead of just warning about it, treats this as an error since most of the time this assumption is just false and may cause runtime issues.
You have multiple options:
Add a header file that defines int entry_point(void); and #include it in your runtime.c.
Add the line int entry_point(void); near the top of your runtime.c.
Pass -Wno-error=implicit-function-declaration to the compiler.

Unable to run windows binary compiled with clang/lld/mingw

I have downloaded and installed clang on windows 10 from http://releases.llvm.org/download.html
and mingw from https://sourceforge.net/projects/mingw-w64/
I am trying to compile a very basic C program using clang/lld/mingw:
int main(int argc, char* argv[argc + 1])
{
return 0;
}
To compile I invoke:
clang.exe -target x86_64-windows-gnu -fuse-ld=lld.exe -g -gcodeview -Wl,/debug,/pdb:example.pdb example.c -o example.exe
This creates an exe which faults on startup in mainCRTStartup (__security_init_cookie to be precise).
However, running with default ld from binutils is successful:
clang.exe -target x86_64-windows-gnu example.c -o example.exe
Please note that I wish to use mingw headers, not msvc.
In total I tried:
x86_64-8.1.0-posix-seh-rt_v6-rev0
x86_64-7.3.0-posix-seh-rt_v5-rev0
x86_64-8.1.0-win32-seh-rt_v6-rev0
x86_64-8.1.0-win32-sjlj-rt_v6-rev0
without any luck producing a functional program.
So I am wondering, is there something obvious I am doing wrong here?
EDIT:
I have also tried with msys2 to no avail. Specifically:
pacman -S mingw-w64-x86_64-clang mingw-w64-x86_64-lld
According to https://bugs.llvm.org/show_bug.cgi?id=40568
Linking against mingw import libraries from a normal mingw installation is a new feature, first present in LLD 8.
Unless wanting to compile a pre-release version of lld, have to wait for binary release of llvm 8.0.0. This will hopefully be sometime in March.

Unable to use compiled netlib BLAS on mac OS X

I'm trying to make a repository collecting all the examples, tutorials and instructions I could find on the internet for C mathematical and algebra libraries (BLAS, CBLAS, LAPACK, CLAPACK, LAPACKE, ATLAS, openblas, GSL...). but it seems that I just can't get the compiled BLAS .a files working on mac OS X.
So far I have been able to compile BLAS and use it on ubuntu:
BLAS source code from netlib website downloaded and compiled (rename blas_LINUX.a to libblas.a)
Then I can compile the C file on ubuntu using the command below:
gcc foo.c path/to/libblas.a
On my mac OS X (EL Capitan), I can compile BLAS (changing LINUX in the make.inc to DARWIN), but when I try to compile a C code using the command above I get errors like below:
Undefined symbols for architecture x86_64:
"_ddot_", referenced from:
_main in foo-3a35db.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
("ddot" part differs for different functions)
possibilities:
Maybe I'm not compiling the library correctly on mac and there are some differences I'm not aware of
The builtin Accelerate framework of mac OS X is messing up with the compiling process
P.S. Guys I know BLAS/LAPACK is already built into the mac OS X Accelerate framework and I can easily compile using the command gcc foo.c -lblas or gcc foo.c -framework Accelerate but I want to use the compiled .a from netlib. I want to know why it works properly on ubuntu but not mac OS X?
P.S.2. Please notice that I can compile the source code successfully without any errors on mac OS X. I just can use it!
Example code: source
#include <stdio.h>
#include <stdlib.h>
double ddot_(const int *N, const double *a, const int *inca, const double *b, const int *incb);
int main(int argc, char **argv) {
double *a = (double *)malloc(3 * sizeof(double));
a[0] = 1.0;
a[1] = 2.0;
a[2] = 3.0;
// on the stack
double b[3] = {4.0, 5.0, 6.0};
int N = 3, one = 1; // one really doesn't look good in C
double dot_product = ddot_(&N, a, &one, b, &one);
printf(" The dot product is: %f \n", dot_product);
return 0;
}
(edit1) solution:
open make.inc
change the line OPTS = -O3 to OPTS = -O3 -pipe -c and make.
(edit2): better solution:
since I asked this question I have realised that I have been doing everything wrong. Netlib BLAS is actually a collection of fortran routines/subroutines/functions. and the Makefile in the source code just gives us a static library libblas.a which is a collection of all .o object files compiled with gfortran. when we want to compile a C code which want to call one of those routines, we also need to link to the gfortran library libgfortran.* so if you have gcc installed (brew install gcc). look for libgfrotran* (sudo find / -name "libgfortrn.*") and then link your gcc to this folder too. to make it easy I put a Makefile here:
all:
gcc -c foo.c
gcc -o bar.out foo.o -L path/to/libgfortran.*/ -lgfortran -L path/to/libblas.a -lblas
or alternatively compile the code directly with gfortran:
all:
gcc -c foo.c
gfortran -o bar.out foo.o -L path/to/libblas.a -lblas
or simply compile with:
gcc foo.c bar.out -L path/to/libblas.a -lblas -L path/to/libgfortran.*/ -lgfortran
the wonder is how/why the former solution actually worked and why on ubuntu you don't have to link to -lgfortran!
It seems you compiled BLAS library from Netlib with compiler options that changed the mangling scheme of Fortran routines.
By default, Netlib's make.inc uses gfortran to compile BLAS:
$ grep FORTRAN make.inc
# Modify the FORTRAN and OPTS definitions to refer to the
FORTRAN = gfortran
It is compiled without any flags:
gfortran -O3 -pipe -c ddot.f -o ddot.o
and you get the ddot() routine:
$ grep -i ddot ddot.o libblas.a
Binary file ddot.o matches
Binary file libblas.a matches
And you can find it with the command line tools:
$ nm ddot.o libblas.a | grep -i ddot
ddot.o:
0000000000000000 T _ddot_
libblas.a(ddot.o):
0000000000000000 T _ddot_
Your example compiles with the library:
cc ex.c libblas.a
or with the ddot.o file:
cc -pipe ex.c ddot.o
I cannot reproduce your problem. You should use the nm and grep commands to find out what happened to the name of the ddot() routine.
PS. Your code has extra semicolon ; after the end of definition of main().

Clang static analyzer can't find stdio.h

I'm trying to use Clang static analyzer on a very simple program:
#include <stdio.h>
main ()
{
printf("Hello, world !");
}
When i do
clang helloworld.c
It compiles the program successfully.
When i do
clang -cc1 -analyze -analyzer-checker=unix helloworld.c
it raises an error:
helloworld.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^
1 error generated.
clang --analyze -Xanalyzer -analyzer-checker=unix helloworld.c
doesn't print anything.
What is the problem and how can i fix it?
I assume static analyzer doesn't see the header files though the compiler can use them.
Please, help me.
Sometimes the checker is not able to read the default include path. So you might want to pass it as an argument.
You can find the exact include path clang looks at using this command:
clang -E -x c - -v < /dev/null
and then your final query will become:
clang -I<path to include> --analyze -Xanalyzer -analyzer-checker=unix helloworld.c
Solution using -cc1 flag:
See what include paths the clang is receiving. The flag -v is the key option. The quick way of using it is the following (as given by #Nishant) along with the sample include paths it prints,
$ clang -E -x c - -v < /dev/null
...
#include <...> search starts here:
/usr/local/include
/home/codeman/.itsoflife/local/packages-live/llvm-clang6/build/lib/clang/6.0.1/include
/usr/include/x86_64-linux-gnu
/usr/include
...
On my machine, the simple use of the following command works seamlessly,
$ clang --analyze -Xanalyzer -analyzer-checker=debug.DumpCFG main.c
however the following form fails, as you pointed,
$ clang -cc1 -analyze -analyzer-checker=debug.DumpCFG main.c
For this second command (with -cc1) you can create an environment variable say MY_INCLUDES with the necessary includes. Paste the code below (with necessary include paths as per your system) into ~/.bashrc or ~/.zshrc depending on if you are using bash or zsh. (don't forget to source ~/.bashrc or source ~/.zshrc)
export MY_INCLUDES="-I/usr/local/include -I/home/codeman/.itsoflife/local/packages-live/llvm-clang6/build/lib/clang/6.0.1/include -I/usr/include/x86_64-linux-gnu -I/usr/include"
Now on bash use,
$ clang -cc1 $MY_INCLUDES -analyze -analyzer-checker=debug.DumpCFG main.c
on zsh use,
$ clang -cc1 ${=MY_INCLUDES} -analyze -analyzer-checker=debug.DumpCFG main.c
Note the use of MY_INCLUDES after -cc1 but before the main.c file. Moreover, on zsh one has to use the = prefix with the env variable or else its considered a single string (for details see this answer).

How do I add a directory to C header include path?

I am having trouble installing a dependency for a program that itself depends on pcre.h. I have this installed to /opt/local/include, but the C compiler does not see it and thus gives me:
error: pcre.h: No such file or directory
I have confirmed this by writing a hello world program that tries to include it:
#include <pcre.h>
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
}
This also gives the error unless I specify the path as </opt/local/include/pcre.h>.
I would like the C compiler to find this by default but I do not know where this is configured. Tab completion hasn't revealed any HEADER_PATH environment variables and I cannot find anything like it that isn't specific to XCode. I am, however, using Mac OSX Snow Leopard on the off chance that makes a difference.
Use -I /opt/local/include on the command line or C_INCLUDE_PATH=/opt/local/include in the environment.
Use the pcre-config utility to get the right flags:
$ pcre-config --libs --cflags
-L/opt/local/lib -lpcre
-I/opt/local/include
If you're compiling via the command line,
$ gcc -Wall -g `pcre-config --libs --cflags` main.c

Resources