Bypass C errors to generate clang debugging information - c

TL:DR
Can you generate clang debugging information(CFGs, PDGs) when the original source file have DEPENDENCY errors from missing header files that cause compilation issues such as undeclared identifiers and unknown types? The files are syntactically correct. Is there a flag that maybe set all undeclared identifiers to INTs for debugging?
I am using Clang to analyze source code packages. Usually, I modify the makefile so clang generates debugging information using the command below
clang -emit-llvm -g -S -ferror-limit=0 -I somefile some_c_file
However, this approach is very makefile focused and if developer does not support Clang in that given build version, I have to figure out how to generate the debugging information.
This is not good for automation. For things such as OpenSSL where they include dozen of files(headers) and custom configurations for the given platform, this is not practical. I want to suppress or ignore the errors if possible since I know the build version's file under test is syntactically correct.
Thanks!

Recently I used clang-tidy for source code analysis of one of our projects. The project uses GNU compiler and we didn't wanted to move away from that. So the process that I followed was below:
1) Use bear to generate the compilation database i.e. compile_commands.json which is used by clang-tidy
2) By pass the include files that we don't want to analyze by including them as system files i.e. use --isystem for their inclusion and project specific files using -I. (If you can't change the Make files you could change the compile_commands.json by a simple find and replace)
Hope this helps

Related

Make clangd aware of macros given from the compiler

I have two executables that are build from the same source (a client and a server) and they're built with the compile options -D CLIENT=0 -D SERVER=1 for the server and -D CLIENT=1 -D SERVER=0 for the client. If I do something like
if (CLIENT) {
// Client specific code
}
clangd complains that CLIENT is not defined. Is there a way to make clangd aware of those macros? (The code compiles just fine, the errors are from clangd, not the compiler)
Is there a way to make clangd aware of those macros?
From getting started with clangd:
Project setup
To understand source code in your project, clangd needs to know the
build flags. (This is just a fact of life in C++, source files are not
self-contained.)
By default, clangd will assume that source code is built as clang
some_file.cc, and you’ll probably get spurious errors about missing
#included files, etc. There are a couple of ways to fix this.
compile_commands.json
compile_commands.json file provides compile commands for all source
files in the project. This file is usually generated by the build
system, or tools integrated with the build system. Clangd will look
for this file in the parent directories of the files you edit. Other
tools can also generate this file. See the compile_commands.json
specification.
compile_commands.json is typically generated with CMake build system, but more build systems try to generate it.
I would suggest moving your project to CMake, in the process you will learn this tool that will definitely help you in further C-ish development.
compile_flags.txt
If all files in a project use the same build flags, you can put those
flags, one flag per line, in compile_flags.txt in your source root.
Clangd will assume the compile command is clang $FLAGS some_file.cc.
Creating this file by hand is a reasonable place to start if your
project is quite simple.
If not moving to cmake, create a compile_flags.txt file with the content for example like the following, and clangd should pick this file up:
-DCLIENT=1
-DSERVER=1

Why can my C program run in "git bash", but not in "cmd"?

I wrote a demo using libpq to connect to a PostgreSQL database.
I tried to connect the C file to PostgreSQL by including
#include <libpq-fe.h>
after I added the paths into system variables I:\Program Files\PostgreSQL\12\lib as well as to I:\Program Files\PostgreSQL\12\include and compiled with this command:
gcc -Wall -Wextra -m64 -I "I:\Program Files\PostgreSQL\12\include" -L "I:\Program Files\PostgreSQL\12\lib" testpsql.c -lpq -o testpsql
It first raised three errors, like
libssl-1_1-x64.dll is missing
libintl-8.dll was missing
libcrypto-1_1-x64.dll was missing
After I downloaded these three files and put them into I:\Program Files\PostgreSQL\12\lib, and compiled it again, it shows the error
The application was unable to start correctly (0xc0150002)
when I type testpsql. But if I type ./testpsql on git bash, it works. Anyone can please tell me why?
The code that I used was the first example from here.
Environment: PostgreSQL 12, Windows 10, MinGW64
“Download the DLL files” sounds dangerous. From where?
I would get rid of these files again. Since you probably don't reference these libraries from your code, it must be the dependencies of libpq.dll and are probably found in I:\Program Files\PostgreSQL\12\bin (if you used the EDB installer).
The problem is probably that you the PATH environment variable is different in git bash and in cmd.exe, and in the latter case not all required shared libraries can be found on the PATH. The solution is to change the PATH so that it includes all DLL files the executable requires, not to start copying around files.
It is probably enough to include I:\Program Files\PostgreSQL\12\bin in the PATH. To resolve missing dependencies, use a tool like dependency walker or this replacement.

Compile entire C project instead of few files

