I wrote a C++ class containing some static methods and I use it to build a library as dynamic library under Linux.
Then I compiled an application that use the same class and it links also the dynamic library previously compiled. In this way the class is used either in my application either in dynamic library.
When the application runs it causes a segmentation fault when a function of dynamic library calls a static method of the class: looking at the stack trace using gdb it seems to be a memory corruption because the error is very strange.
I suspect the problem is the call to the static function because his address showed in gdb stack trace is the address of symbol in executable binary and not in the library .so file. (I checked the addresses using nm tool)
The application calls the "wrong" version of the function.
The application can see two identical copies of functions: one symbol in application binary and one symbol (the same symbol) in dynamic library file.
My question are:
How can I distinguish the call of functions in application and in the library project? (considering that the class with static functions is the same source for both projects)
Why when I compile the application, the linker does not report an error for duplicated symbols?
Thanks
Update with more details
Trying to compile the application without compiling the class used by the library works perfectly.
The application needs to compile the class because afterwards it will be called but now it does NOT use it. Only the linked library uses it.
The static methods of the class calls a C function (declared using extern "C"). I tried to define a namespace in the library but without success. The static function called now is the correct one because the symbol has a different name using the namespace, but the function internally calls a global C method that has no namespace so the segmentation fault happens equally because it calls the wrong C function.
I don't understand why it crashes if the application calls the wrong function (the own version instead of the library version). The functions are identical and it is called only by the library (the application does not call it). There should be no difference on what function is called.
Related
Recently I changed (for packaging) my own libraries to STATIC. Now i receive error messages that a variable defined in the library is multiply defined. It is OK, the libraries use each other. But why was this not noticed by the linker until I changed to STATIC?
In one of my files, I set the variable declared as 'extern' and the linker also flags it as 'multiply defined'. Is it OK?
Basically the compiler has 4 stages:
pre-processing: macro and symbol edition
compiling : generate assembling code to be executed by the processor
assembling : generate binary code that the machine can understand(0/1 binary code)
Linking: the three previous operations are done separately for each file, however we need to edit the address mapping of each variable, pointer, function for the whole project here when we will have some problems when we have some multiple definition of variable because linking will check all file and generate an output for the whole project.
if a library is declared as static then the declared and defined function inside this library can't be used until the run time but in compile time it is not allowed to use this library in other files so if it is the case we will get errors during linking stage because the compiler will figure out the use of the function inside this static library by another file which is not allowed.
If you want it static , then use runtime concept to use this library (for example in C you can use pointer to function .
But why was this not noticed by the linker until I changed to STATIC?
Runtime linker allows duplicate symbol definitions (only one will be used at runtime, this is symbol interposition).
I'm writing a trivial windows console application that links to a bunch of static libraries via a
#pragma comment(lib, "SomeLibrary.lib");
(Amongst these libaries is SQLite3.lib)
When I start my program, the code in my main function doesn't seem to be executed, but instead the command line propt of the sqlite console application appears. Strange, isn't it? The only thing I can imagine causing this is that somehow another main function is defined somewhere else (supposedly in the static sqlite library) and that one is exectuted.
Is that possible? Is there some way to find out if there's a main function defined in a static library? And is there some way to give my main function precedence over the other one?
The sqlite3.lib library has a main function because you compiled the source code of the SQLite command-line shell into it.
Compile that library without shell.c.
It should contain nothing but sqlite3.c.
Hi I'm using a library that has globally overridden new/delete. But I have a problem with this library, the problem is that it has to be manually initialized in the main function.
Now I'm trying to use another library that initializes a few functions before main is called, unfortunately this library uses new within these functions. So I get errors because the memory manager that uses the overridden new/delete keywords are not initialized yet.
I'd really like to use the default memory manager because I want to add unit testing to this library. It would not make much sense to use the memory used my the library I want to test also used by my Unit Testing library.
So my question is if it's possible to ignore global overridden new/delete when including the second library and just use the default new/delete?
I'm using visual studio 2010 on Windows 7 with the standard C++ compiler.
I do not think this is possible without modifying the library itself. I guess it is about a static library (inside a dll, the overridden new/delete will be pointed by the functions inside the dll.)
You can remove an obj file from a static library by using the command (Visual command prompt):
LIB /REMOVE:obj_to_remove /OUT:removed.lib input.lib
To find out what obj to remove, first run:
DUMPBIN /ARCHIVEMEMBERS input.lib
You will see lines such as
Archive member name at 14286: /0 compilation.dir\objfile1.obj
14286 'identifies' the obj file. To see where each symbol is, run:
DUMPBIN /LINKERMEMBER:1 input.lib > members.txt
and look for the new/delete. members.txt will contains the mangled names of each symbols and an identifier of the obj in which this symbol is. For instance
14286 ?_Rank#?$_Arithmetic_traits#C#std##2HB
The 14286 is telling you the obj 'identifier' in which the symbol lies. If you have trouble finding new/delete, you can run:
DUMPBIN /SYMBOLS input.lib > sym.txt
which will flush into sym.txt the mangled and unmangled names for each symbol.
At the end, remove the obj file with the LIB command above by replacing obj_to_remove by compilation.dir\objfile1.obj in our example, and link against removed.lib.
Now, if you are not lucky, other symbols you need may be in the same object file as the new/delete. In that case, you can "hack" the lib using something like this (say renaming new to dew and delete to nelete.)
Can you place the memory manager's initialization out of main into a shared lib ?
If this is possible you could try forcing the initialization order of your libraries (by dependency) to load (and initialize) the memory manager before anything else is loaded. This is however a very brittle (or specific) solution since it'll be dependent on platform specific workarounds for forcing the order in which shared libs are initialized.
if overriding is done with a macro you may use
#pragma push_macro ("new")
#undef new
...code with standard new here ...
#pragma pop_macro ("new")
If it is really done by function override then you may temporarily construct a "new" macro yourself that calls a function with another name placed elsewhere which just calls the standard function.
Macros are resolved before function calls.
I am interested in using my static lib to create a dll (implicitly linking). which means I need to (in vs2008)
create a dll project that should generate the following:
header file (which have export function declarations. These are simple wrappers to actual functions in the static lib using __declspec(dllexport) which are in the .cpp )
import lib which will be made as a result of creating the dll
the actual dll which is created.
I have made a test program that will utilize the above dll(including the import lib/header files) to test it.
in this I have included all the three items. now the exe compiles/links without issue.
however in the main.cpp when i call the exported functions (with the associated __declspec(dllimport) call it never seems to execute. I am uncertain why this is?
Its almost like the even though the exe can see the exported function in in the dll...the dll cannot call on the code that is in the static lib?
i just cannot answer why my exe can't see the code in the static lib? do i need an archiver/librarian for vs2008 to include all those obj files as part of the import lib?
I am at a loss and am not sure how to test this?
other than just making my static lib directly into a dll. I wanted to try this method. I know i am missing something...i have read all over the place and i am just stuck. There were some threads here that had some people posting something similar but i can't seem to get it. please be as detailed as possible as I am new to this. thanks again.
update 1:
ok so currently i added the extern line to the function prototype and now it sees the exported function from the dll. however, now the only issue left is that:
i can't invoke the function that this exported function (aka wrapper) is trying to call. which happens to be in the static library. how should my exe get visibility to that static library function. I know it can be done because I think there was one other person on this board who was able to make this work.
update 2: my setup is exactly like this questioner...
How to force inclusion of an object file in a static library when linking into executable?
but i am not using explicit linking. i am using implicit linking. my real issue is how to call a static lib function in my dll wrapper which is exported to the exe?
If the app and DLLs are MFC app/dlls, then make sure that the application and all dlls are either "Debug" versions or "release" versions and not a mix.
So, I have an interesting issue. I am working with a proprietary set of dlls that I ,obviously, don't have the source for. The goal is to write an intermediate dll that groups together a large series of funnction calls from the proprietary dlls. The problem I am having, when compiling with g++, is that I get errors for the original dlls along the lines of:
cannot export libname_NULL_THUNK_DATA. Symbol not found.
If I add a main and just compile to an executable everything works as expected. I'm using mingw for compilation. Thanks for any help.
In response to the first reply: Either I'm confused about what you're saying or I didn't word my question very well. I'm not explicitly trying to export anything from my wrapper I am just calling functions from their dlls. The problem is that I get errors that it can't export these specific symbols from the dll to my wrapper. The issue is that I'm not even entirely sure what these _NULL_THUNK_DATA symbols are for. I did a search and read somewhere that they shouldn't be exported because they're internal symbols that windows uses. I have tried using the --exclude-symbols directive to the linker but it didn't seem to do anything. I apologize if I'm completely misunderstanding what you're trying to say.
So, I think my issue was related to this. When just compiling a standard executable that uses a dll I was able to include the headers and directly call the functions for example:
#include :3rdparty.h
int main(){
dostuff(); // a function in the 3rdparty.dll
}
this would compile and run fine. I just needed to link the libraries in the g++ command.
When linking with the -shared flag I would get these errors (with main removed of course). I think it has something to do with the fact that by default g++ attempts to import all symbols from the dll. What I didn't understand is why this happens in the dll vs in an executable. I will try doing it using GetProcAddress(). Thank you!
it should be as easy as you think it should be.
eg:
your dll code needs:
void doStuff()
{
3rdparty.login();
3rdparty.dostuff();
3rdparty.logoff();
};
so far - so good, you've included the right headers .... (if you have them, if you don't then you need to import the library using LoadLibrary(), then create a function pointer to each exported dll entrypoint using GetProcAddress() and then call that function pointer)
You then link with the 3rd party lib and that's it. Occasionally you will have to wrap the definitions with 'extern "C"' in order to get the linkage name mangling correct.
As you say you're using g++, you can't be getting confused with __declspec(dllimport) which is a MS VC extension.
"Compiling" tells me that you're approaching this from the wrong end. Your DLL should not export its own wrapper functions, but directly refer to exports from other DLLs.
E.g. in a Windows Kernel32.DEF file, the following forward exists:
EXPORTS
...
HeapAlloc = NTDLL.RtlAllocHeap
There's no code for the HeapAlloc function.