LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 05-06-2013, 03:38 AM   #1
webquinty
Member
 
Registered: Apr 2008
Location: España
Distribution: Suse
Posts: 210

Rep: Reputation: 32
static local vars doubt.....


Hello,

I have two functions and both has a static local var....

Code:
void comm_tk_init(void)
{
static UINT prueba;

	prueba = 1;
}


void comm_tk_cyclic(void)
{
static UINT prueba;

	prueba = 0;
}
Now, I check address of each var..

Code:
john@linux-2sn9:~/workspace/Applications/QT_template> nm -f sysv QT_template
prueba.3188         |08068748|   d  |            OBJECT|00000002|   
prueba.3192         |0806874a|   d  |            OBJECT|00000002|
Code:
< 1><0x000000a4>    DW_TAG_subprogram
                      DW_AT_external              yes(1)
                      DW_AT_name                  comm_tk_init
                      DW_AT_decl_file             0x00000001 TaskClass1/comm_tk.c
                      DW_AT_decl_line             0x00000013
                      DW_AT_prototyped            yes(1)
                      DW_AT_low_pc                0x0804d998
                      DW_AT_high_pc               0x0804d9ad
                      DW_AT_frame_base            <loclist with 3 entries follows>
			[ 0]<lowpc=0x00000000><highpc=0x00000001>DW_OP_breg4+4
			[ 1]<lowpc=0x00000001><highpc=0x00000003>DW_OP_breg4+8
			[ 2]<lowpc=0x00000003><highpc=0x00000015>DW_OP_breg5+8
                      DW_AT_sibling               <0x000000cf>
< 2><0x000000bd>      DW_TAG_variable
                        DW_AT_name                  prueba
                        DW_AT_decl_file             0x00000001 TaskClass1/comm_tk.c
                        DW_AT_decl_line             0x00000014
                        DW_AT_type                  <0x00000065>
                        DW_AT_location              DW_OP_addr 0x08068748
< 1><0x000000cf>    DW_TAG_subprogram
                      DW_AT_external              yes(1)
                      DW_AT_name                  comm_tk_cyclic
                      DW_AT_decl_file             0x00000001 TaskClass1/comm_tk.c
                      DW_AT_decl_line             0x00000020
                      DW_AT_prototyped            yes(1)
                      DW_AT_low_pc                0x0804d9ad
                      DW_AT_high_pc               0x0804d9bb
                      DW_AT_frame_base            <loclist with 3 entries follows>
			[ 0]<lowpc=0x00000015><highpc=0x00000016>DW_OP_breg4+4
			[ 1]<lowpc=0x00000016><highpc=0x00000018>DW_OP_breg4+8
			[ 2]<lowpc=0x00000018><highpc=0x00000023>DW_OP_breg5+8
                      DW_AT_sibling               <0x000000fa>
< 2><0x000000e8>      DW_TAG_variable
                        DW_AT_name                  prueba
                        DW_AT_decl_file             0x00000001 TaskClass1/comm_tk.c
                        DW_AT_decl_line             0x00000021
                        DW_AT_type                  <0x00000065>
                        DW_AT_location              DW_OP_addr 0x0806874a
Now, How can I know that Variable belongs to its function?
I suppose that gcc add that number but what is the criteria?

Best regards.

Last edited by webquinty; 05-06-2013 at 08:05 AM.
 
Old 05-06-2013, 03:58 AM   #2
pan64
Senior Member
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 4,508

Rep: Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221
I do not think there is an "official" way for it, because those vars are local and access is not allowed from outside. So you need to find the function itself, disassemble and you will find the address of the given local variable
 
Old 05-06-2013, 04:01 AM   #3
mina86
Member
 
Registered: Aug 2008
Distribution: Slackware
Posts: 354

Rep: Reputation: 148Reputation: 148
Quote:
Originally Posted by webquinty View Post
Now, How can I know that Variable belongs to its function?
Strictly speaking, static “local” variables do not belong to anyone, but since they are defined inside a function, their scope is function's body, which means that they can be accessed (by name) only inside the function.

Short answer to your question is: you cannot. Why would you even need that? What is a problem you are trying to solve?
 
1 members found this post helpful.
Old 05-06-2013, 04:23 AM   #4
webquinty
Member
 
Registered: Apr 2008
Location: España
Distribution: Suse
Posts: 210

Original Poster
Rep: Reputation: 32
Hello,
Thank you for fast answers.

