Retrieving/Listing global variable info

I have been tasked with writing a program that will retrieve global variable information from a combination of c and c++ programs (compiled w/gcc).
I need to be able to get the variable names, types, and addresses for all defined global variables.

The only way I see that this can be done is to compile with debug info (gcc -g) and then to use a debugger such as gdb or dbx in batch mode to retrieve the information.
Is there a way to list all of the global variables by name in gdb or dbx?  

Also, if someone has another approach, suggestions are welcome...
The program needs to work in both cygwin and IRIX (both have gcc, gdb, and dbx available).


Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

consider using 'nm -g'

I don't believe gdb provides what you are looking for

Suppose you have compiled with debugging symbols...

objdump -t --demangle programNameHere |awk '{if ($2=="g"&&$3=="O"&&($4==".data" || $4==".bss")){print $0}}' |less

and include any other symbol types like  .rodata    that you might need to extract also

Objdump is part of binutils, but you may very well need a different strategy for each runtime

I don't have Cygwin or IRIX available, so I can't say what will happen exactly.. it may be better to try just
objdump -t

first,  then store the output of that in a file, and have your software process and filter the result listing

What are you REALLY trying to do?

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

For a release build, I guess you need to look at the map file, generated by the linker. The GNU linker ld has the -M option to output the map to stdout.
str8dnAuthor Commented:
Thanks for the suggestions.  I have been looking into nm, objdump, and ld, and I seem to be coming up short on documentation
other than the manual pages that are everywhere.  While man pages are helpful, they do not really let me know what I am
looking at for several of the tags/info output.  Is there something that lays these out?

The program I am writing is to take the list of global variables with their addresses, dimensions, and types, and pass them
to another program. The second program allows changes to be made to the values of the variables already in memory via PERL script.  

I have already written the second program (c++ and PERL to read/set values to/from memory).  The program that was passing me the
global variable info is majorly flawed and poorly written (not to mention it requires "dwarfdump", which is not readily
available on other systems), so I am redoing it.

The Binutil objdump appears to give me the variable names, dimensions and type with the following:
objdump --stabs --demangle -e a.exe

However, I am unsure of what I am really looking at with output such as:

622    GSYM   0      10     00000000 140134 tmp_testIntArray:G(1,9)=ar(11,7);0;3;(0,1)
tmp_testIntArray      /usr/include/c++/3.3.1/iostream      0;"      kind:v      type:int |[4]:uint32

The var tmp_testIntArray I set up, and I assume GSYM means it is a "global symbol".
It is an int arra with a single dim of 4 elements (from int [4]).

As for the rest of it, I am quite ignorant, save that uint32 probably means it is 32 bit.  Explanations appreciated.
I need to do a couple of things yet:
1. Identify its whereabouts in memory.
2. Identify which variable were defined in my files (since I am not really interested in all of the std:: and type definitions, etc.
  that are spit out along with my variables.)

Additinoal suggestions are welcome, and perhaps I have not given nm or ld enough of a look, objdump has been getting most of the attention.


What, exactly, are you trying to accomplish?

It sounds like you are writing a perl program that attempts to modify the values
of variables in a loaded, running application, based upon the un-fixedup offsets
in the unloaded image.  That would violate the memory protection mechanisms
of the OS.   Whenever someone asks me a request that seems quite strange, I
usually inquire as the the overall goal of the application.  So I ask, "What are
you really trying to accomplish?" (Not "how" you plan accomplish it.)  Perhaps
there is a better way to accomplish the goal.

str8dnAuthor Commented:
All of the memory manipulation is done via c++.  Perl talks to a c++ program and tells it which variables to give which values.
That way any violations are avoided.

We currently have a large number of c and c++ programs that use global variables as settings for a simulation.   Theses variables
are changed often enough that I have been requested to set up a shell through which changes can be made.

I have the memory manipulation and shell issues resolved.  What I need now is to be able pass the initial information for all of the
existing global variables to the shell.   In order to avoid compiling some type of master list, I want to be able to read this info directly
from the programs.  A master list would have to be constantly updated every time someone added a variable - highly undesirable.

For each global variable I need the following:
Address in memory

That sounds horrendous. I guess it's too late in the day to get yor developers to organise their variables?
This looks really awful.   It's not going to be easy to get the variable type info.

Could you do something just a TEENSY bit cleaner, like get the programs to register their variables if a command line parameter is passed?  Something like (in C ):

#define Register( Var, Type, Len )   \
     printf("Variable %s |  Type %s   | Length %d  | Address  %8x\n", "Var", "Type",  Len, &Var );

int main() {
if( option = 'r' ) {
    Register( NumberOfRubbersInMachine, int, 1 );
    Register( InitialCostPerItemPerDayOfWeek,  float, 7 );
    Register( ChartTitle, char, 80 );
    ... and so on for all the variables you want to be visible
   { mainprogram( argc, argv ); }


This would be almost infinitely cleaner than messing around with load maps.

The question is do you have that much "juice" to get others to do a TEENSY bit of work.

If that's too much work, you could write a little perl script, no more than 30 lines or so,
that would insert these lines for you.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
str8dnAuthor Commented:
Thanks for all of the comments, I learned a great deal from them.

After perusing the mess of information that debug makes me cull through, I believe that grg99's solution will be cleanest and
most portable.  I had considered something similar but thrown it out as too much hassle.  Thanks for helping me to see the

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.