LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 02-13-2005, 01:43 PM   #1
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Rep: Reputation: 15
Why does my C program lookup libraries on runtime?


I decided to create a neat little program out of boredom a few days ago. It works perfectly but whenever I run it, it produces weird output along with my own output. Every time a function call appears in my code, a line is sent to stdout that says that it is looking for the function in a file called libc.so.6 located in the directory /lib/tls. Here are two examples of what happens when I try to run my program:

Example 1: (my normal output is highlighted in dark red)

jarobman@linux:~/Documents> ./imessage samurai.jpg Hello World!
10603: symbol=strlen; lookup in file=./imessage
10603: symbol=strlen; lookup in file=/lib/tls/libc.so.6
10603: symbol=fgetc; lookup in file=./imessage
10603: symbol=fgetc; lookup in file=/lib/tls/libc.so.6
10603: symbol=printf; lookup in file=./imessage
10603: symbol=printf; lookup in file=/lib/tls/libc.so.6

ffd8
10603: symbol=fputc; lookup in file=./imessage
10603: symbol=fputc; lookup in file=/lib/tls/libc.so.6
10603: symbol=fclose; lookup in file=./imessage
10603: symbol=fclose; lookup in file=/lib/tls/libc.so.6
10603: symbol=free; lookup in file=./imessage
10603: symbol=free; lookup in file=/lib/tls/libc.so.6
10603: symbol=strlen; lookup in file=./imessage
10603: symbol=strlen; lookup in file=/lib/tls/libc.so.6

Filename: samurai.jpg
Message: Hello World! @


Example 2:

