Link to home
Start Free TrialLog in
Avatar of peparsons
peparsons

asked on

Debugging a C shared library used by a Tcl script

I'm trying to debug a shared library written in C and called by a Tcl script. (I know very little about Tcl & Tk.)

Can anybody please suggest how I can use a debugger to step through the C code in the shared library as it is executed?

It's a Solaris system and normally I use ddd & gdb to debug C programs.
ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of peparsons
peparsons

ASKER

I tried that, but the breakpoint didn't work.

i.e. I was able to identify the pid, attach to the process and set a breakpoint, but when I made it execute the code it didn't break.

I know this is the case because I added a printf to prove that it was going through the code where it should have hit the breakpoint.

Nice try though... :-)
Breakpoint did not work ... hmmm ...

1. Did you follow the process exactly as I mentioned? ... The sleep was long enough  etc ...

2. how did you compile the library ... I suspect that your library does not have debug information built into it and might be even stripped!!!
>  I'm trying to debug a shared library written in C
Do you have the source code for the "shared library"?

-ssnkumar
Yes, I have the source code.
And library is compiled with -g option?
And also make sure that the optimization (-O option in gcc) is switched off.

Will it be possible to show us the set of commands you are using to compile and then to debug?

-ssnkumar
In response to sunnycoder...

I didn't follow it exactly as you said, but I think I followed the spirit of it, as follows:
1. I ran the Tcl script, which displayed a dialog.
2. I ran ddd (which is just a gui front-end for gdb).
3. Using ddd, I did "File/Open Program..." and it gave me the option of loading the shared library.
4. Using ddd, I did "File/Attach to Process..." and I selected (from a list) the process that was the Tcl script.
5. Using ddd, I opened the source file where I wanted to put the breakpoint, and I created the breakpoint.
6. In ddd, I told the program to continue.
7. I then did things in the Tcl window to execute the code where I'd put the breakpoint. But it didn't break. I know it executed the code 'cos I did it again with a printf there and it did the printf.

As I write this, I realise that the library I opened in step 3 was the one in the local directory. But I think the Tcl script will have picked up the shared library using the LD_LIBRARY_PATH environment variable. It points to another (more central) directory. However, the one it will be using is a symbolic link to the local one. Perhaps that confused gdb. Maybe I should try that again.

Incidentally, although I have the source for all of this, I didn't write any of it and I have no access to documentation, the author(s) etc.
sounds good ... just make sure
1. The function of interest was not already executed by the time you set the break point ... i.e. it should be executed after Tcl dialogue
2. As you pointed out, you have the right library compiled with the right options
> I didn't follow it exactly as you said, but I think I followed the spirit of it, as follows:
Are you using -g option while compiling your code?
Is the -g option used for compiling the shared lib also?

Instead of using ddd, use gdb itself and try to put a breakpoint in the first line ("b 1" at gdb> prompt will do this)
Now run the code. If it is not stopping at line 1, then that means you have not used -g option during compilation.

Note that, without -g option, you will not be able to debug the code.

-ssnkumar
I wrote a make file to build the shared library.
It does something like this:

gcc -Wall -Dsun -Dsparc -Dsolaris -g -fpic -I. -Iinclude -I/usr/openwin/share/include -c mysrc1.c
gcc -Wall -Dsun -Dsparc -Dsolaris -g -fpic -I. -Iinclude -I/usr/openwin/share/include -c mysrc2.c
g++ -o libmylib.so -shared mysrc1.o mysrc2.o

So, it's not optimised or stripped.
And the source is compiled for debug.
Do I need to build the library with a -g too?)

To give you a bit more background, the Tcl allows a user to select a data file and passes its name to the C code which reads it in. So, I'm sure the C hasn't been executed before I set the breakpoint.

As a workaround, I've created another make file that builds an executable instead of a library and includes an extra file with a little main() function to call the function I'm interested in, passing the name of a file as its argument. I used that to debug it, but I'm still interested enough to try other ideas so that I understand how to do this properly.
> instead of a library and includes an extra file with a little main() function
So, your current code doesn't have main() and you haven't created the executable out of it!?

And by TCL do you mean the script that you have written using TCL?

-ssnkumar
>As a workaround, I've created another make file that builds an executable instead of a library and includes an extra file with a
>little main() function to call the function I'm interested in, passing the name of a file as its argument. I used that to debug it, but
>I'm still interested enough to try other ideas so that I understand how to do this properly.

Excellent thinking ... did you try running this executable through gdb?
> > instead of a library and includes an extra file with a little main() function
> So, your current code doesn't have main() and you haven't created the executable out of it!?
> And by TCL do you mean the script that you have written using TCL?

My original question said that I didn't really understand Tcl & Tk. Bearing that in mind I'll try to answer these questions...

The C code I have is a collection of files containing functions which compile separately into .o files. There is no main() function. The .o files are linked together to form a shared library. This is OK and it works.

I also have a collection of scripts which are written in a language called Tcl. I can execute one of these scripts just by typing its name. I think Solaris somehow knows it's a Tcl script and uses a program called "wish" to run it. In the scripts there are calls to functions which are found in the shared library. So, when I interect with the GUI displayed by the Tcl script, it causes functions in the C shared library to be called.

What I did as a workaround was to create a new file containing a main() function. I then created a new make file to build an executable rather than a shared library.

> did you try running this executable through gdb?
I then tried debugging that with ddd/gdb. It all worked fine and I found the problem I was looking for.

Hopefully that answers both your questions...
>> did you try running this executable through gdb?
>I then tried debugging that with ddd/gdb. It all worked fine and I found the problem I
>was looking for.
so the issue we were after is solved?
> so the issue we were after is solved?
Well... yes and no.

Yes - I've been able to debug the code I needed to debug.
but...
No - I still don't know how to debug a shared library called from a Tcl script file.

There are 2 things still to try:
1. Setting the -g when linking.
2. Ensuring that library in use is a file rather than a symbolic link to the library.

I'll have a go at those tomorrow, report back and award the points anyway.

Thanks for your help.
>There are 2 things still to try:
>1. Setting the -g when linking.
-g is for compilation only ... AFAIK it has no effect on linking

>2. Ensuring that library in use is a file rather than a symbolic link to the library.
This is something worth checking
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> Here is a link which might be of help:
http://www.donour.com/prof/mondo-pythonDC

I've had a look at this and although it's related, it's not really what I need.
Mondo seems to be a tool that displays the dynamic linking of a shared library in a format that's easier to understand than just a log file.
I think it also helps in debugging the scripts.
> I think it also helps in debugging the scripts.

It says it's for debugging but it's not a debugger in the sense that you can set breakpoints, continue etc.
Also, I had a look at sourceforge and nothing is released yet.

Nice try, but I think it's a blind alley for me.

I appreciate help from both of you but I think I need to call time on this now.
I split the points, but it doesn't seem to have done what I intended - probably finger trouble!
What I intended was that the accepted answer was the first one from sunnycoder (400 points)
and the assisted answer was the one near the end from ssnkumar about Mondo (100 points)
It seems to have put the accepted & assisted the other way wrong.
Can this be fixed please?
Ta.