In this frame i cannot understand which line is for RBP and which line is for RIP - gdb

i am learning buffer overflow but could not identify which line is for RIP and RBP?
It will be very helpful if you describe me the whole frame , what for is each address, thank you.
0x7fffffffe010: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe020: 0x00000000 0x00000000 0x55555189 0x00005555
0x7fffffffe030: 0x00000000 0x00000001 0xffffe128 0x00007fff
0x7fffffffe040: 0x00000000 0x00000000 0x5bb6e43a 0x19c91c39
0x7fffffffe050: 0xffffe128 0x00007fff 0x55555189 0x00005555

Related

Why GCC 8/9/10 and GCC-7 behaves differently in calculating stack shift amount?

I am porting code to modern compilers and unfortunately encountered a subtle segmentation fault when an FFI function was invoked from Rust to C++.
The stacktrace showed that after the transition to C++, the first argument provided from Rust magically disappeared which misled C++ to use wrong arguments.
The code was somewhat private so I cannot post it here, but the assembly showed something interesting:
In GCC-7 (where the code runs without problem), the first several lines of assembly look like:
0x0000000000001119 <+0>: push rbp
0x000000000000111a <+1>: mov rbp,rsp
0x000000000000111d <+4>: push r13
0x000000000000111f <+6>: push r12
0x0000000000001121 <+8>: push rbx
0x0000000000001122 <+9>: sub rsp,0x128
0x0000000000001129 <+16>: mov QWORD PTR [rbp-0x118],rdi
0x0000000000001130 <+23>: mov rax,rsi
0x0000000000001133 <+26>: mov rsi,rdx
0x0000000000001136 <+29>: mov rdx,rsi
0x0000000000001139 <+32>: mov QWORD PTR [rbp-0x130],rax
0x0000000000001140 <+39>: mov QWORD PTR [rbp-0x128],rdx
0x0000000000001147 <+46>: mov QWORD PTR [rbp-0x120],rcx
0x000000000000114e <+53>: mov QWORD PTR [rbp-0x140],r8
0x0000000000001155 <+60>: mov QWORD PTR [rbp-0x138],r9
0x000000000000115c <+67>: lea rax,[rbp-0x110]
0x0000000000001163 <+74>: mov rdi,rax
0x0000000000001166 <+77>: call 0x116b
0x000000000000116b <+82>: mov rax,QWORD PTR [rbp-0x128]
0x0000000000001172 <+89>: mov edx,eax
0x0000000000001174 <+91>: mov rcx,QWORD PTR [rbp-0x130]
0x000000000000117b <+98>: lea rax,[rbp-0x110]
0x0000000000001182 <+105>: mov rsi,rcx
0x0000000000001185 <+108>: mov rdi,rax
0x0000000000001188 <+111>: call 0x118d
With GCC-8/9/10, however, the assembly becomes
0x0000000000001125 <+0>: push rbp
0x0000000000001126 <+1>: mov rbp,rsp
0x0000000000001129 <+4>: push r12
0x000000000000112b <+6>: push rbx
0x000000000000112c <+7>: sub rsp,0x120
0x0000000000001133 <+14>: mov QWORD PTR [rbp-0x108],rdi
0x000000000000113a <+21>: mov QWORD PTR [rbp-0x110],rsi
0x0000000000001141 <+28>: mov QWORD PTR [rbp-0x120],rdx
0x0000000000001148 <+35>: mov QWORD PTR [rbp-0x118],rcx
0x000000000000114f <+42>: mov QWORD PTR [rbp-0x128],r8
0x0000000000001156 <+49>: mov QWORD PTR [rbp-0x130],r9
0x000000000000115d <+56>: lea rax,[rbp-0x100]
0x0000000000001164 <+63>: mov rdi,rax
0x0000000000001167 <+66>: call 0x116c
0x000000000000116c <+71>: mov rax,QWORD PTR [rbp-0x118]
0x0000000000001173 <+78>: mov edx,eax
0x0000000000001175 <+80>: mov rcx,QWORD PTR [rbp-0x120]
0x000000000000117c <+87>: lea rax,[rbp-0x100]
0x0000000000001183 <+94>: mov rsi,rcx
0x0000000000001186 <+97>: mov rdi,rax
0x0000000000001189 <+100>: call 0x118e
So the logic is almost the same the shift amount is changed? I think the behavior is so strange.
The argument list is something like:
struct Opaque {
char _inner[0];
}
struct View {
char * base;
size_t len;
}
ReturnType ffi_function(Opaque*, View, uint64_t, View, uint64_t, uint64_t);
I also dumped the stack by x/-100xg $rbp
0x7fe7a67d41c0: 0x00007fe7a67d41f0 0x0000000014c1b1dc
0x7fe7a67d41d0: 0x000000000000003e 0x0000000000000006
0x7fe7a67d41e0: 0x00007fe7a67d4330 0x00007fe88714b540
0x7fe7a67d41f0: 0x0000000000201000 0x0000000013bd0df1
0x7fe7a67d4200: 0x0000000000000001 0x00007fe7a5e2f4e0
0x7fe7a67d4210: 0x000000000000003e 0x000000000000003b
0x7fe7a67d4220: 0x00007fe7a5e01080 0x00007ffebbd1ddb0
0x7fe7a67d4230: 0x000000001602ff80 0x0000000000000000
0x7fe7a67d4240: 0x0000000000000000 0x0000000000000000
0x7fe7a67d4250: 0x0000000000000000 0x0000000018d59680
0x7fe7a67d4260: 0x0000000018d59680 0x0000000000000000
0x7fe7a67d4270: 0x0000000000000000 0x0000000000000000
0x7fe7a67d4280: 0x00007fe700000000 0x0000000000000000
0x7fe7a67d4290: 0x00007fe7a5e2f4e0 0x00007fe88f1630ed
0x7fe7a67d42a0: 0x00007fe7a67d42f8 0x00007fe7a5e2f4e0
0x7fe7a67d42b0: 0x00007fe7a5e2f4e0 0x00007fe88f0d5f42
0x7fe7a67d42c0: 0x00007fe7a5e2f4e0 0x00007fe7a67d43f0
0x7fe7a67d42d0: 0x00007fe7a67d43f0 0x00007fe88f0ffa04
0x7fe7a67d42e0: 0x0000000000000001 0x0000000000000001
0x7fe7a67d42f0: 0x00007fe7a67d43f0 0x00007fe7a5e2f4e0
0x7fe7a67d4300: 0x00007fe7a5e2f4e0 0x0000000000000001
0x7fe7a67d4310: 0x00007fe7a67d43f0 0x00007fe88f0cf1cf
0x7fe7a67d4320: 0x0000000000000006 0x00007fe88714b540
Now, it seems that 0x00007ffebbd1ddb0 is the correct value for the first argument but C++ read it as 0x00007fe7a5e01080
update:
Right after the callq, before executing push %rbp:
This is what I have got from x/-100xg $rsp ($rsp = 0x7fff0b7d4338)
0x7fff0b7d4108: 0x00007fff0ae01080 0x000000000000003e
0x7fff0b7d4118: 0x0000003e00000060 0x00007fff0b7d4ab8
0x7fff0b7d4128: 0x00007fff0b7d4310 0x00007fff0b7d4310
0x7fff0b7d4138: 0x00007fff00000004 0x00007fff0b7d41b8
0x7fff0b7d4148: 0x00007fff0ae2f480 0x00007fff00000004
0x7fff0b7d4158: 0x00007fff0b7d41b8 0x00007fff0ae2f480
0x7fff0b7d4168: 0x0000000000000004 0x0000000000000000
0x7fff0b7d4178: 0x00007fff0b7d41b8 0x00007fff0ae2f498
0x7fff0b7d4188: 0x0000000000000000 0x00007fff0ae2f498
0x7fff0b7d4198: 0x00007ffff3d8219e 0x00007fff0b7d41b8
0x7fff0b7d41a8: 0x00007ffff3da157f 0x00007fff0ae01080
0x7fff0b7d41b8: 0x000000000000003e 0x000000000000003e
0x7fff0b7d41c8: 0x0000000000000002 0x000000000000003e
0x7fff0b7d41d8: 0x00007ffff5d4326d 0x00007fff0ae01080
0x7fff0b7d41e8: 0x000000000000003e 0x00007fff0b7d41b0
0x7fff0b7d41f8: 0x00007fff0ae01080 0x000000000000003e
0x7fff0b7d4208: 0x000000000000003e 0x0000000000000004
0x7fff0b7d4218: 0x00007fff0ae2f480 0x00007fff0ae2f498
0x7fff0b7d4228: 0x0000000000000004 0x00007fff0ae2f480
0x7fff0b7d4238: 0x00007fff0ae2f498 0x00007fff0ae2f480
0x7fff0b7d4248: 0x0000000000000004 0x0000000000000001
0x7fff0b7d4258: 0x00007fff0b7fe2a8 0x00007fff0ae2f480
0x7fff0b7d4268: 0x0000000000000004 0x00007fff0ae2f498
0x7fff0b7d4278: 0x00007fff0ae2f498 0x00007fff0ae2f4e0
0x7fff0b7d4288: 0x0000000000000000 0x00007fff0ae2f4e0
0x7fff0b7d4298: 0x00007ffff3e270ed 0x00007fff0b7d42f8
0x7fff0b7d42a8: 0x00007fff0ae2f4e0 0x00007fff0ae2f4e0
0x7fff0b7d42b8: 0x00007ffff3d99f42 0x00007fff0ae2f4e0
0x7fff0b7d42c8: 0x00007fff0b7d43f0 0x00007fff0b7d43f0
0x7fff0b7d42d8: 0x00007ffff3dc3a04 0x0000000000000001
0x7fff0b7d42e8: 0x0000000000000001 0x00007fff0b7d43f0
0x7fff0b7d42f8: 0x00007fff0ae2f4e0 0x00007fff0ae2f4e0
0x7fff0b7d4308: 0x0000000000000001 0x00007fff0b7d43f0
0x7fff0b7d4318: 0x00007ffff3d931cf 0x00007fff0ae2f4e0
0x7fff0b7d4328: 0x0000000000000001 0x00007fff0b7d43f0
and 100xg:
0x7fff0b7d4338: 0x00007ffff3dc42fe 0x0000000000000007
0x7fff0b7d4348: 0x0000000000000006 0x00007ffff637393e
0x7fff0b7d4358: 0x00007fff0ae2f480 0x00007fff0b7d4388
0x7fff0b7d4368: 0x00007fff0ae2f480 0x0000000000000060
0x7fff0b7d4378: 0x00007fff0ae01080 0x000000000000003e
0x7fff0b7d4388: 0x0000000000000001 0x00007fff0ae2f4e0
0x7fff0b7d4398: 0x000000000000003e 0x00007fff0ae01080
0x7fff0b7d43a8: 0x0000000013bd0d88 0x00007fffffffbfe0
0x7fff0b7d43b8: 0x00007fff0b7d4420 0x00007fffffffbfa8
0x7fff0b7d43c8: 0x00007fffffffbf50 0x00007fff0b7d4ab8
0x7fff0b7d43d8: 0x000000000000003b 0x0000000000000007
0x7fff0b7d43e8: 0x0000000000000006 0x00007fff0ae2f4e0
0x7fff0b7d43f8: 0x0000000000000004 0x0000000000000001
0x7fff0b7d4408: 0x00007fff0ae2f480 0x0000000000000004
0x7fff0b7d4418: 0x0000000000000001 0x00007fff0ae01080
0x7fff0b7d4428: 0x000000000000003e 0x000000000000003e
0x7fff0b7d4438: 0x00007fffffffbf50 0x00007fff0b7d4ab8
0x7fff0b7d4448: 0x000000000000003b 0x0000000000000007
0x7fff0b7d4458: 0x0000000000000006 0x00007fff0ae2f2a0
0x7fff0b7d4468: 0x000000000000003e 0x00007fff0ae01080
0x7fff0b7d4478: 0x000000000000003e 0x00007fff0ae2f4e0
0x7fff0b7d4488: 0x0000000000000001 0x00007fff0b7d45b0
0x7fff0b7d4498: 0x000001ff0ae2f2a0 0x00007fff0ae2f480
0x7fff0b7d44a8: 0x0000000000000000 0x00007ffff7bb2c60
0x7fff0b7d44b8: 0x00007ffff3daebc6 0x0000000000201000
0x7fff0b7d44c8: 0x0000000000000000 0x00007fffebd4f080
0x7fff0b7d44d8: 0x00007fff0ae2f2a0 0x000000000000003e
0x7fff0b7d44e8: 0x0100000000010301 0x00007fff0ae2f2a0
0x7fff0b7d44f8: 0x000000000000003e 0x000000000000003e
0x7fff0b7d4508: 0x00007fff0ae2f2a0 0x000000000000003e
0x7fff0b7d4518: 0x00007fff0ae2f2a0 0x000000000000003e
0x7fff0b7d4528: 0x00007fff0ae2f2a0 0x0000000060cc0baf
0x7fff0b7d4538: 0x00007fff0ae32180 0x00007fffffffbf50
0x7fff0b7d4548: 0x0000000000000000 0x00007fff0ae32240
0x7fff0b7d4558: 0x00007fff0ae32000 0x0000000000000006
0x7fff0b7d4568: 0x0000000000000007 0x000000000000003b
0x7fff0b7d4578: 0x00007fff0ae3e000 0x00007fff0b7d50b0
0x7fff0b7d4588: 0x00007fff0b7d50b0 0x00007fff0b7d4ab8
0x7fff0b7d4598: 0x00007fff0ae2f480 0x0000000000000004
0x7fff0b7d45a8: 0x0000000000000001 0x00007fff0ae32240
0x7fff0b7d45b8: 0x00007fff0ae32240 0x0000000000000000
0x7fff0b7d45c8: 0x00007fff0ae2f2a0 0x000000000000003e
0x7fff0b7d45d8: 0x0000000000000001 0x00007fff0ae2f480
0x7fff0b7d45e8: 0x0000000000000004 0x0000000000000001
0x7fff0b7d45f8: 0x0000000000000000 0x00007fff0ae3e000
0x7fff0b7d4608: 0x000000000000003b 0x0000000000000007
0x7fff0b7d4618: 0x0000000000000006 0x00007fffebda59d0
0x7fff0b7d4628: 0x00007ffff21bf5cd 0x00007fff0ae32180
0x7fff0b7d4638: 0x00007fff0ae32180 0x00007fff0ae32180
0x7fff0b7d4648: 0x0000000000000000 0x00007fff0b7d4858
The frame info of C++:
called by frame at 0x7fff0b7d44c0
source language c++.
Arglist at 0x7fff0b7d4330, args: server=0x7fff0ae2f498, region_buff=..., peer_id=62, snaps=..., index=62, term=140737324202302
Locals at 0x7fff0b7d4330, Previous frame's sp is 0x7fff0b7d4340
Saved registers:
rip at 0x7fff0b7d4338
expected first arg: 0x7fffffffbfe0
expected second arg: (0x7fff0ae01080, 0x3e)
expected third arg: 0x3b
expected 4th arg: (0x7fff0ae2f4e0, 1)
expected 5th, 6th arg: 7, 6
Newer GCC does one fewer push at the top of the function (saving one fewer call-preserved register). So it only needs to move RSP by an even multiple of 8 (0x120) to reach a 16-byte alignment boundary before the next call along with reserving enough space, not 0x128.
Both of these things change the distance between RBP and RSP, and thus the [RBP-0x130] offsets necessary to reach the space just above RSP to pass large structs by value on the stack.
I didn't check the math, but you can double-check yourself if you still think it's possible that GCC may have a correctness bug.
struct View only has two pointer-sized members. As such, the x86-64 System V ABI can pass it in a pair of registers.
And it has no constructors or destructors, or anything else, so the C++ ABI goes along with that. (I forget the exact rule used to decide whether an object must have an address and thus pass it on the stack. If your C++ vs. Rust code disagrees about that, it could lead to them disagreeing about how to pass it.)
Update since the problem did turn out to be a non-trivial struct:
GCC manual for the -fabi-version option:
Version 12, which first appeared in G++ 8, corrects the calling conventions for empty classes on the x86_64 target and for classes with only deleted copy/move constructors. It accidentally changes the calling convention for classes with a deleted copy constructor and a trivial move constructor.
Version 13, which first appeared in G++ 8.2, fixes the accidental change in version 12.
As such, the first 6 args (counting the structs as two args) will get passed in RDI, RSI, RDX, RCX, R8, R10 (in that order), with the rest on the stack. You can write a simple function to see where it looks for args:
int ffi_function(Opaque *server, View region_buf, uint64_t peer_id,
View snaps, uint64_t index, uint64_t term)
{
//return region_buf.len;
return region_buf.len - snaps.len + index;
}
GCC -Og -fverbose-asm makes the following asm, GCC11 on Godbolt:
ffi_function(Opaque*, View, unsigned long, View, unsigned long, unsigned long):
sub rdx, r9 # _3, tmp103
mov rax, rdx # _3, _3
add rax, QWORD PTR [rsp+8] # _3, index
ret
(You can see index is thus the first stack arg, right above the return address; the earlier ones are in registers. snaps.len is the last register arg, in R9.)
I guessed uint64_t as your ReturnType. If it's a struct larger than 2 registers, then you'll have a pointer to the return-value object as the first arg in RDI, and the other args bumped over by 1.
Your dump matches your expected args just fine. I reformatted it so I could add an annotation to each qword (8-byte) stack slot.
RSP:
0x7fff0b7d4338: 0x00007ffff3dc42fe (return addr)
0x0000000000000007 (expected 5th arg = 7)
0x0000000000000006 (expected 6th arg = 6)
0x00007ffff637393e (part of the caller's stack frame, not args)
...
The earlier args are all in registers.
If debug info isn't finding them perfectly, that's perhaps because you compiled with optimization; things get tricky and a callee might not keep a copy of its incoming args anywhere. Or even if not, getting debug info working right for this can be tricky.
sorry for my late reply. thanks again for #Peter Cordes.
The problem was finally located and addressed by one of my colleague.
it turns out that View was not defined purely trivial. A self defined ctor was added to the struct.
My colleague did twos things to fix the problem:
remove all ctors to keep the struct trivial
move all related ffi functions to extern C scope.
I haven't yet taken a look at the generated code but according to the report, the segfault has gone.
That is being said, I still think there may be something to think about carefully. If we follow the Itanium ABI strictly, one can see that View is still trivial for the purpose of call
and should be passed in the convention of C.
https://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial-parameters
So even though the original code was somewhat "messy", I think it can be used in FFI? (after all gcc-7 is doing good with that and -Wabi=11/12/13 didn't give any complaints to it).
Update:
checked the assembly just now. After the change, gcc-10 are generating exact the same code as gcc-7.

c++ Segmentation fault when do list.push_back(), correct on the host, error on the arm

Program received signal SIGSEGV, Segmentation fault.
0x400741e0 in std::_List_node_base::hook(std::_List_node_base*) ()
from /mnt/yaffs2/Cdatabox/lib/libstdc++.so.6
(gdb) bt
#0 0x400741e0 in std::_List_node_base::hook(std::_List_node_base*) ()
from /mnt/yaffs2/Cdatabox/lib/libstdc++.so.6
#1 0x00012df8 in std::list<std::list<Cbox::SteadyNode, std::allocator<Cbox::SteadyNode> >, std::allocator<std::list<Cbox::SteadyNode, std::allocator<Cbox::SteadyNode> > > >::_M_insert (this=0xbe9d1af0, __position=..., __x=...)
at /opt/arm-2008q3-linux/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/../../../../arm-none-linux-gnueabi/include/c++/4.3.2/bits/stl_list.h:1342
#2 0x00012e30 in std::list<std::list<Cbox::SteadyNode, std::allocator<Cbox::SteadyNode> >, std::allocator<std::list<Cbox::SteadyNode, std::allocator<Cbox::SteadyNode> > > >::push_back (this=0xbe9d1af0, __x=...)
at /opt/arm-2008q3-linux/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/../../../../arm-none-linux-gnueabi/include/c++/4.3.2/bits/stl_list.h:876
#3 0x0000d508 in Cbox::SteadyAnalysis::__dealSteady (this=0xbe9d1a98)
at ../include/class/SteadyAnalysis.h:237
#4 0x0000dc7c in Cbox::SteadyAnalysis::input (this=0xbe9d1a98,
weight=1467031, rawTime=1552067705)
at ../include/class/SteadyAnalysis.h:110
#5 0x0000deb4 in main (argc=2, argv=0xbe9d1d74) at SteadyAnalysis.cc:30
(gdb) disassemble
Dump of assembler code for function _ZNSt15_List_node_base4hookEPS_:
0x400741d0 <+0>: ldr r3, [r1, #4]
0x400741d4 <+4>: stm r0, {r1, r3}
0x400741d8 <+8>: ldr r2, [r1, #4]
0x400741dc <+12>: str r0, [r1, #4]
=> 0x400741e0 <+16>: str r0, [r2]
0x400741e4 <+20>: bx lr
End of assembler dump.
(gdb) i r
r0 0x31220 201248
r1 0xbe9d1af0 3197967088
r2 0x46 70
r3 0x46 70
r4 0xbe9d1a98 3197967000
r5 0x40dd4c00 1088244736
r6 0x4136629f 1094083231
r7 0x1e400000 507510784
r8 0x41d720ab 1104617643
r9 0x0 0
r10 0x31d20 204064
r11 0xbe9d1944 3197966660
r12 0x30a58 199256
sp 0xbe9d1928 0xbe9d1928
lr 0x12df8 77304
pc 0x400741e0 0x400741e0 <std::_List_node_base::hook(std::_List_node_base*)+16>
cpsr 0x60000010 1610612752
(gdb)
code:
//Type declaration
struct SteadyNode {
double mean;
int duration;
int startLine;
time_t startDetectedRawTime;
time_t endDetectedRawTime;
};
//Definition info
//list<SteadyNode>::iterator upIt, downIt;
//list<SteadyNode> steadyNodeList;
//list<list<SteadyNode> > sleepPiceList;
{
steadyNodeList.back().endDetectedRawTime = currentRawTime;
SteadyNode last = steadyNodeList.back();
if (onBedFlag == 1)
{
downIt = steadyNodeList.end();
list<SteadyNode> onBedMeanList;
onBedMeanList.splice(onBedMeanList.begin(), steadyNodeList, upIt, downIt);
steadyNodeList.clear();
steadyNodeList.push_back(last);
sleepPiceList.push_back(onBedMeanList); //<=== crash position
onBedMeanList.clear();
onBedFlag = -1;
}
else
{
steadyNodeList.clear();
steadyNodeList.push_back(last);
}
}
There is only one source code.
When I compiled successfully on the debian9 host, valgrind --leak-check=full tested no memory leaks and the program executed correctly.
On the arm platform, the compilation was successful, but the program got this error when it was executed. I hope to get everyone's help, thank you.
Solved.
Those gdb print info is not major problem.
For gcc4.4 and gcc4.3, STL list will not pre alloc element when you write code like list<DiyClass>, but in gcc6.3 will. That is why the same code can run well in gcc6.3 but segment fault in gcc4.3.
I guess some low level implements is different between diff gcc version. if someone know detail reason, give a answer, thanks.

Stack content for g++4.8

I have written this simple piece of code for testing buffer overflow:
#include <stdio.h>
#include <string.h>
using namespace std;
int f(int x, int y, char *s){
char buf[4];
strcpy(buf,s);
return 0;
}
int main(int argc, char** argv){
f(2,3,argv[1]);
return 0;
}
Then compiling and viewing its execution with gdb (g++ 4.8.4)
g++ -g -fno-stack-protector -o bo bo.c
gdb bo
...
b f
r "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
p $rbp // 0x7fffffffdc90
p $rsp // 0x7fffffffdc70
x/20xw $rsp
0x7fffffffdc70: 0xffffe0ef 0x00007fff 0x00000003 0x00000002
0x7fffffffdc80: 0xffffdcb0 0x00007fff 0x00000000 0x00000000
0x7fffffffdc90: 0xffffdcb0 0x00007fff 0x00400585 0x00000000
0x7fffffffdca0: 0xffffdd98 0x00007fff 0x00000000 0x00000002
0x7fffffffdcb0: 0x00000000 0x00000000 0xf7a36ec5 0x00007fff
My understanding is that the stack grows downward to lower addresses, but it looks this stack frame (from 0x7fffffffdc90 - 0x7fffffffdc90) is growing upward: the parameters are pushed upward (s, y then x). Why is that?
Looks like the return address (0x00400585) is pushed first. But what are the meanings of subsequent words? Are they:
Saved $rbp$?
What are the next 2 words?
To see what happens to your stack after the call of f, call disassembler in gdb:
(gdb) disas
Dump of assembler code for function f(int, int, char*):
0x000000000040052d <+0>: push %rbp
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x20,%rsp
0x0000000000400535 <+8>: mov %edi,-0x14(%rbp)
0x0000000000400538 <+11>: mov %esi,-0x18(%rbp)
0x000000000040053b <+14>: mov %rdx,-0x20(%rbp)
0x000000000040053f <+18>: mov -0x20(%rbp),%rdx
0x0000000000400543 <+22>: lea -0x10(%rbp),%rax
0x0000000000400547 <+26>: mov %rdx,%rsi
0x000000000040054a <+29>: mov %rax,%rdi
=> 0x000000000040054d <+32>: callq 0x400410 <strcpy#plt>
0x0000000000400552 <+37>: mov $0x0,%eax
0x0000000000400557 <+42>: leaveq
0x0000000000400558 <+43>: retq
Before the call to strcpy the stack looks like (I use 64bit formating rather than 32bit):
(gdb) x/6xg $rsp
0x7fffffffddb0: 0x00007fffffffe297 0x0000000200000003
0x7fffffffddc0: 0x00007fffffffddf0 0x0000000000000000
0x7fffffffddd0: 0x00007fffffffddf0 0x0000000000400585
So you can see:
0x0000000000400585 - return address of the function f.
right next to it 0x00007fffffffddf0 - pushed on the stack by 0x000000000040052d <+0>: push %rbp
the next 4 values were reserved on stack via
0x0000000000400531 <+4>: sub $0x20,%rsp
you can see parameters 2 and 3 being saved on the stack prior to the call of the strcpy (0x0000000200000003- because ints are only 4 byte long).
You can also deduce other values on the stack from the disassembly.
The top of the stack is at the beginning (address 0x7fffffffddb0) and the addresses get bigger (e.g. 0x7fffffffddd0 for the third line) so you can see the stack really grows downwards but is shown upside down by gdb.

What is the fastest way to find where an address is mapped in GDB?

Currently I manually go through the list of memory mappings in info proc mappings to see in what range the address falls in. Isn't there an easier way?
(gdb) i proc map
process 23912
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x601000 0x6ce000 0xcd000 0x0 [heap]
0x7fffe6d65000 0x7fffe6d67000 0x2000 0x0 /usr/lib64/libXau.so.6.0.0
0x7fffe6d67000 0x7fffe6f67000 0x200000 0x2000 /usr/lib64/libXau.so.6.0.0
0x7fffe6f67000 0x7fffe6f68000 0x1000 0x2000 /usr/lib64/libXau.so.6.0.0
0x7fffe6f68000 0x7fffe6f69000 0x1000 0x3000 /usr/lib64/libXau.so.6.0.0
0x7fffe6f69000 0x7fffe6f89000 0x20000 0x0 /usr/lib64/libxcb.so.1.1.0
0x7fffe6f89000 0x7fffe7188000 0x1ff000 0x20000 /usr/lib64/libxcb.so.1.1.0
0x7fffe7188000 0x7fffe7189000 0x1000 0x1f000 /usr/lib64/libxcb.so.1.1.0
0x7fffe7189000 0x7fffe718a000 0x1000 0x20000 /usr/lib64/libxcb.so.1.1.0
0x7fffe718a000 0x7fffe718c000 0x2000 0x0 /usr/lib64/libXss.so.1.0.0
0x7fffe718c000 0x7fffe738c000 0x200000 0x2000 /usr/lib64/libXss.so.1.0.0
0x7fffe738c000 0x7fffe738d000 0x1000 0x2000 /usr/lib64/libXss.so.1.0.0
0x7fffe738d000 0x7fffe738e000 0x1000 0x3000 /usr/lib64/libXss.so.1.0.0
...
You want info sym. Here it is from different frames in the stack of a simple program:
(gdb) info sym $pc
_fxstat + 20 in section .text of /lib64/libc.so.6
or
(gdb) info sym $pc
std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) + 422 in section .text of /lib64/libstdc++.so.6
or
(gdb) info sym $pc
main + 25 in section .text of /tmp/q

core dump with same pattern

My application crashes once in a while and generates coredump.
Each time stack is different. But each time when it dumps, i find that one of the pointer will be corrupt. and each time first 4 bytes of pointer value will be 0X100 (256). By this i can make out that this dump is because of memory corruption. But i have no idea as how to proceed. I ran all the static tools on the code. But i cant really attach valgrind (I have no access to site)
#0 0x00002b5775455738 in _STL::_List_base<int, _STL::allocator<int> >::clear (this=0x2b576debd408) at /home/enipcore/core/add-ons/include/stlport/stl/_list.c:72
72 in /home/xxxx/core/add-ons/include/stlport/stl/_list.c
(gdb) info locals
__tmp = 0x10084a957f0
__cur = 0x10084a957f0
(gdb)
I will share the info which i have, Pls suggest me how to proceed. I really do not know what info to give here. If any one want me to run any command and get memory print i can share.
(gdb) p &__tmp
$13 = (_STL::_List_node<int> **) 0x2b577b70e4b8
(gdb)
Registers, eax will have this wrong value
$13 = (_STL::_List_node<int> **) 0x2b577b70e4b8
(gdb) i r
rax 0x10084a957f0 1101737318384
rbx 0x2b5771e1fccb 47654572784843
rcx 0x2b576e1251d0 47654508843472
rdx 0x85 133
rsi 0x2b571729eee8 47653050773224
rdi 0x2b576debd408 47654506320904
rbp 0x2b577b70e4c0 0x2b577b70e4c0
rsp 0x2b577b70e4a0 0x2b577b70e4a0
r8 0x2b576d176480 47654492398720
r9 0x7bbe 31678
r10 0x2b5774f0a5e0 47654624077280
r11 0x2b57165c3f80 47653037293440
r12 0x2b577b716e68 47654733180520
r13 0x0 0
r14 0x2b57188221e0 47653073330656
r15 0x2b577b716e68 47654733180520
rip 0x2b5775455738 0x2b5775455738 <_STL::_List_base<int, _STL::allocator<int> >::clear()+40>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
fctrl 0x37f 895
fstat 0x0 0
ftag 0xffff 65535
fiseg 0x0 0
fioff 0x0 0
foseg 0x0 0
fooff 0x0 0
fop 0x0 0
mxcsr 0x1fa0 [ PE IM DM ZM OM UM PM ]
(gdb)
Some memory dump.
(gdb) x/20a 0x2b577b70e4b8 -20
0x2b577b70e4a4: 0x6debd40800002b57 0x84a957f000002b57
0x2b577b70e4b4: 0x84a957f000000100 0x7b70e4e000000100
0x2b577b70e4c4: 0x754557fb00002b57 0x7b70e55000002b57
0x2b577b70e4d4: 0x6debd40800002b57 0x7b70e50000002b57
0x2b577b70e4e4: 0x7545583100002b57 0x7b716e6800002b57
0x2b577b70e4f4: 0x6debd40800002b57 0x7b70e55000002b57
0x2b577b70e504: 0x75451de100002b57 0x6de161a000002b57
0x2b577b70e514: 0x100002b57 0x6debd40800000000
0x2b577b70e524: 0x6debd3c800002b57 0x2b57
0x2b577b70e534: 0x167f860800000000 0x71e1fccb00002b57