Clang static analyzer can't find stdio.h - c

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).

Related

Cygwin, gcc and C_INCLUDE_PATH

First of all, I'm a complete Cygwin/Unix/gcc noob. (I've only used VC++)
I installed Cygwin and tried to compile some C programs.
Some header files (I'd say, "brabra.h" which is in /home/MyUsername/brabrabra/include) were needed so I did
export C_INCLUDE_PATH=/home/MyUsername/brabrabra/include
and then tried to compile by
gcc -o program1 program1.c
but it said
brabra.h: No such file or directory
So I did
gcc -o program1 program1.c -v
and it said
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include
/usr/include
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/../../../../lib/../include/w32api
End of search list.
So yea, it seems that the include directory I set by "export" command is not recognized by gcc.
What can I do?
What can I do?
You could tell the compiler directly where to look for specific files.
This can be done by using the -I option.
gcc -I /home/MyUsername/brabrabra/include -o program1 program1.c
Note that this options need go before the source file which might need to look up the directory specified by -I, so the command shoud at least look like this:
gcc -o program1 -I /home/MyUsername/brabrabra/include program1.c
BTW, the -L option works the same, but for library files needed for linking.

Why do I keep getting "Killed: 9" when I run this very basic SQLite3 based C file?

I have this super basic C file:
#include <sqlite3.h>
#include <stdio.h>
int main(void) {
printf("%s\n", sqlite3_libversion());
return 0;
}
And in the same directory I have sqlite3.h, sqlite3.c and sqlite3ext.h downloaded from the downloads page on sqlite.org.
I then run gcc -c main.c. Then chmod +x main.o. Then ./main.o. And every time I get:
Killed: 9
What am I doing wrong?
You cannot execute a relocatable object file directly like that. Try this:
gcc main.c -o main -lsqlite3
This works on Ubuntu with libsqlite3-dev package installed. Running main results in:
3.8.2
The -o flag specifies the name of the executable file. If you ommit -o main, you'll get a file called a.out with gcc on most platforms (maybe a.exe on windows+cygwin?). Either way, this file will already be executable, so you can skip the chmod +x.
The -lsqlite3 flag tells the compiler to link in the sqlite3 library too.
If you've built sqlite3 from scratch, you may also need -I and -L flags to tell the compiler where to look for libraries and headers.
In your command, the "-c" flag skips the linking stage and produces a relocatable object, where otherwise, gcc will produce an executable file.
You can use readelf -h main.o using output of your original command and readelf -h main using output of my suggested command, or alternatively just file main.o and file main to see differences in file types.

Compile a project (say, Emacs) to LLVM bytecode

I cloned the Emacs source, with the intention of compiling to LLVM bytecode. I have been fiddling with Makefile flags for hours, but with no luck. Whenever I Google this, I get completely unrelated results about compiling .el files.
So I ask you this: how can I compile a project like Emacs to LLVM bytecode?
I am on OS X 10.9 Mavericks.
EDIT: I ran these commands:
CC=clang CFLAGS=-emit-llvm ./configure --with-jpeg=no --with-gif=no --with-tiff=no
then
CC=clang CFLAGS=-emit-llvm make
Then I got this error:
xml.c:23:10: fatal error: 'libxml/tree.h' file not found
#include <libxml/tree.h>
^
1 error generated.
When in fact libxml2 is already installed.
-emit-llvm only tells clang that you want any emitted assembly to be in LLVM IR. However, you still need to inform clang that you would like it to emit assembly to start with. This is done by using the -S flag. Additionally, to compile to LLVM bytecode, you need to use llvm-as. Lastly, you will have to do this for every single file, since AFAIK you cannot link LLVM bytecode files together, meaning that you will have many, many LLVM bytecode files.
Enough blabbering though, here's how you would do it for a given file (in the shell, not in the makefile, mind you):
$ clang -c foo.c -S -emit-llvm # additional options as necessary
$ llvm-as foo.s
$ ls
foo.bc foo.c foo.s
Explanation:
$ clang -c foo.c
Compile foo.c by itself without linking.
$ clang -c foo.c -S
Generate assembly and, if no output file is specified, save the results in foo.s.
$ clang -c foo.c -S -emit-llvm
Generate LLVM IR instead of native assembly.
$ llvm-as foo.s
Assemble foo.s and, if no output file is specified, save the results in foo.bc.
EDIT:
Apparently, this works too:
$ clang -c foo.c -emit-llvm -o foo.bc
The -o foo.bc above is because otherwise clang will output a .o file.

Change build output directory when building via terminal

Recently, I found a program that is kind of a mix between an IDE and a text editor. It supports the syntax of the language and it does formatting, but it does not build and run the program for you. I am running Mac OS X 10.6.8. I looked up how to build C code using the Terminal application. The format is:
gcc [file]
Pretty simple. The problem is that I cannot change the directory of where the built file is outputted, nor can I change the name. By default, every file compiled is outputted in the home directory by the name of 'a.out.' How can I specify the output directory and name?
Thanks!
gcc has a -o option to change the output name. You can specify the path there. E.g.:
$ ls
program.c
$ gcc program.c -o program
$ ls
program program.c
$ mkdir bin
$ gcc program.c -o bin/program
$ ls bin
program
$
You should probably also want to know about a few other common options:
-std=c99, -std=gnu99: Use the c99 standard / with gnu extensions.
-Wall, -Wextra, -pedantic: Enable extra warnings.
-O0 -ggdb: Compile with debugging symbols. Look up how to use gdb.
-O2: Compile with processor-independent optimizations. Not compatible with -O0.

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