2
votes

I have a .so library and while building it I didn't get any undefined reference errors. But now I am building an executable using the .so file and I can see the undefined reference errors during the linking stage as shown below:

xy.so: undefined reference to `MICRO_TO_NANO_ULL'

I referred to this and this but couldn't really understand the dynamic linking.

Also reading from here lead to more confusion:

Dynamic linking is accomplished by placing the name of a sharable library in the executable image. Actual linking with the library routines does not occur until the image is run, when both the executable and the library are placed in memory. An advantage of dynamic linking is that multiple programs can share a single copy of the library.

My questions are:

  • Doesn't dynamic linking means that when I start the executable using ./executable_name then if the linker not able to locate the .so file on which executable depends it should crash?

  • What actually is dynamic linking if all external entity references are resolved while building? Is it some sort of pre-check performed by dynamic linker? Else dynamic linker can make use of LD_LIBRARY_PATH to get additional libraries to resolve the undefined symbols.

4
People voting for the question to be closed - Please post a link where I can read about it and I will delete the question myself.Yug Singh
You should indeed post the linker errors you observe.Ctx
@YugSingh "Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question." -- close reason for "Needs focus"S.S. Anne
@S.S.Anne I felt like the questions were related and occurred to me while trying to understand the dynamic linking. That's why I posted them as part of same question. Thanks for the suggestion.Yug Singh
@Ctx I have added the linker error. Thanks for the suggestion.Yug Singh

4 Answers

2
votes

Doesn't dynamic linking means that when I start the executable using ./executable_name then if the linker not able to locate the .so file on which executable depends it should crash?

No, linker will exit with "No such file or directory" message.

Imagine it like this:

  • Your executable stores somewhere a list of shared libraries it needs.
  • Linker, think of it as a normal program.
  • Linker opens your executable.
  • Linker reads this list. For each file.
    • It tries to find this file in linker paths.
    • If it finds the file, it "loads" it.
    • If it can't find the file, it get's errno with No Such file or directory from open() call. And then prints a message that it can't find the library and terminates your executable.
  • When running the executable, linker dynamically searches for a symbol in shared libraries.
    • When it can't find a symbol, it prints some message and the executable teerminates.

You can for example set LD_DEBUG=all to inspect what linker is doing. You can also inspect your executable under strace to see all the open calls.

What actually is dynamic linking if all external entity references are resolved while building?

Dynamic linking is when you run the executable then the linker loads each shared library.

When building, your compiler is kind enough to check for you, that all symbols that you use in your program exist in shared libraries. This is just for safety. You can for example disable this check with ex. --unresolved-symbols=ignore-in-shared-libs.

Is it some sort of pre-check performed by dynamic linker?

Yes.

Else dynamic linker can make use of LD_LIBRARY_PATH to get additional libraries to resolve the undefined symbols.

LD_LIBRARY_PATH is just a comma separated list of paths to search for the shared library. Paths in LD_LIBRARY_PATH are just processed before standard paths. That's all. It doesn't get "additional libraries", it gets additional paths to search for the libraries - libraries stay the same.

1
votes

It looks like there is a #define missing when you compile your shared library. This error

xy.so: undefined reference to `MICRO_TO_NANO_ULL'

means, that something like

#define MICRO_TO_NANO_ULL(sec) ((unsigned long long)sec * 1000)

should be present, but is not.

The compiler assumes then, that it is an external function and creates an (undefined) symbol for it, while it should be resolved at compile time by a preprocessor macro.

If you include the correct file (grep for the macro name) or put an appropriate definition at the top of your source file, then the linker error should vanish.

1
votes

Doesn't dynamic linking means that when I start the executable using ./executable_name then if the linker not able to locate the .so file on which executable depends it should crash?

Yes. If the .so file is not present at run-time.

What actually is dynamic linking if all external entity references are resolved while building? Is it some sort of pre-check performed by dynamic linker? Else dynamic linker can make use of LD_LIBRARY_PATH to get additional libraries to resolve the undefined symbols.

It allows for libraries to be upgraded and have applications still be able to use the library, and it reduces memory usage by loading one copy of the library instead of one in every application that uses it.

The linker just creates references to these symbols so that the underlying variables or functions can be used later. It does not link the variables and functions directly into the executable.

The dynamic linker does not pull in any libraries unless those libraries are specified in the executable (or by extension any library the executable depends on). If you provide an LD_LIBRARY_PATH directory with a .so file of an entirely different version than what the executable requires the executable can crash.


In your case, it seems as if a required macro definition has not been found and the compiler is using implicit declaration rules. You can easily fix this by compiling your code with -pedantic -pedantic-errors (assuming you're using GCC).

1
votes

Doesn't dynamic linking means that when I start the executable using ./executable_name then if the linker not able to locate the .so file on which executable depends it should crash?

It will crash. The time of crash does depend on the way you call a certain exported function from the .so file. You might retrieve all exported functions via functions pointers by yourself by using dlopen dlysm and co. In this case the program will crash at first call in case it does not find the exported method.

In case of the executable just calling an exported method from a shared object (part of it's header) the dynamic linker uses the information of the method to be called in it's executable (see second answer) and crashes in case of not finding the lib or a mismatch in symbols.

What actually is dynamic linking if all external entity references are resolved while building? Is it some sort of pre-check performed by dynamic linker? Else dynamic linker can make use of LD_LIBRARY_PATH to get additional libraries to resolve the undefined symbols.

You need to differentiate between the actual linking and the dynamic linking. Starting off with the actual linking: In case of linking a static library, the actual linking will copy all code from the method to be called inside the executable/library using it. When linking a dynamic library you will not copy code but symbols. The symbols contain offsets or other information pointing to the acual code in the dynamic library. If the executable does invoke a method which is not exported by the dynamic library though, it will already fail at the actual linking part.

Now when starting your executable, the OS will at some point try to load the shared object into memory where the code actually resides in. If it does not find it or also if it is imcotable (i.e.: the executable was linked to a library using different exports), it might still fail at runtime.