Just a simple ask:
The (gdb) info locals command gives the list of local variables and their values.
Are these values initialized values or point in time of execution of that frame?
Can you provide any documentation around this?
Are these values initialized values or point in time of execution of that frame?
The latter. Documentation says:
"These are all variables (declared either static or automatic) accessible
at the point of execution of the selected frame."
Related
"bt full" stack trace in GDB shows the locals in each of the frame. Does it always show values of the locals at the entry of the function or the updated value of the locals when "bt full" is executed?
It shows the values of variables at the current point in each frame.
The way this works is that a variable's debugging information carries a description of the variable's location. gdb evaluates this description, then fetches the value from the location. Now, this can be complicated (variables can be in registers at one spot and in memory at another; or structures on the stack can be broken into their constituent parts; etc) -- but in the simple case this is just some location on the stack. So, if the variable is assigned to, the old value is overwritten.
However, if you are using a new-enough gcc and a new-enough gdb, you can in some cases see entry values for function arguments. An entry value might look like var#entry = 72. This means that the compiler was able to tell the debugger how to compute the value-at-entry. This is normally done by unwinding one frame and evaluating a DWARF expression that says how to compute the value given the state in the calling frame.
Can someone tell me how to set OpenMP stack size to unlimited?
Like this link: Why Segmentation fault is happening in this openmp code?
I also have a project written by Fortran (customer‘s complex code), if I set OMP_STACKSIZE, the project is running normally. If I unset it, the project fails.
But, different input data have different OMP_STACKSIZE, so I must try it for each inputdata, (because I must save memory).
Can I set the OpenMP stack like pthread (ulimit -s unlimited)? Or have some way to set omp stack size dynamically?
I'm using RHEL 6.1, and the Intel compiler.
Thanks a lot!
There is big difference between how the stacks of the main thread and of the worker threads are implemented.
The "unlimited" stack of the main thread starts at the highest virtual address available in user mode and grows downwards until it meets the program break (the end of the data segment) or hits another memory allocation (either named or anonymous mapping) at which point the program crashes.
Any additional stacks have to be placed somewhere in memory between the program break and the bottom of the main stack. They cannot have an arbitrary extendible length since their initial placements (i.e. the distance between their beginnings) determines their maximum sizes (and vice versa - the specified maximum sizes determine their initial placement). This is the reason why the Linux implementation of pthread_create(3) (used by virtually all OpenMP runtimes in order to create new threads) states:
On Linux/x86-32, the default stack size for a new thread is 2 megabytes. Under the NPTL threading implementation, if the RLIMIT_STACK soft resource limit at the time the program started has any value other than "unlimited", then it determines the default stack size of new threads. Using pthread_attr_setstacksize(3), the stack size attribute can be explicitly set in the attr argument used to create a thread, in order to obtain a stack size other than the default.
In other words, the answer is no - you cannot specify unlimited stack size for threads other than the main one.
Please see the back trace below, I don´t think I have seen this before and I can not find any information in the documentation:
(gdb) bt
#0 0x000000007b44042c in Driver::setRec (this=0x1, message=#0x50)
I can't find it in documentation, but it looks like this is how gdb displays references to variables. According to backtrace, you were stopped at class method, accepting 1 parameter by reference with the following signature: Driver::setRec(message&).
Update:
It is not explicitly stated about # in C++ Expressions documentation. The only thing stated is:
In the parameter list shown when gdb displays a frame, the values of
reference variables are not displayed (unlike other variables); this
avoids clutter, since references are often used for large structures.
The address of a reference variable is always shown, unless you have
specified `set print address off'.
I dont know if this helps but from http://sources.redhat.com/gdb/download/onlinedocs/gdb.html#index-g_t_0040_0040_0040r_007b_002c-referencing-memory-as-an-array_007d-525
It is often useful to print out several successive objects of the same type in memory; a section of an array, or an array of dynamically determined size for which only a pointer exists in the program.
You can do this by referring to a contiguous span of memory as an artificial array, using the binary operator #'. The left operand of #' should be the first element of the desired array and be an individual object. The right operand should be the desired length of the array. The result is an array value whose elements are all of the type of the left argument. The first element is actually the left argument; the second element comes from bytes of memory immediately following those that hold the first element, and so on. Here is an example. If a program says
There for how I would interet this is 0x50 is a pointer address to the beginning of a string where the output message is. If I find more information on this I will update the post.
its for printing successive memory locations as array like output.
$gdb *memory#10
${1,2,3,4,5,6,7,8,9,10}
its a less powerful but easy to use memory inspection. if you want more power you should use the x (examine memory) command. consult
$info gdb
As mentioned in this tutorial:
http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/
In computer programming, a stack is a container that holds other
variables (much like an array). However, whereas an array lets you
access and modify elements in any order you wish, a stack is more
limited. The operations that can be performed on a stack are identical
to the ones above:
1) Look at the top item on the stack (usually done via a function
called top()) 2) Take the top item off of the stack (done via a
function called pop()) 3) Put a new item on top of the stack (done via
a function called push())
But if I defined two variables in C++ I do not have to use them in the same order of definition:
Example:
int main() {
int a;
int b;
b = 5;
a = 6;
}
Is there a problem on this code? I can use them in any order I like!! I do not have to use the a first then the b.
Am I misunderstanding something? What is it?
You are confusing two different kinds of stacks.
One stack, is where some of the memory for your application is allocated. This would be part of a discussion about the stack and heap and where your memory is allocated.
The other kind of stack is a data structure that conforms to a LIFO style of access. This could be implemented using a std::vector or other forms of data structures.
Yep, the "automatic storage" that holds a called method's local variables is allocated in a stack. But with the automatic storage stack you push and pop (variable sized) "stack frames" that contain all of the local variables for a method, not individual values.
This is conceptually similar to the kind of stack discussed in the article you quote, except that the items being pushed and popped are much larger.
In both cases the mechanism is "LIFO", since when you call a method you essentially return by "popping the stack" -- you always have to return from methods in the opposite order that you called them.
Am I misunderstanding something? What is it?
The "stack" that you're putting 'a' and 'b' on is (WARNING HUGE SIMPLIFICATIONS AND CONCEPTUALIZATIONS AHEAD) not made out of variables; it is made out of stack frames. A stack frame consists of the parameters to a function and a space for its return value, and sometimes also the variables used within the function (except that these can also be held in registers, and sometimes parameters are also passed via the registers). "Pushing" onto this stack is accomplished by calling a function. "Popping" from this stack is accomplished by returning from a function. You indeed only have access to the "top" element; you can't just read the variables of the function that called the current function, unless they were explicitly passed in as parameters.
Like any other data structure , stack is a data structure which follows LIFO(last in first out) principle.As mentioned in your question it does push and pop operation for inputting and retrieving data according to LIFO principle.
Every process consists of basically 4 portions of address space that are
accessible to the process
when it is running
Text - This portion contains the actual m/c instructions to be
executed. On many Operating Systems this is set to read only, so that the
process can't modify its instructions. This allows multiple instances of
the program to share the single copy of the text.
Data - This portion contains the program's data part. It furthere
divided into
1) Initialized Read Only Data - This contains the data elements
that are initialized by the program and they are read only during the
execution of the process.
2) Initialized Read Write Data - This contains the data elements
that are initialized by the program and will be modified in the course of
process execution.
3)Uninitalized Data - This contains the elements are not
initialized by the program and are set 0 before the processes executes.
These can also be modified and referred as BSS(Block Started Symbol). The
adv of such elements are, system doesn't have to allocate space in the
program file for this area, b'coz it is initialized to 0 by OS before the
process begins to execute.
Stack - This portion is used for local variables, stack frames
Heap - This portion contains the dynamically allocated memory
int abc = 1; ----> Initialized Read-Write Data
char *str; ----> BSS
const int i = 10; -----> Initialized Read-Only Data
main()
{
int ii,a=1,b=2,c; -----> Local Variables on
Stack
char *ptr;
ptr = malloc(4); ------> Allocated Memory in Heap
c= a+b; ------> Text
}
Data, store data
Text, store code
There are 3 (main?) segments/sections of the file produced by a linker.
text - program text (and apparently const char arrays. maybe other 'const' arrays, since those can not be changed anyway). I am not 100% sure about the array part, maybe
someone will correct me.
data - initialized global data. see examples below.
bss - uninitialized global data.
Here are some examples
int x = 1; /* goes into data */
int y; /* goes into bss */
const int z = 1;
this, we've seen go into 'text', since can't be changed anyway,but can be protected
const char array[] = {'a','b'....etc}
/* the rest goes into text */
int main(void)
{
return EXIT_SUCCESS;
}
Block Started by Symbol
(BSS) The uninitialised data segment produced by Unix linkers. The other segments are the "text" segment which contains the program code and the "data" segment contains
initialised data. Objects in the bss segment have only a name and a size but no value.
You don't have to use them in the order defined. But they are destroyed - taken off the stack- in that order. LIFO does not refer to access, only putting things on or taking them off the stack.
You can trivially observe this by changing int for a type which prints in it's destructor.
A stack is a standard data structure that's used all over the place. A thread's so called stack is in fact an implementation of this paradigm. There's a stack pointer (usually in a processor register) that points to a memory location. Data is 'pushed' onto this stack by moving the sp. We 'pop' by returning the value it points to and moving the sp the opposite direction.
As far as your a, b declared above it makes no difference. They're both allocated before they get used.
Stack program:
Your example program is not an implementation of stack. Stack shall store elements like an array (or by some means) where elements can be pushed (stored) or poped (pulled out) in LIFO (last in first out) order. It's implementation is not as simple as declaring two variables. Standard C++ provides stack class so that you can use it without having to implement on your own.
Stack Memory:
Variables in a function are stored in stack memory (Somewhere in the RAM) in LIFO order. From your example, Variable a will be created and pushed to stack memory. Then, the variable b is pushed to stack memory. After the function completes it's execution, the variables are destroyed in LIFO fashion. So variable b is the first to get destroyed and finally variable a gets destroyed. You don't write the code for it. The compiler takes care to write assembly low level code for it.
I have a question to clarify my confusion about the memory organization in computer in C++.
In C++, different data is put in different location. My understanding is like this.
1) data segment section, where global and static data are located;
2) heap section, the objects created by new
3) stack section, the local variable
4) text section, the code itself.
Is that right? Is there anything I missed or did wrong?
Thanks!
I wrote an article called "C++ Internals :: Memory Layout" which will clarify this for you.
Short excerpt from the article:
.text segment
It's a Read-Only, fixed-size segment.
The text segment, a.k.a. code segment, contains executable instructions provided by the compiler and assembler.
.data segment
It's a Read-Write, fixed-size segment.
The data segment, a.k.a. initialized data segment, contains initialized:
global variables (including global static variables)
static local variables.
The segment's size depends on the size of the values in the source code, the values can be altered at run-time.
.rdata/.rodata segment
It's a Read-Only segment
The segments contains static unnamed data (like string constants)
.bss segment
It's a Read-Write and adjacent to the .data segment.
BSS segment, a.k.a. uninitialized data segment, contains statically-allocated (global and static) variables represented solely by zero-valued bits on program start. BSS stands for Block Started by Symbol, a pseudo-operation that existed in a very old assembler developed for the IBM.
heap & stack
You are quite right about those. Anyway, if you want to check some examples and get a closer look, please, refer to mentioned article.
There are typically at least two data sections. One with initialized globals, another without (BSS). A stack section isn't typically emitted in the binary.
Of course, these kind of very implementation specific questions are kinda useless if you don't specify the implementation.