Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the -ldl flag while compiling and linking C++ files

With reference to the following code

test_linker.cpp

int main() {

    srand(time(0));
    for (int i = 0; i < 10; ++i) {
        cout << rand() % 10 << endl;
    }

    return 0;
}

urandom.cpp

#include <iostream>
using std::cout;
using std::endl;
#include <dlfcn.h>

int rand() throw() {

    // get the original rand() function
    static auto original_rand = (decltype(&rand)) dlsym(RTLD_NEXT,"rand");

    cout << "Call made to rand()" << endl;
    return original_rand();
}

When I try to compile the code with the following command

g++ -std=c++11 -Wall -Werror -Wextra -Wvla -pedantic -O3 urandom.cpp -c
g++ -std=c++11 -Wall -O3 test_linker.cpp urandom.o -ldl

everything works fine, but when I move the -ldl flag to being before the files, the linker throws an error saying

urandom.cpp:(.text+0xaf): undefined reference to `dlsym'

Question 1 Could someone explain why this would happen? I generally do not care about the order of flags in a compilation command.

Question 2 Also is it wrong to keep the function pointer to the original rand() function a static variable? I do not know how exactly dynamic linking works and I am afraid that maybe the function address is moved around in memory at runtime. The manual pages said that the dlsym() function with the RTLD_NEXT handle is an expensive computation so I just wanted to lazily evaluate this once.

Note : I am compiling this on a Linux distribution and the Linux dynamic linker is involved so I will go ahead and tag this with Linux also.

like image 568
Curious Avatar asked Feb 10 '16 19:02

Curious


People also ask

What does the flag do in compiling?

Compile-time flags are boolean values provided through the compiler via a macro method. They allow to conditionally include or exclude code based on compile time conditions. There are several default flags provided by the compiler with information about compiler options and the target platform.

What are compiler flags in c?

Compiler flags are options you give to gcc when it compiles a file or set of files. You may provide these directly on the command line, or your development tools may generate them when they invoke gcc.

What is Flag in make file?

Flags in make are just variables containing options that should be passed to the tools used in the compilation process. Although you can use any variable for this purpose, make defines some commonly used flags with default values for some common tools, including C and C++ compiler, C preprocessor, lex , and yacc .

What is the use of flag in gcc?

This flag helps us to specify the name of the final executable produced by GCC. It places the output of the final executable in a file “file” as specified along with the flag.


2 Answers

-ldl is a library designation for the linker. It tells the linker to find and link a file named libdl.so (or sometimes libdl.a). It has the same effect as placing a full path to the library in question in the same position of the command line.

Library and object order on the command line does matter. Normally if library A calls library B, B should be placed after A on the command line. All libraries should normally go after all object files. This is covered extensively in several SO questions and answers like this one.

As for the second question, no, an address of a function doesn't change at run time unless you dlopen a shared library, then unload it, then dlopen it again. In your case, since you don't dlopen the library, it is safe to keep the function address in a static variable. Of course if you run multiple threads you need to ensure thread safety somehow (mutex it out, or use thread-local storage).

like image 198
n. 1.8e9-where's-my-share m. Avatar answered Sep 18 '22 14:09

n. 1.8e9-where's-my-share m.


Begin with your second question, dynamic linking works during run time either way in C/C++ we call later binding with this -> operation. Of course when you are invoking later binding declared like an interface or class instance, should be pointing to the specified object and memory location for that object.

The first one question is more i think specific to compiler. I guess you are compiling not in Visual Studio(Not in Windows OS) if i am right u should ask to the vendor of the compiler to configure debugging properties. :)

like image 24
Achiko Mezvrishvili Avatar answered Sep 20 '22 14:09

Achiko Mezvrishvili