Well, I have developed a function that if I give it a name of var, it return me address, type and length of var using GDB/MI. With global variables, it works fine.
Now, I am interesting in use the same function with local vars, but with static local variables I cannot give the name because gdb return me error "No symbol "prueba" in current context" and it is normal.

But if you use other nomenclature...
Quote:
(gdb) p &comm_tk_init:rueba
$3 = (UINT *) 0x8068748 <prueba.3188>
GDB return me correct information.

I'm looking for a relationship between the function and the name of the variable, but understand that your response will be somewhat difficult.
 
Old 05-06-2013, 04:26 AM   #5
pan64
Senior Member
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 4,508

Rep: Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221
no, it is not difficult at all. I think there is no logical relationship, so those numbers (pointers) are more or less random-like ones.
 
Old 05-06-2013, 04:42 AM   #6
webquinty
Member
 
Registered: Apr 2008
Location: España
Distribution: Suse
Posts: 210

Original Poster
Rep: Reputation: 32
So, in few words....

prueba.3188 --> comm_tk_init:rueba
prueba.3192 --> comm_tk_cyclic:rueba

any advice.

Last edited by webquinty; 05-06-2013 at 04:44 AM.
 
Old 05-06-2013, 04:58 AM   #7
pan64
Senior Member
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 4,508

Rep: Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221
Why do you need that? Probably the variables counted and that is the result or that is something like "distance" in bytes from somewhere....
 
Old 05-06-2013, 07:57 AM   #8
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,052

Rep: Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101
First you should understand there are two different kinds of information that gcc puts in the object code for those symbols.

It puts in information needed by the linker to build the correct binary. That is the information you have looked at. In that kind of information, the size of each of those symbols is indicated, but the scope is not (the linker decides on the address). As others indicated, the info for the function indicates how to find the variable, but the info for the variable has no need to point back to the scope.

There is also optional debugging info, that is transformed by the linker into the information used by gdb. The kind of information you want is in that debugging info. I don't recall what commands you use to get readable information from the debugging info in an object file.

Last edited by johnsfine; 05-06-2013 at 08:01 AM.
 
Old 05-06-2013, 08:58 AM   #9
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,267

Rep: Reputation: 1086Reputation: 1086Reputation: 1086Reputation: 1086Reputation: 1086Reputation: 1086Reputation: 1086Reputation: 1086
Exactly.

local is a scope, or if you will visibility modifier. The variable-name is visible only to the local context in which it is defined. A static variable that is local will also be a unique instance ... if two separate subroutines define a local variable named x, it will be a distinct variable whether-or-not it is static.

static causes a single unique memory address to be assigned to that variable, and for the lifetime of that address to be the lifetime of the program.

A function is free to divulge the address of one of its local static variables if it wishes to do so, thereby giving anyone else access to it by means of a pointer or indirect reference.

The runtime debugger acts on memory-address based information, and, in the particular situation that you are describing, it can indeed be confusing although it is correct.
 
Old 05-06-2013, 09:23 AM   #10
webquinty
Member
 
Registered: Apr 2008
Location: España
Distribution: Suse
Posts: 210

Original Poster
Rep: Reputation: 32
Hi,

well, I understood all post.

local is a scope and if I declare a variable as static in two different functions with the same name, both variables are different and it has own address memory.

But my questions is:
Can I looking for debug information of this vars????
How can I detect that Variable belongs to its function????

prueba.3188 --> variable prueba in comm_tk_init function.
prueba.3192 --> variable prueba in comm_tk_cyclic function.

is it possible to obtain this information with any debug tool like gdb for example?
Note: I dont know the struct of program.

with "nm" tool.....
Quote:
prueba.3188 |08068748| d | OBJECT|00000002|
prueba.3192 |0806874a| d | OBJECT|00000002|
second step: how to know that Variable belongs to its function????

Best regards.
 
Old 05-07-2013, 12:22 AM   #11
pan64
Senior Member
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 4,508

Rep: Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221Reputation: 1221
No, you still not understand. Scope works on the language level, I mean you will use it inside the c/c++ code to define accessibility. The compiler checks it and will throw and error in case of a violation (syntax rules). That is the first task what a compiler must do.
The following phases will translate to code to binary, will collect all the variables (probably some optimization will happen) and will construct a result file (lib, app, whatever). Here you do not need/have scope at all, and also using direct memory access you can reach whatever you want. In this level you have only pointers to different parts of the memory...
 