jarobman@linux:~/Documents> ./imessage samurai.jpg This is a message, fool!
11060: binding file ./imessage to /lib/tls/libc.so.6: normal symbol `strlen' [GLIBC_2.0]
11060: binding file ./imessage to /lib/tls/libc.so.6: normal symbol `fgetc' [GLIBC_2.0]
11060: binding file ./imessage to /lib/tls/libc.so.6: normal symbol `printf' [GLIBC_2.0]

ffd8
11060: binding file ./imessage to /lib/tls/libc.so.6: normal symbol `fputc' [GLIBC_2.0]
11060: binding file ./imessage to /lib/tls/libc.so.6: normal symbol `fclose' [GLIBC_2.1]
11060: binding file /lib/tls/libc.so.6 to /lib/tls/libc.so.6: normal symbol `free' [GLIBC_2.0]
11060: binding file /lib/tls/libc.so.6 to /lib/tls/libc.so.6: normal symbol `strlen' [GLIBC_2.0]

Filename: samurai.jpg
Message: This is a message, fool! @


Here is my code just in case: (This is a console program that accepts a JPEG file and either writes a message in in it [parameters after the file name] or retrieves an already placed message [no parameters after the file name])

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define SOI 0xffd8 //image header
#define EOI 0xffd9 //end of image marker
#define HEADER_SIZE 128 //number of bytes in jpeg header
#define MASK 0x6a //byte mask for encoding

int main(int argc, char *argv[])
{
	char *usage = "Usage: imessage jpeg_file [message]";
	char *msg;
	int i, in, out, len;
	unsigned short int chksoi;
	FILE *input;
	if (argc >= 3)
	{
		if ((input = fopen(argv[1], "r+")) != NULL)
		{
			for (i = 2; i < argc; i++)
			{
				msg = strcat(msg, argv[i]);
				msg = strcat(msg, " ");
			}
			msg = strcat(msg, "@");
			len = strlen(msg);
			in = fgetc(input);
			chksoi = in<<8;
			in = fgetc(input);
			chksoi |= in;
			//
			printf("%x\n", chksoi);
			//
			if (chksoi == SOI)
			{
				for(i = 2; i < HEADER_SIZE; i++)
				{
					in = fgetc(input);
				}
				for (i = 0; i < len; i++)
				{
					in = (msg[i] != '@') ? (int)msg[i]^MASK : (int)msg[i];
					out = fputc(in ,input);
				}
			}
			else
			{
				printf("Error: Invalid JPEG image\n");
			}
			fclose(input);
			printf("%s: %s\n", "Filename", argv[1]);
			printf("%s: %s\n", "Message", msg);
		}
		else
		{
			printf("%s %s %s\n", "Error: file", argv[1], "not found");
		}
	}
	else if (argc == 2)
	{
		if ((input = fopen(argv[1], "r")) != NULL)
		{
			in = fgetc(input);
			chksoi = in<<8;
			in = fgetc(input);
			chksoi |= in;
			//
			printf("%x\n", chksoi);
			//
			if (chksoi == SOI)
			{
				for (i = 2; i < HEADER_SIZE; i++)
				{
					in = fgetc(input);
				}
				printf("Message Received: ");
				while ((in = fgetc(input)) != '@')
				{
					putchar(in^MASK);
				}
				printf("\n");
			}
			else
			{
				printf("Error: Invalid JPEG image\n");
			}
			fclose(input);
		}
		else
		{
			printf("%s %s %s\n", "Error: file", argv[1], "not found");
		}
	}
	else
	{
		printf("%s\n", usage);
	}
	return 0;
}

Although my program works, I still could do without the ugly output. I have compiled my program with gcc version 3.3.3-41. I have no idea what the libc.so.6 file is and I don't know why it has to be searched through every time I call a C function. The main problem I have with this issue other that aesthetics is that this can cause a problem if I want to script my output to a file. Any solutions would be greatly appreciated. If I somehow, by a fluke, solve the problem myself, I will post the solution here for anyone having a similar problem.
 
Old 02-13-2005, 03:08 PM   #2
jailbait
Guru
 
Registered: Feb 2003
Location: Blue Ridge Mountain
Distribution: Debian Wheezy, Debian Jessie
Posts: 7,574

Rep: Reputation: 184Reputation: 184
"Every time a function call appears in my code, a line is sent to stdout that says that it is looking for the function in a file called libc.so.6 located in the directory /lib/tls."

"I have no idea what the libc.so.6 file is and I don't know why it has to be searched through every time I call a C function."

Every time you call a C function your program will go through libc.so.6. What is peculiar is that your program is logging calls to libc.so.6. Check the gcc command you used to compile this program to see if you have specified any debug options.

http://gcc.gnu.org/onlinedocs/gcc/De...ugging-Options

----------------------------
Steve Stites
 
Old 02-13-2005, 03:17 PM   #3
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
I have only used the following commands to compile my program:
gcc imessage.c -Wall -o imessage

-and-

gcc imessage.c -o imessage

It is a mystery to me why my program is logging calls to libc.so.6 because when it comes to compiling C programs, the above is as simple as it gets.
 
Old 02-13-2005, 03:18 PM   #4
crabboy
Moderator
 
Registered: Feb 2001
Location: Atlanta, GA
Distribution: Slackware
Posts: 1,823

Rep: Reputation: 120Reputation: 120
Does the file /lib/tls/libc.so.6 exist?

libc.so contains the all the basic c libraries that you compile into your code. Your program is using fgetc, strlen, printf and others. You can see the libraries that you program depends on by running:
Code:
ldd imessages
You will see /lib/tls/libc.so.6

Type the command:
Code:
locate libc.so.6
If that file does not exist, it may be picking up an older version of libc.so.6, but I'm not sure how. Look in your YaST configuration and see if all your programs and libraries are in good standing and you are not missing any depenedent pacakges.
 
Old 02-13-2005, 03:33 PM   #5
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
I just ran my program without typing in any parameters. The result is a call to printf with a string describing the usage of the program as a parameter. This call to printf does not cause a call to libc.so.6 to be logged! I noticed that this is the only case where my FILE struct is not assigned to a stream, so I'm tempted to think that that might be related to my overall problem. I will look into this issue some more for now...
 
Old 02-13-2005, 03:36 PM   #6
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
Quote:
Does the file /lib/tls/libc.so.6 exist?
Yes, the file does exist in my system in that exact location.
 
Old 02-13-2005, 04:26 PM   #7
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
I don't think my FILE stream has anything to do with my problem. I created the following program and it doesn't log calls to libc.so.6 at all:

Code:
#include <stdio.h>

int main(int argc, char *argv[])
{
	FILE *input;
	int i;
	
	input = fopen("samurai.jpg", "r+");
	for (i = 1; i < argc; i++)
	{
		printf("%s %c ", argv[i], fgetc(input));
	}
	fclose(input);
	printf("\n");
	return 0;
}
I do think that the problem might lie in my code; precisely in this section:
Code:
	if (argc >= 3)
	{
		if ((input = fopen(argv[1], "r+")) != NULL)
		{
			for (i = 2; i < argc; i++)
			{
				msg = strcat(msg, argv[i]);
				msg = strcat(msg, " ");
			}
			msg = strcat(msg, "@");
			len = strlen(msg); 
			in = fgetc(input);
			chksoi = in<<8;
			in = fgetc(input);
			chksoi |= in;
			//
			printf("%x\n", chksoi);
			//
			if (chksoi == SOI)
			{
				for(i = 2; i < HEADER_SIZE; i++)
				{
					in = fgetc(input);
				}
				for (i = 0; i < len; i++)
				{
					in = (msg[i] != '@') ? (int)msg[i]^MASK : (int)msg[i];
					out = fputc(in ,input);
				}
			}
			else
			{
				printf("Error: Invalid JPEG image\n");
			}
			fclose(input);
			printf("%s: %s\n", "Filename", argv[1]);
			printf("%s: %s\n", "Message", msg);
		}
		else
		{
			printf("%s %s %s\n", "Error: file", argv[1], "not found");
		}
	}
The lines in red are the ones that are responsible for making calls to libc.so.6. The weird thing about the output I decribed above is that it makes a call to libc.so.6 for the function free and an additional strlen function, both which are non-existant in my program (I only have one strlen function, but once a call to libc.so.6 is made, additional calls to the same function do not and should not result in additional calls to the library file). My theory is that my problem begins with the strlen function.
 
Old 02-13-2005, 05:02 PM   #8
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
You're somehow invoking LD_DEBUG.

Look here:

http://www.wlug.org.nz/LD_DEBUG

Try this:
set|grep LD
<= IF YOU'VE SOMEHOW SET "LD_DEBUG" IN YOUR ENVIRONMENT, PLEASE
TRY *UNSETTING* IT AND RE-RUN YOUR PROGRAM

'Hope that helps .. PSM
 
Old 02-13-2005, 07:01 PM   #9
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
I ran set|grep LD but that didn't change my situation. I am not sure how to change anything in my environment variables. The link you provided didn't tell me much about how to solve my problem. However, I now have a focus point towards the grand solution of my problem. Thanks.
 
Old 02-13-2005, 07:41 PM   #10
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,999
Blog Entries: 11

Rep: Reputation: 880Reputation: 880Reputation: 880Reputation: 880Reputation: 880Reputation: 880Reputation: 880
set | grep LD
wouldn't change the situation .... it would show you whether
LD_DEBUG is set or not ... that aside, do you compile the
program from a Makefile, and if so, did you "borrow" from
some other source, by any chance? Maybe the directive
is being invoked somewhere you haven't looked yet...



Cheers,
Tink
 
Old 02-14-2005, 04:42 PM   #11
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
I didn't compile from a makefile and I didn't borrow from another source. I made this program completely from scratch and as you can see from my code, I have only included three C standard libraries. I did similar operations in the test program that I wrote and the output was normal. I don't see anything unusual about my code that would cause this whole issue . It just doesn't make sense. If anyone can tell me how to change the LD_DEBUG_OUTPUT environment variable, please do. Thanks!
 
Old 02-14-2005, 05:13 PM   #12
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Not sure if this is the cause of your problem, but it is definitely a problem:

Code:
	char *msg;
	int i, in, out, len;
	unsigned short int chksoi;
	FILE *input;
	if (argc >= 3)
	{
		if ((input = fopen(argv[1], "r+")) != NULL)
		{
			for (i = 2; i < argc; i++)
			{
				msg = strcat(msg, argv[i]);
				msg = strcat(msg, " ");
			}
			msg = strcat(msg, "@");
Maybe I'm missing it, but I see nowhere that you are allocating memory for msg. Usually you will get a segfault from code like this, but perhaps it is overwriting some other memory space and inadvertently turning on the debug messages?
 
Old 02-14-2005, 05:41 PM   #13
jarobman
LQ Newbie
 
Registered: Jan 2005
Location: Manitoba, Canada
Distribution: SUSE Personal 9.1
Posts: 23

Original Poster
Rep: Reputation: 15
I don't think mallocs are required in this situation. What the string functions do is put data in some place in memory and I'm just assigning the pointer msg to that address. I haven't seen a single segmentation fault during the creation of my program so far.
 
Old 02-14-2005, 06:10 PM   #14
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
Quote:
DESCRIPTION
The strcat() function appends the src string to the dest string over-
writing the `\0' character at the end of dest, and then adds a termi-
nating `\0' character. The strings may not overlap, and the dest
string must have enough space for the result.
Quote:
RETURN VALUE
The strcat() and strncat() functions return a pointer to the resulting
string dest.
It's a common mistake. In general, libc functions don't do allocation for you because they don't know how you want to handle a failure.
 
Old 02-15-2005, 09:20 AM   #15
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Quote:
Originally posted by jarobman
What the string functions do is put data in some place in memory and I'm just assigning the pointer msg to that address.
Never assume anything about where memory is coming from. Whenever you have to use the phrase "some place in memory," you likely will have to allocate that memory yourself unless the documentation for the function explicitly states that it will allocate the memory.

As already stated, strcat just appends to the end of the pointer you give it, then returns that same pointer as a convenience. It does no memory allocation of its own.

Last edited by deiussum; 02-15-2005 at 09:21 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ runtime library compatibility with Redhat libraries srinatar Suse/Novell 2 01-30-2005 12:47 AM
C++ runtime library compatibility with Redhat libraries ( post #1) srinatar Fedora 1 01-30-2005 12:46 AM
Apache log hostname lookup program ? Carlee Linux - Software 1 01-29-2005 06:40 PM
java runtime() exec() program mcshen Programming 4 11-25-2004 12:29 PM
Runtime Program For Linux Red-Hat David@330 Linux - Newbie 6 10-22-2004 02:58 PM


All times are GMT -5. The time now is 09:47 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration