Stack and Heap
Hey,
I would like to get a more thorough understanding of memory allocation and execution of my programs. I was wondering if there is any way of looking at what is contained on the stack and the heap for a program that i write using dev-c++? or any other tool for that matter?
Thanx
Dev-C++? So you're asking about Windows?
The NT_TIB structure contains the base address of the stack (top) as well as the current bottom (Win32 Thread Information Block, Under The Hood - MSJ, May 1996). You ought to be able to read contents of that range of addresses. To be on the safe side, check the pointers using IsBadRead (and friends) before dereferencing them.
Also look into the VirtualQuery function. You can use this to traverse the entire user space range of a process address space. That would be 0x00000000 to 0x7FFFFFFF. This includes the stack and the heap. The information returned by that function can help determine whether an address is valid or not as well.
The value returned by GetProcessHeap is the address where the default process heap begins. It's not the same a the CRT heap, but it's readable too.
And if you really want to get into the nuts and bolts of virtual memory under Windows, check out: Memory Management: What Every Driver Writer Needs to Know as well as the Intel IA32 Processor manuals.
The NT_TIB structure contains the base address of the stack (top) as well as the current bottom (Win32 Thread Information Block, Under The Hood - MSJ, May 1996). You ought to be able to read contents of that range of addresses. To be on the safe side, check the pointers using IsBadRead (and friends) before dereferencing them.
Also look into the VirtualQuery function. You can use this to traverse the entire user space range of a process address space. That would be 0x00000000 to 0x7FFFFFFF. This includes the stack and the heap. The information returned by that function can help determine whether an address is valid or not as well.
The value returned by GetProcessHeap is the address where the default process heap begins. It's not the same a the CRT heap, but it's readable too.
And if you really want to get into the nuts and bolts of virtual memory under Windows, check out: Memory Management: What Every Driver Writer Needs to Know as well as the Intel IA32 Processor manuals.
Sweet thanx man :D guess I got a bit of reading to do.
Was hoping for some sort of stack emulator thing but I guess I could make my own after reading all this stuff.
Was hoping for some sort of stack emulator thing but I guess I could make my own after reading all this stuff.
Why emulate when you can look at the real thing?
Using Dev-C++, you can use GDB to debug. GDB has the fine "x" command that lets you look at arbitrary addresses.
With MSVC, it's even easier (download the free version of MSVC++ Express if it's still available); the debugger has a scrollable, interactive Memory View window.
Just stop at a breakpoint and look to your hearts content!
Using Dev-C++, you can use GDB to debug. GDB has the fine "x" command that lets you look at arbitrary addresses.
With MSVC, it's even easier (download the free version of MSVC++ Express if it's still available); the debugger has a scrollable, interactive Memory View window.
Just stop at a breakpoint and look to your hearts content!
A debugger, perhaps? Never used any to step through at the source code level other than Visual Studio's, but if you have a passing knowledge of assembly (not really needed, to be honest) and how the stack works then almost any one would do - and with that in mind, I'd like to recommend OllyDbg.
EDIT: It's too late, and I'm too slow for these forums!
EDIT: It's too late, and I'm too slow for these forums!
I second the OllyDbg proposal. The amount of knowledge you can gain from debugging a single executable in OllyDbg is colossal. It strikes a perfect balance between user-friendliness and raw power - I wouldn't trade my Olly for anything.
That said, there really isn't much to memory allocation. Certainly not on a release build. A brief outline:
Stack: Local objects, Function parameters, Return addresses, SEH frames
.data Heap: Global & static variables, initialised variables
Extended Heap: Dynamically allocated objects
.rsrc: Resources
.bss: System-wide shared memory
Regards
Admiral
That said, there really isn't much to memory allocation. Certainly not on a release build. A brief outline:
Stack: Local objects, Function parameters, Return addresses, SEH frames
.data Heap: Global & static variables, initialised variables
Extended Heap: Dynamically allocated objects
.rsrc: Resources
.bss: System-wide shared memory
Regards
Admiral
Quote:To be on the safe side, check the pointers using IsBadRead (and friends) before dereferencing them.
Remember that IsBadXxxPtr should really be called CrashProgramRandomly. Poking around in the stack using it is very likely to cause the "hit a guard page" problem.
Quote:
Stack: Local objects, Function parameters, Return addresses, SEH frames
.data Heap: Global & static variables, initialised variables
Extended Heap: Dynamically allocated objects
.rsrc: Resources
.bss: System-wide shared memory
.data is not a heap, but a section of your executable file. You are correct in stating that it holds initialized global and static variables.
The .bss section contains your application's uninitialized (and, AFAIK, zero-initialized) global and static variables. It is not shared, but process-private. The reason it is separate from the .data section is that since the initial values of its contents are zero, they do not need to be stored explicitly within your executable.
Quote:Original post by bakery2k1Quote:To be on the safe side, check the pointers using IsBadRead (and friends) before dereferencing them.
Remember that IsBadXxxPtr should really be called CrashProgramRandomly. Poking around in the stack using it is very likely to cause the "hit a guard page" problem.
Interesting, and recent too September 27, 2006. Too bad MS let it ride for all those years...
Quote:Original post by bakery2k1
.data is not a heap, but a section of your executable file. You are correct in stating that it holds initialized global and static variables.
I'm fully aware of this, but in my experience, high-level programmers tend to lump everything into either 'stack' or 'heap'. Since this section is entirely dissociated from the stack, I figured it would be best to bend truth and throw it in with the heap storage. The .data section, of course, cannot grow dynamically and so it doesn't qualify as a heap, but it's treated in much the same way from the coder's perspective.
As for the .bss issue, it seems I had totally the wrong end of the stick. In my defense, no widely-used compilers have been known to create uninitialised data storage, and aren't likely to in future. I've never actually seen a .bss section [sad]. Nevertheless, I stand corrected.
I'm sure you'd have guessed this, but the bss section is zero-initialised, but only because ntdll's process-loading routines initialise memory to zero by default. Of course, this isn't part of the PE specification, and so it can't be relied on, so technically this section is indeed uninitialised.
Regards
Admiral
Quote:Original post by TheAdmiral
in my experience, high-level programmers tend to lump everything into either 'stack' or 'heap'
True, but I wish they wouldn't. "Name and describe the memory areas used by your program" seems to be quite a common job interview question and of course, the first time I was asked it, I got it wrong on this particular point.
Quote:
no widely-used compilers have been known to create uninitialised data storage, and aren't likely to in future.
Of course widely used compilers create .bss sections for uninitialized (or zero-initialized) variables. Consider the following code:
unsigned char array[0x1000000] = {0};int main(){ return 0;}
The resulting object file (and executable file) do not contain a 16MB chunk of zeros in their data section to represent "array". Rather, they contain an entry in their section header table stating that there is a 16MB BSS section, which is to be zero-initialised. Here is the output of objdump -h for the corresponding object file (compiled with gcc):
Sections:Idx Name Size VMA LMA File off Algn 0 .text 00000040 00000000 00000000 0000008c 2**4 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 00000000 00000000 00000000 2**4 ALLOC, LOAD, DATA 2 .bss 01000000 00000000 00000000 00000000 2**4 ALLOC
Here is the corresponding dump when compiled with MSVC:Sections:Idx Name Size VMA LMA File off Algn 0 .drectve 0000002a 00000000 00000000 000000b4 2**0 CONTENTS, READONLY, DEBUGGING, EXCLUDE 1 .debug$S 0000007e 00000000 00000000 000000de 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA, DEBUGGING 2 .bss 01000000 00000000 00000000 00000000 2**3 ALLOC 3 .text 00000007 00000000 00000000 0000015c 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE
Note that in the MSVC case, the .bss section is not actually present in the executable - I imagine it is merged with the .data section. Nontheless, this means that the data section contains both initialised and non- (zero-)initialised items.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement