Initial commit.
This commit is contained in:
commit
cacea349d3
|
@ -0,0 +1,175 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
// Function definitions.
|
||||
void stack();
|
||||
void heap();
|
||||
void address();
|
||||
void sigHandler(int);
|
||||
|
||||
/*
|
||||
* Learned about these from:
|
||||
* https://linux.die.net/man/3/etext
|
||||
*/
|
||||
extern char etext, edata, end;
|
||||
|
||||
// Data variables.
|
||||
int UNINITIALIZED1;
|
||||
int INITIALIZED1 = 0;
|
||||
int INITIALIZED2 = 0;
|
||||
int INITIALIZED3 = 0;
|
||||
int UNINITIALIZED2;
|
||||
int UNINITIALIZED3;
|
||||
int UNINITIALIZED4;
|
||||
int INITIALIZED4 = 0;
|
||||
|
||||
/**
|
||||
* Main function for driving program.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
// Binding signal handler.
|
||||
signal(SIGINT, sigHandler);
|
||||
|
||||
/*
|
||||
* Getting addresses relating to static program segments
|
||||
* (See man page referenced above for sample code)
|
||||
*/
|
||||
printf("===\n");
|
||||
printf("First address past:\n");
|
||||
printf("Program text (etext) %10p\n", &etext);
|
||||
printf("Initialized data (edata) %10p\n", &edata);
|
||||
printf("Uninitialized data (end) %10p\n", &end);
|
||||
printf("===\n");
|
||||
|
||||
// Getting some initialized data addresses.
|
||||
printf("INITIALIZED\n");
|
||||
printf("1: %p\n", &INITIALIZED1);
|
||||
printf("2: %p\n", &INITIALIZED2);
|
||||
printf("3: %p\n", &INITIALIZED3);
|
||||
printf("4: %p\n", &INITIALIZED4);
|
||||
printf("===\n");
|
||||
|
||||
// Getting some unitialized data addresses.
|
||||
printf("UNINITIALIZED\n");
|
||||
printf("1: %p\n", &UNINITIALIZED1);
|
||||
printf("2: %p\n", &UNINITIALIZED2);
|
||||
printf("3: %p\n", &UNINITIALIZED3);
|
||||
printf("4: %p\n", &UNINITIALIZED4);
|
||||
printf("===\n");
|
||||
|
||||
// Adding some variables on the stack (will be stored in reverse).
|
||||
int stackvar1 = 12313;
|
||||
int stackvar2 = 12313;
|
||||
int stackvar3 = 12313;
|
||||
|
||||
// Main stack addresses.
|
||||
printf("Main Stack\n");
|
||||
printf("%p\n", &stackvar1);
|
||||
printf("%p\n", &stackvar2);
|
||||
printf("%p\n", &stackvar3);
|
||||
printf("===\n");
|
||||
|
||||
// Function stack addresses (should be lower than main).
|
||||
printf("Function Call Stack\n");
|
||||
stack();
|
||||
printf("===\n");
|
||||
|
||||
// Printing heap addresses.
|
||||
heap();
|
||||
|
||||
// Getting the address of the pow function.
|
||||
printf("Address of pow: %p\n", &pow);
|
||||
|
||||
// Getting the address of the pthread_create function.
|
||||
address();
|
||||
|
||||
// Pausing so we can examine headers / maps info.
|
||||
pause();
|
||||
|
||||
// Probably never will reach here, but bye if we do.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts some variables in the function's
|
||||
* stack frame and prints out their addresses.
|
||||
* Should be lower than main function's addresses,
|
||||
* although variables seem to increase in address
|
||||
* as we print them out (vars stored in reverse
|
||||
* order on the stack)
|
||||
*/
|
||||
void stack()
|
||||
{
|
||||
int stackvar1 = 12313;
|
||||
int stackvar2 = 12313;
|
||||
int stackvar3 = 12313;
|
||||
printf("%p\n", &stackvar1);
|
||||
printf("%p\n", &stackvar2);
|
||||
printf("%p\n", &stackvar3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for some heap space and prints out the
|
||||
* locations of the memory we receive.
|
||||
*/
|
||||
void heap()
|
||||
{
|
||||
printf("Heap\n");
|
||||
char *heap1 = malloc(16 * sizeof(char));
|
||||
char *heap2 = malloc(32 * sizeof(char));
|
||||
char *heap3 = malloc(64 * sizeof(char));
|
||||
char *heap4 = malloc(128 * sizeof(char));
|
||||
char *heap5 = malloc(256 * sizeof(char));
|
||||
char *heap6 = malloc(512 * sizeof(char));
|
||||
char *heap7 = malloc(1024 * sizeof(char));
|
||||
char *heap8 = malloc(2048 * sizeof(char));
|
||||
printf("1: %p\n", heap1);
|
||||
printf("2: %p\n", heap2);
|
||||
printf("3: %p\n", heap3);
|
||||
printf("4: %p\n", heap4);
|
||||
printf("5: %p\n", heap5);
|
||||
printf("6: %p\n", heap6);
|
||||
printf("7: %p\n", heap7);
|
||||
printf("8: %p\n", heap8);
|
||||
printf("===\n");
|
||||
|
||||
free(heap1);
|
||||
free(heap2);
|
||||
free(heap3);
|
||||
free(heap4);
|
||||
free(heap5);
|
||||
free(heap6);
|
||||
free(heap7);
|
||||
free(heap8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a function address from a dynamic library.
|
||||
*/
|
||||
void address()
|
||||
{
|
||||
printf("Address of pthread_create: %p\n", &pthread_create);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for signals. Bound for the one signal handled
|
||||
* in this application: SIGINT (program interrupt signal ^C).
|
||||
*
|
||||
* @param sigNum, the identifying number of the signal
|
||||
* sent and now being handled. According to the
|
||||
* man page for signal, SIGINT = 2.
|
||||
*/
|
||||
void sigHandler(int sigNum)
|
||||
{
|
||||
// Just exit if we ^C.
|
||||
if (sigNum == SIGINT)
|
||||
{
|
||||
// Exiting program.
|
||||
exit(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
The segments in the diagram below are organized from higher addresses to lower addresses.
|
||||
|
||||
| Location in Test Program Run | Segment | Direction of Growth |
|
||||
|:-:|:-:|:-:|
|
||||
| 0x7ffc1f885000 to 0x7ffc1f864000 | Stack | Grows ↓ |
|
||||
| 0x7fc7431f9000 to 0x7fc742e49000 | Shared C Libraries | Grows ↓ |
|
||||
| 0x55772bca6000 to 0x55772bc85000 | Heap / Runtime Data | Grows ↑ |
|
||||
| Ends at 0x55772a3aa090 | Uninitialized Data | N/A |
|
||||
| Ends at 0x55772a3aa068 | Initialized Data | N/A |
|
||||
| Ends at 0x55772a3a76f5 | Program Text | N/A |
|
Loading…
Reference in New Issue