I have an entire library made in C. It has almost 10 folders with a lot of files.
I have created a filename.c file in root folder and trying to compile it in mac using gcc test.c -o test however its not including header files. Generally I have to add all the header files gcc test.c libaudio.c -o test
How can I compile entire project instead of just one file.
Makefiles will solve your problem. You can create your own rules to clear the project (remove the generated files), build the project indicating where is your compiler (compile the source files located in some specific path, extension, etc), set the output path and so on, without typing a large compilation order.
https://www.gnu.org/software/make/manual/make.html
Edit: There you will be able to find how to add shared, static or raw libraries to your proyect through makefiles.
Use a Makefile. make the utility the reads the configuration within the Makefile will automate the running of the individual commands, such that you only need to name the item you wish to be rebuilt.
make myprogram
And make will use the dependency information stored in the Makefile's rules to determine what other elements are "out of date", rebuilding those and assembling them into myprogram.
This is a decent "first time" tutorial for "make".
Here is the full blown documentation for "make"
Once you master the concepts within make, you can then use other tools that make maintaining Makefiles either easier, more portable, or both.
Some tools that improve upon "make" include "cmake", "automake", "the autotools collection", "scons", "waf", "rake", "doit", "ninja", "tup", "redo", and "sake". There are more, and some are programming language specific, or limited to a particular enviornment.
The reason I recommend "make" over the others is because "make" is a baseline that will always be present, and the features in the other tools are often not understood or recognized to be needed until you get enough experience with "make".
In C, the concept of project is not part of the language, it depends generally of the tools / platform / library you have to build.
On Linux based platforms, you may have a makefile describing the project, or the library may have a cmake script.
You should be able to find the build instructions in you library documentation.
I definitely recommend the make approach as it is scalable.
If you really only have a couple of files, gcc will accept multiple .c files on the command line and link them all to generate one executable.

Error coming in compilation of C code on Oracle Linux 7.2

I am trying to compile a C code on Oracle Linux 7.2 which is hosted as VM on windows 10.
Name of file run: configure
Name of log file: confg.log
Error where I am stuck
gcc: error: unrecognized command line option '-V'
As per my understanding of the code structure so far, there is a file named configure which is having compilation related commands and this file generates Makefile.am which further generates Makefile.in and at last Makefile.
Please help me in solving the error and also let me know if my understanding about the configure and makefiles is incorrect
configure scripts explore the environment in which a program is to be built. They then accordingly adjust tools called, options used and libraries linked, among other things. Some of the information is obtained by trying to execute programs with certain options; failure of a program to run is the intended way of obtaining the information that the given program is not available or does not take those options. Therefore it is not necessarily an error if one of the things doesn't work and produces an error; it may be one of the legitimate outcomes, and the (error, here) exit code of the compiler will be used to modify the Makefile accordingly — for example by omitting -V ;-).
Does the configure script actually stop there, or are you just observing the error in the log file? If you search for gcc -V on the web you'll find examples of configure scripts failing actually later (for unrelated reasons) which have the same "-V error" line in it. Could that be the case? I would assume that errors which actually cause configure to stop and not produce a Makefile should be visible on the command line, not only in the log file.
As an aside it is worthwhile to run ./configure --help and look through the options. Some may improve the build process or the result; for example you can usually tell configure that you are using gcc, gnu ld and so on, or that you don't need certain features (like X25 ;-) ).
You should look into the makefile of your project, identify where the misspelled -V option is and replace it with -v (lowercase). As pointed out by others in the comments -V is not a compiling flag, but gives back the compiler's version.

Having issues compiling an exploit using GCC

I was trying to compile a C exploit for a security class I'm in and was struggling to get GCC to perform. The issue is that my /usr/include folder is missing folders that GCC is looking for to handle the includes of the file. The first error below describes a folder that doesn't exist.
asm/page.h: No such file or directory
What I've tried so far:
Symlink it with my /usr/src/linux-headers-4.4.0-kali1-common/include/* folders, but files within that folder start throwing errors that they in turn can't find other files.
Using GCC's -I parameter to manually specify each folder to look in for my includes but this also doesn't work. (Below)
gcc 10613.c -o workdamnit-I/usr/src/linux-headers-4.4.0-kali1-common/include/asm-generic/ -I/usr/src/linux-headers-4.4.0-kali1-common/include/linux/ -I/usr/src/linux-headers-4.4.0-kali1-common/include/uapi/asm-generic/ -I/usr/src/linux-headers-4.4.0-kali1-common/include/uapi/linux/
ERROR: In file included from /usr/include/stdio.h:33:0,
from 10613.c:2:
/usr/src/linux-headers-4.4.0-kali1-common/include/linux/stddef.h:4:31: fatal error: uapi/linux/stddef.h: No such file or directory
compilation terminated.
I updated the import statement to use page.h from my kali linux common headers. When I tried to run this, I received the below error:
'PAGE_SIZE' undeclared (first use in this function).
Lastly, I tried to compile with wine gcc but this particular exploit uses a socket library that I guess can't be compiled on a windows machine.
GCC version: 5.3.1
Link to exploit: https://www.exploit-db.com/exploits/10613/
My knowledge of C and its compilation requirements is very limited. Any assistance would be greatly appreciated.
Please give a usable and compilable example: https://stackoverflow.com/help/mcve
Based on the errors, it looks like -I/usr/src/linux-headers-4.4.0-kali1-common/include/uapi/linux/ should actually probably be -I/usr/src/linux-headers-4.4.0-kali1-common/include.

Resources