0

I have a common scenario: Some source files for an executable which depend on some standard libraries and some user libraries. All the user libraries are statically linked into the executable whereas the standard libraries are linked dynamically to it.

Problem: I believe that I have multiply defined symbols in my complete package (executable which already includes the user library code + shared standard libraries). The linker obviously has insight into it, but as I understand the linker won't complain unless it encounters multiple strong named symbols. My fear is that, while I am moving my code from solaris 8/sparc platform to solaris10/sparc platform, some standard unix functions have been implemented in the user libraries which are causing the app to crash at runtime. Note that the app runs fine in solaris 8/sparc platform

I have been facing weird issues which have led me to believe this might be the source

  1. Modifying one variable from one library is changing the value of another variable in another library
  2. Solaris 8-10: host2ip conversion problems

What I need:

  1. Is there a way to easily list all multiply defined symbols?
  2. Is there a way to easily list all multiply defined symbols stemming from user libraries?
  3. Do you guys think the issue #1 might be caused by linking issues, or you feel it might be a sign of some other issue?

Edit1: Since then I know that on generating map file using ld, it has a section of multiply defined symbol which I am going through to find names that look like standard library call. For people who do not know, the linker will only fail to link if it finds multiple symbols with the same name AND the names are strong names.

Community
  • 1
  • 1
IDK
  • 178
  • 8

2 Answers2

0

You could turn on MAP file generation in the compiler (actually linker) settings and look through the map file for symbols that match the UNIX system functions you are concerned about. You'd probably have to write a script to automate it, but this would be a good starting point. The command line switch is probably -map or something similar, it will depend on which compiler/linker you are using.

syplex
  • 1,147
  • 6
  • 27
  • I am trying to understand the map file. It would be great if you could elaborate a bit on how it will help. I am using the map file generated by "ld -m" through gcc frontend, and it apparently does not have the symbols – IDK Sep 19 '12 at 13:37
  • @IDK I'm not sure if case is important, but make sure you're using the linker option -Map=mapfile.map (if passing through gcc, -Wl,-Map=mapfile.map). The symbol names and their locations will be generated into the mapfile. Then you'd be looking for symbols that have the same names as unix/stdlib functions such as inet_ntoa_r. This is the part where you'd probably have to write a script. – syplex Sep 20 '12 at 22:52
  • ld does not take that option. I tried gcc-2.95.2 -Wl,-Map=mapfile.map and got the error ld: fatal: file ap=mapfile.map: stat failed: No such file or directory since the -M is what it considered the option – IDK Sep 24 '12 at 14:53
  • I wanted to mark your suggestion as one of the answers, but I guess I can select only one – IDK Sep 24 '12 at 15:52
0

The actual problem that was happening is: The library (let's call it lib1) had an array like below

#define ARRAY_SIZE 1024
SomeStruct* global_array[ARRAY_SIZE];

This array is used by my another library (let's call it lib2) which in turn is used by my application using an extern declaration for it.

While compiling lib2 (or is it the app not sure), we did not define ARRAY_SIZE at all. This somehow caused the compiler of lib2 (or the app) to miscalculate the size of global_array in-turn causing it to allocate the memory for some other variable at a location which was already allocated to the global_array.

By defining ARRAY_SIZE again while compiling my libs and apps, everything starts behaving normal. I do not fully understand what caused the issue and why it gets resolved since extern declaration of arrays do not contain the size. Also, if the library really used the MACRO ARRAY_SIZE, then why wouldn't the compilation fail? Also, there is a possibility, that the name used for the define is a standard name (the actual string was FD_SETSIZE)

My initial gut feeling about the linker was wrong.

IDK
  • 178
  • 8