C program links to wrong version of function - c

I'm trying to debug an issue where the wrong version of a function gets called causing a segfault. The code that I'm compiling is machine generated and includes a function called 'times' that does a complex multiply of it's two arguments. This code is compiled to a .o before being linked into a higher level object file.
When run this code segfaults and gdb indicates that it's in glibc's version of 'times' which doesn't even take the same number of arguments. The are no instances of '#include anywhere in this code.
Changing the name of times to times1 resolves the problem. This isn't a long term solution though due to the machine generated nature of the code and manually editing the name of this function all the time is unappealing.
The whole mess compiles cleaning with -Wall so I'm not sure where to look. Any ideas on how to resolve this?
Compile chain:
gcc -Wall -I. -g --shared -o dpd.o -fPIC *.c (mahine generated code here)
gcc -g --std=c99 -c -fpic getData.c -I/usr/local/include -L/usr/local/lib -lmatio -I/usr/local/include/iverilog -I$(MATLAB)
gcc -g -shared -o getData.vpi getData.o $(MATLAB)/dpd.o -lvpi -lmatio -L/usr/local/lib

C only uses the name of a function as an identifier, so any two (exported) functions with the same name will conflict. The normal approch is to prefix all exported names in a library with a unique prefix. The other alternative is to use C++ as "a better C" and simply build your C code using a C++ compiler, making use of C++ name mangling.

So the real answer to this one is to throw -fno-builtin-times to gcc. That avoids the problem neatly with no fuss.
This of course assumes that you can't changes the name of times to something that doesn't conflict with a glibc provided function.

Related

Compiling cmocka on windows