Old 05-07-2013, 07:53 AM   #12
mina86
Member
 
Registered: Aug 2008
Distribution: Slackware
Posts: 354

Rep: Reputation: 148Reputation: 148
Quote:
Originally Posted by pan64 View Post
In this level you have only pointers to different parts of the memory...
However, with debug symbols it should be able to get from the pointer back to the variable, and I'm guessing that's what OP is asking about.
 
Old 05-07-2013, 08:30 AM   #13
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,052

Rep: Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101Reputation: 1101
I'm far from expert in this stuff, but I tried creating a .c file similar to what the OP described, then compiling (gcc -g -c ...) to create a .o file with debug info. Then I used readelf -w to dump out the debug info from the .o file.

It is very verbose, with lots of content (such as from the include files) that I don't really understand.

But searching for the repeated variable name, it was easy to find a (DW_TAG_variable) section in the output for each of them. Then searching backward in the output from that DW_TAG_variable section, I could find the next earlier (DW_TAG_subprogram) section, which appears to give the scope of the variable. So I can infer the basic rules.

I also put another static variable of the same name at module scope (outside of any subprogram) and was surprised to see its DW_TAG_variable at the end of the output with nothing that I understand telling me it is not part of the next earlier DW_TAG_subprogram.

So there is more complexity than I can deduce with a quick test. Maybe there is enough complexity that studying the source code of readelf would be required.

But close to what the OP wants can be achieved by parsing the output of readelf. It would be better (though I'm not sure whether harder or easier) to do the same by calling the same functions that readelf calls. That is part of the beauty of open source.

Edit: I wasn't looking at the obvious. Each section of that output starts with a level number in <>. So the variables in subprogram scope each start with <2> so you know to look backward for the next earlier <1> to get their scope. The static variable at module scope has its section start with <1> so you know there is no outer scope. The file is also identified. There is a DW_AT_external entry in the global sections to distinguish a <1> meaning global from a <1> meaning file scope.

Edit2: After figuring all that out, I looked again at the output the OP showed in the first post. When I first saw that, I knew neither where the OP got that output, nor what it meant. But I see it is nearly the same as what I got from readelf -w including the key fact (that may be the whole answer to the OP's question) that the level numbers <1> and <2> combined with the sequence in which those sections appears, tells you the way the scopes nest.

Last edited by johnsfine; 05-07-2013 at 08:50 AM.
 
Old 05-07-2013, 09:10 AM   #14
webquinty
Member
 
Registered: Apr 2008
Location: España
Distribution: Suse
Posts: 210

Original Poster
Rep: Reputation: 32
Hello johnsfine,

Thank you.
Yes, you are right. With dwarf, is clear ( more or less ) how to find variables.

I would like to make the same with GDB but it is more complex.

Best regards.
 
Old 05-07-2013, 12:42 PM   #15
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,396

Rep: Reputation: 814Reputation: 814Reputation: 814Reputation: 814Reputation: 814Reputation: 814Reputation: 814
Maybe gdb's info scope command is what you need:
Code:
% gdb comm_tk
GNU gdb (GDB) 7.4.1-debian
[...snip...]
Reading symbols from /home/npostavs/tmp/comm_tk...done.
(gdb) info functions
All defined functions:

File comm_tk.c:
void comm_tk_cyclic(void);
void comm_tk_init(void);
int main();

Non-debugging symbols:
0x0000000000400370  _init
[...snip...]
(gdb) info scope comm_tk_cyclic
Scope for comm_tk_cyclic:
Symbol prueba is in static storage at address 0x6008f4, length 4.
(gdb) info scope comm_tk_init
Scope for comm_tk_init:
Symbol prueba is in static storage at address 0x6008f8, length 4.
 
  


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
Exporting vars in a script (Local KDE installation) AphoxemaG Linux - General 3 01-21-2007 04:52 PM
Configuring local host to have Static IP logosys Linux - Networking 2 03-02-2006 01:20 AM
Static Local IP for Azureus and Samba techlover Linux - Networking 0 12-16-2005 01:05 AM
setting up radvd with static local ips pIscIs Linux - Networking 0 12-13-2005 03:48 PM
static local ip assignment??? dslboy Linux - Networking 1 08-29-2004 03:16 PM


All times are GMT -5. The time now is 06:19 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