Calls the same shared library, but yields different result. Very strange!!!
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Calls the same shared library, but yields different result. Very strange!!!
First let's see the simple test code as follows:
------------- fn.c
#include <stdio.h>
int myfn()
{
printf("The myfn in main called\n");
return 8903;
}
#ifdef TEST1
//the function declared in shared library
extern void testmyfn();
#endif
int main()
{
#ifdef TEST2
//call shared library function with dlopen and dlsym
void *handle;
void (*fptr)();
/* open the needed object */
handle = dlopen("./libdll.so", RTLD_LOCAL | RTLD_NOW);
/* find the address of function and data objects */
*(void **)(&fptr) = dlsym(handle, "testmyfn");
/* invoke function */
(*fptr)();
#endif
printf("calling myfn in main function...\n");
printf("myfn = %d\n\n", myfn());
#ifdef TEST1
//directly call shared library function
testmyfn();
#endif
return 0;
------------------------fndll.c
#include <stdio.h>
//another myfn function with the same prototype as that in file fn.c
int myfn()
{
printf("The myfn in dll called\n");
return 1234;
}
void testmyfn()
{
int x = myfn(); //intend to call the myfn function in shared library. But
//actually the myfn function in fn.c might be called. ???
printf("Calling myfn in dll...\n");
printf("myfn = %d\n\n", x);
}
Compile fndll.c to produce libdll.so. Compile fn.c and main.c to produce main executable test1 or test2, depending the following two makefiles.
-----------------Makefile.test1
OBJ=test1
Execute test1, and I find that the call to myfn function in the testmyfn function in shared library actually calls the one in fn.c, but not the one in fndll.c. I am surprised.
Execute test2, and I find that the call to myfn function in the testmyfn function in shared library calls the one in fndll.c. It is what people usually expect.
use objdump to view the assembly language code of libdll.so. I find that the call instruction is very strange.
----------------------------------
00000544 <myfn>:
#include <stdio.h>
//#include <stdlib.h>
int myfn()
{
544: 55 push %ebp
545: 89 e5 mov %esp,%ebp
547: 83 ec 08 sub $0x8,%esp
printf("The myfn in dll called\n");
54a: 83 ec 0c sub $0xc,%esp
54d: 68 de 05 00 00 push $0x5de
552: e8 fc ff ff ff call 553 <myfn+0xf>
557: 83 c4 10 add $0x10,%esp
return 1234;
55a: b8 d2 04 00 00 mov $0x4d2,%eax
}
55f: c9 leave
560: c3 ret
00000561 <testmyfn>:
void testmyfn()
{
561: 55 push %ebp
562: 89 e5 mov %esp,%ebp
564: 83 ec 08 sub $0x8,%esp
int x = myfn();
567: e8 fc ff ff ff call 568 <testmyfn+0x7>
56c: 89 45 fc mov %eax,0xfffffffc(%ebp)
printf("Calling myfn in dll...\n");
56f: 83 ec 0c sub $0xc,%esp
572: 68 f6 05 00 00 push $0x5f6
577: e8 fc ff ff ff call 578 <testmyfn+0x17>
57c: 83 c4 10 add $0x10,%esp
printf("myfn = %d\n\n", x);
57f: 83 ec 08 sub $0x8,%esp
582: ff 75 fc pushl 0xfffffffc(%ebp)
585: 68 0e 06 00 00 push $0x60e
58a: e8 fc ff ff ff call 58b <testmyfn+0x2a>
58f: 83 c4 10 add $0x10,%esp
}
592: c9 leave
593: c3 ret
-----------------------------------------------------------
Look at this line.
567: e8 fc ff ff ff call 568 <testmyfn+0x7>
It corresponds to the call to myfn function. "e8" means Intel i386 call instruction. "fc ff ff ff" should means the relative address. Obviously, the relatvie address does not means the myfn function in both fn.c and fndll.c. I guess the instruction calls a glibc function, which does some job I still don't know.
Else, people who understand the shared library loading mechanism can give me some hints.
I cant get your code to run so I cant test this, so Ill just say that its probably those declarations at the start main.c. In the first test, the main is linked directly to the lib, so the linker is probably seeing the main's definition for the function first, and using that. In the second example, its not being linked, so the linker uses the definition found in the lib as it cant see inside the main.
I cant get your code to run so I cant test this, so Ill just say that its probably those declarations at the start main.c. In the first test, the main is linked directly to the lib, so the linker is probably seeing the main's definition for the function first, and using that. In the second example, its not being linked, so the linker uses the definition found in the lib as it cant see inside the main.
I cant get your code to run so I cant test this, so Ill just say that its probably those declarations at the start main.c. In the first test, the main is linked directly to the lib, so the linker is probably seeing the main's definition for the function first, and using that. In the second example, its not being linked, so the linker uses the definition found in the lib as it cant see inside the main.
I think the problem is not at link time, but at the time the shared library is being loaded.
You know, the shared library libdll.so is generated before test1. There is no chance that linker will link the myfn call in the shared library to the one in test1. Actually, I think the call to myfn function in shared library is relocated at the time the shared library is being loaded. Surprising, in test1, the call to myfn function in shared library is relocated to the first myfn function. In test2, the call is relocated to the second one. So I think the problem is the two different shared library loading mechanisms.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.