I'm trying to compile a simple unit test on my windows machine.
When I'm trying to compile my test I'm using the shared library flag.
gcc -c -L./bin/ -lcmocka .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o -o main
But the second line throws this error:
undefined reference to `_cmocka_run_group_tests'
However, if I'm compiling using directly the cmocka.c file which I downloaded from their git it works fine:
gcc -c .\lib\cmocka.c .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o .\cmocka.o
What am I doing wrong in the first compilation?
In addition, I would happy to understand the difference between the two compilations. Which one is the better practice?
Thank you
In order to compile your code, the compiler does not need to know where to look for the library. It's enough if the compiler "finds" the declarations of the functions which are usually in the header files provided by the library.
This step is done in the first line of your compilation procedure (maybe you need to specify the folder to the header files by adding -Ipath/to/headers/):
gcc -c .\Test.c .\src\some_module.c
The library itself is "combined" with your code during the linking step, which is done during your second compilation step. Here you need to specify the library (and its path via -Lpath/to/library, if the linker does not find the library on its own):
gcc .\Test.o .\some_module.o -o main -L./bin/ -lcmocka
You should definitely not use your second approach and compile the library by yourself.

How to figure out which function of a shared library is used if linking fails due to missing -lX fails?

Expanding a bit: given a project that you didn't see before and a linking failure like /usr/bin/ld.bfd.real: cannot find -lperl caused by gcc -shared -o PERLUAFS/ukernel.so -fPIC -Wl,-E -fstack-protector -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/perl/5.20/CORE -lperl -ldl -lm -lpthread -lc -lcrypt PERLUAFS/ukernel_swig_perl.o .libs/libuafs_pic.a /home/richter/openafs/lib/libcmd_pic.a /home/richter/openafs/lib/libafsutil_pic.a /home/richter/openafs/lib/libopr_pic.a -L/home/richter/openafs/lib -L/home/richter/openafs/lib -lafshcrypto -lrokenafs -lcrypt -lresolv
How would I figure out the functions which are used for linking to be passed to autoconf's AC_CHECK_LIB which doesn't allow omitting the function name and even if it would I'd still prefer to know exactly which functions are used.
The most trivial answer: ask the author(s) of the code which I would always do, but I'm interested in a theoretical solution as well.
Steps to resolv are imo:
determine the implementation source file which creates the .a files -> Assuming you have a configure.ac and Makefile.am which create Makefile.in and Makefile with thousands of lines what's the best proceedure here
check the source and findout where functions of the library X used by -lX are used
I have no idea how to do any of those. I would also be happy with a listing of complications which can be solved infinitely faster by the original author(s) than me so that I will really no ever try to solve this task.

What is the proper sequence of options for gcc & the importance of that sequence?

I used this command for compiling my program:
gcc -g -Wall -Werror -lpthread multi_thread_server.c -o multi_thread_socket_v4
It gave undefined reference to <function_name> error.
After of lot of trial and error to fix the error, finally I (by mistake) rearranged the options to gcc as:
gcc multi_thread_server.c -lpthread -Wall -Werror -o multi_thread_server -g
and it worked.
I read this question at SO, I got the reason as why it happened.
Here I want to know that, is there any rule for the sequence of options used for gcc?
P.S.: I know there are infinite options available for gcc, I want to know the sequence according to the category of options.
List libraries last.
After compiling, GCC passes files to the linker for linking (unless linking is not to be performed, as happens when you request compilation-only with the -c switch). It passes the files to the linker in the order you list them (or their corresponding inputs) on the command line.
You listed -lpthread (which means the pthread library, named libpthread.a or something similar) followed by multi_thread_server.c (which gets compiled to an object file named multi_thread_server.o. So the linker receives the library first, then the object file.
When the linker processes a library file, it extracts from it only the modules that supply a definition of a symbol that is needed to satisfy earlier references to the symbol. Since the library is the first file, there are no earlier references. When the linker processes multi_thread_server.o, it sees the references, but it is too late; the linker does not go back to the library.
If you list multi_thread_server.c first, the linker will see multi_thread_server.o first, and it will see that it has unsatisfied referencs. Then, when the linker processes the library, it will find the definitions for those references and will extract those modules from the library.

How can I know in which step (Pre-Processor,Compiling, Linking) my program failed to compile?

How can I know in which step (Pre-Processor,Compiling, Linking) my program got compilation failure?
For example, I wrote a program of 3 source files: a.c ,b.c, c.c and all three of them included the header file, h.h, which contains all the prototypes of all the source files, but I also implemented one function, in the header file. I know it's wrong to do, but I wonder on what stage did the program crash, Is it the linking or the compiling, I got an error message, Is this say that the problem is at the linking stage? (otherwise I'll just get a red underline on the mistake from the compiler?)
Where can I read about linking and what I shouldn't do regarding headers and source files and linking errors?
(I work in Linux, with Eclipse)
You find the location of the error by separating compiling and linking. An error due to the precompiler is unusual and also found during compiling. This is how compiling works on the command line:
Compile step:
gcc -c -o a.o -pedantic -Wall a.c
gcc -c -o b.o -pedantic -Wall b.c
gcc -c -o c.o -pedantic -Wall c.c
link step:
gcc a.o b.o c.o -o prog
Of course you need to specify whatever other flags that are necessary (e.g. -l for linking to a library etc.)
Then read the errors and warnings (!) carefully and you shall find the problem.
Your program crashes only once you have pre-procesed, compiled and linked your program to generate an executable that you can run. A crash is a run-time error.
Re preprocessor/compilation/linking:
You didn't specify what platform/environment you are working in, but in a Linux/Unix environment it is easy to determine if you are getting problems with the linker as you usually get a message with ld.
Compilation errors usually syntax related and easy to identify that way (e.g., mismatched parens, missing semi-colons, etc) (Aside, as a general rule, I would recommend you always compile with the highest warning level, and then consciously determine which warning messages to ignore.)
I am not at a system were I can try it out, so I'm not sure of the pre-processor throws out specific easily identifiable error/warning messages, or if they just get passed on to the compiler and get spit out at that stage.
None of these steps crash your program, that only happens (if it does) after all these steps have been completed successfully.

C gcc compilation question and makefiles

Not even quite sure what my question is. The short of it is, for a class I'm supposed to add some functionality to this c file, and it came with a handy makefile.
CFLAGS=-DUNIX -lreadline -lcurses -ansi -pedantic-errors
DEBUG=-g
#DEBUG=
all: shell
shell: shell.c parse.c parse.h
gcc $(CFLAGS) $(DEBUG) shell.c parse.c -o shell
clean:
rm -f shell *~
I have to add features to shell.c. I'm very new to C (usually use c++ or c#) so I'm testing out little things in a separate little tests.c file. Things like, see what exactly certain system calls return, how to printf them right, etc. Anyway, tests.c seems to be conforming to different c compiler standards or I'm compiling it wrong. If I accidentally use // to comment something out or declare a variable somewhere other than at the start in shell.c, the compiler yells at me. It doesn't care in tests.c.
I compile tests.c with "gcc tests.c -o tests"
If I compile the shell using "gcc shell.c parse.c -o shell" it compiles fine, but running it simply gives me a segmentation fault. I would love to ask my TA about this, but every time I as him something he answers a completely different question...
Any thoughts on what's going on here? Perhaps a point in the right direction at least?
The problem is that your makefile includes -ansi -pedantic-errors flags for the compiler. This forces it to use a very old version of C. Perhaps this Makefile was provided by your instructor and he wants like that? It is not uncommon.
To use these new features (// comments, automatic variables anywhere in a block) just drop these two flags. If you have the freedom, I recommend also using -std=c99 -Wall.
To get GCC to accept C99 conventions, tell it to do so:
gcc -std=c99 ...
gcc -std=gnu99 ...
So, add -std=gnu99 to your CFLAGS value, and remove -ansi which is equivalent to -std=c89. If you must code to C89 standards, do not use // comments.
We can't tell what causes the core dump - but it could be that you're trying to modify a string literal somewhere, or any of a large number of other problems.
The -ansi -pedantic-errors prevents the impurities like // and variable definitions in the middle of the function. Remove that and you should be able to sin away.
As for the segmentation fault, your best bet is to run your program through gdb to see where it crashes.
Why are you compiling by calling gcc directly instead of using the makefile? The makefile adds a number of additional command-line gcc options which are most likely important. Do you see the same behavior if you compile using make all?
Since you are new to C, I would recommend adding -Wall to the CFLAGS line. This will enable all compiler warnings, which may alert you to a subtle error that you might have otherwise missed.

Resources