Memory management routines ANSI C routines

advertisement
Gerard C. Weatherby
Memory management routines
• ANSI C / C++ routines
• Win32 Virtual memory
• Win32 Heap
• Unix memory functions
Computer Operating Systems
Memory.1
Gerard C. Weatherby
ANSI C routines
• malloc - raw block of memory (aligned for any use)
void *malloc(size_t size);
int *varray = (int *)malloc(100*sizeof(int));
Returns null if memory not allocated
• calloc - array allocation
void *calloc(size_t num, size_t size)
similiar to: malloc(num * size)
memory is zero-filled
• free - release memory
void free(void *mem)
free(varray)
Must free memory to avoid memory leaks. Unused memory
Computer Operating Systems
Memory.2
Gerard C. Weatherby
not being returned to the operating system.
Note: free(NULL) or free(0) is a safe no-operation
free(x) where “x” is not a value returned from a call to malloc, calloc, or realloc is undefined.
Undefined - language standard does not specify
what will happen...
...but it won’t be good. (most often a program
crash)
• realloc - reallocate previous allocated memory
void *realloc(void *previous,size_t newsize)
int *valarray = (int *)realloc(valarray,200 * sizeof(int));
May expand or reduce size of allocated block.
Memory in smaller of old size and new size unchanged.
Computer Operating Systems
Memory.3
Gerard C. Weatherby
Return address may be different from original (block of
memory may be moved and copied)
More likely to be different if new size greater than previous
Returns null if insufficient memory available.
• alloca - variable allocation off runtime stack
void *alloca(size_t size)
void stackAllocate(int size) {
//char block[size];// error C2057: expected constant expression
char * block = (char *)alloca(size * sizeof(char));
exception (Win32) or undefined (Solaris) if insufficient stack
space
freed automatically when function returns
Computer Operating Systems
Memory.4
Gerard C. Weatherby
Memory alignment
• malloc, et. al. return “bytes suitably aligned for any use”
• certain hardware can only process numbers which have specific addresses.
Sparc two-byte quantities should be stored at even locations,
word quantities should be stored at addresses which are
multiples of four.
• Crashes on Solaris:
char memory[13];
double *d = (double *)&memory[2];
*d = 1.234;
Works fine on Win32
Computer Operating Systems
Memory.5
Gerard C. Weatherby
C++ Memory routines
• new - allocates memory for specified type
C++ keyword
semid_ds *buf = new semid_ds;
Note returned pointer is of appropriate type (no cast
required)
For a user defined type (class), special code called constructor automatically executed.
A class may also define a specialized memory allocation routine, a new operator, to provide raw memory
set_new_handler function can be used to customized behavior if insufficient memory behavior
by default, null returned or C++ exception thrown
Computer Operating Systems
Memory.6
Gerard C. Weatherby
• new[] - array new; allocates an array of objects. Constructor
called for each object.
int *array = new int[100]
• delete - releases memory allocated by new.
delete(buf);
A class may define a special function called a destructor
which is automatically executed when object deleted.
• delete[] - release memory allocated by new[]
Must match new/delete and new[]/delete[] calls
Computer Operating Systems
Memory.7
Gerard C. Weatherby
Win32 Virtual Memory
• A set of APIs allow more direct control over memory allocation.
Increased performance
Keeping related data together on nearby pages
Telling operating system to stop swapping pages
(you don’t care about data anymore)
Prohibit operating system from swapping pages
(lock into physical memory)
Set memory to read-only (protect against program errors, security)
Direct mapping of hardware addresses
e.g. Writing a device driver
Computer Operating Systems
Memory.8
Gerard C. Weatherby
• Virtual Alloc - allocate memory
LPVOID VirtualAlloc(
LPVOID lpAddress, // address of region to reserve or commit
DWORD dwSize,
// size of region
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
allocation type:
MEM_COMMIT - allocate
MEM_RESERVE - don’t use for anything else
(not actually allocated)
MEM_RESET - stop maintaining values
MEM_TOP_DOWN - get highest possible address
Computer Operating Systems
Memory.9
Gerard C. Weatherby
protection type:
PAGE_READONLY
PAGE_READWRITE
PAGE_EXECUTE
PAGE_EXECUTE_READ
PAGE_EXECUTE_READWRITE
PAGE_GUARD
PAGE_NOACCESS
PAGE_NOCACHE
Computer Operating Systems
Memory.10
Gerard C. Weatherby
• VirtualFree - release memory
BOOL VirtualFree(
LPVOID lpAddress, // address of region of committed pages
DWORD dwSize,
// size of region
DWORD dwFreeType); // type of free operation
where free type can be
MEM_DECOMMIT
MEM_FREE
• VirtualLock - lock committed memory (keep from swapping)
BOOL VirtualLock(
LPVOID lpAddress, // address of first byte of range to lock
DWORD dwSize );
// number of bytes in range to lock
Maximum of 30 unless changed with SetWorkingSetSize
Computer Operating Systems
Memory.11
Gerard C. Weatherby
• VirtualUnlock - unlocks locked memory
BOOL VirtualUnlock(
LPVOID lpAddress, // address of first byte of range
DWORD dwSize
// number of bytes in range
);
• SetProcessWorkingSetSize - sets number of pages to hold in
physical memory
BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
// handle to the process of interest
DWORD dwMinimumWorkingSetSize, // specifies minimum working set size
DWORD dwMaximumWorkingSetSize // specifies maximum working set size
);
Goal, not a guarantee
Requires appropriate system privileges (Administrator /
Power User)
Computer Operating Systems
Memory.12
Gerard C. Weatherby
• Virtual Protect - change protection level of memory
BOOL VirtualProtect(
LPVOID lpAddress, // address of region of committed pages
DWORD dwSize,
// size of the region
DWORD flNewProtect, // desired access protection
PDWORD lpflOldProtect ); // address of variable to get old protection
DWORD oldProtect;
if (VirtualProtect(myAddress,2000,PAGE_READONLY,&oldProtect))...
options for protect fields same as VirtualAlloc
• Virtual Query - return information about memory range
DWORD VirtualQuery(
LPCVOID lpAddress,
// address of region
PMEMORY_BASIC_INFORMATION lpBuffer, // address of information buffer
DWORD dwLength );
// size of buffer
MEMORY_BASIC_INFORMATION meminfo;
VirtualQuery(memory,&meminfo,sizeof(meminfo));
Computer Operating Systems
Memory.13
Gerard C. Weatherby
MEMORY_BASIC_INFORMATION is defined as:
typedef struct _MEMORY_BASIC_INFORMATION { // mbi
PVOID BaseAddress;
// base address of region
PVOID AllocationBase;
// allocation base address
DWORD AllocationProtect;
DWORD RegionSize;
DWORD State;
// initial access protection
// size, in bytes, of region
// committed, reserved, free
DWORD Protect;
// current access protection
DWORD Type;
// type of pages
} MEMORY_BASIC_INFORMATION;
Type options are image (return from MapDebugInformation), memory mapped, or private
Computer Operating Systems
Memory.14
Gerard C. Weatherby
• GetSystemInfo - returns processor memory information
VOID GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);
SYSTEM_INFO info;
GetSystemInfo(&info);
typedef struct _SYSTEM_INFO {
union { DWORD dwOemId; //obsolete
struct { WORD wProcessorArchitecture; //INTEL, ALPHA, MIPS, PPC
WORD wReserved;
};
};
DWORD dwPageSize; //e.g. 4096 on NT
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD dwActiveProcessorMask; //bit map of active processors
DWORD dwNumberOfProcessors;
DWORD dwProcessorType; //386/486/Pentium -- obsolete
DWORD dwAllocationGranularity; //e.g. 64K
WORD wProcessorLevel;
WORD wProcessorRevision; } SYSTEM_INFO;
Computer Operating Systems
Memory.15
Gerard C. Weatherby
• GlobalMemoryStatus - system’s current physical and virtual
memory usage
VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer );
MEMORYSTATUS mstat;
GlobalMemoryStatus(&mstat);
typedef struct _MEMORYSTATUS {
DWORD dwLength;
// sizeof(MEMORYSTATUS)
DWORD dwMemoryLoad;
// percent of memory in use
DWORD dwTotalPhys;
// bytes of physical memory
DWORD dwAvailPhys;
// free physical memory bytes
DWORD dwTotalPageFile; // bytes of paging file
DWORD dwAvailPageFile; // free bytes of paging file
DWORD dwTotalVirtual; // user bytes of address space
DWORD dwAvailVirtual; // free user bytes
} MEMORYSTATUS, *LPMEMORYSTATUS;
Computer Operating Systems
Memory.16
Gerard C. Weatherby
Virtual memory in other processes
• Previous functions all work in current process
• Variants available to operate in other processes
Have additional process handle argument
• Require appropriate permission
VirtualAllocEx
VirtualFreeEx
VirtualProtectEx
VirtualQueryEx
Computer Operating Systems
Memory.17
Gerard C. Weatherby
• Example program
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winbase.h>
#include <assert.h>
#include <iostream.h>
const char * decodeProtect(DWORD); //implementation omitted (see web)
const char * decodeState(DWORD);
const char * decodeType(DWORD);
int main( )
{
//find lowest valid address
SYSTEM_INFO info;
GetSystemInfo(&info);
void * address = info.lpMinimumApplicationAddress;
//allocate read write memory
const int length = 100;
Computer Operating Systems
Memory.18
Gerard C. Weatherby
int * memory = static_cast<int *>(
VirtualAlloc(address,
length *sizeof(int),
MEM_COMMIT,
PAGE_READWRITE));
assert(memory);
cout << "allocate request " << address << endl;
cout << "allocate return " << memory << endl;
//build table of squares
for (int i=0;i<length;i++)
memory[i] = i * i;
//protect memory
DWORD oldProtect;
const BOOL protect = VirtualProtect(memory,length*sizeof(int),
PAGE_READONLY,&oldProtect);
assert(protect);
assert(oldProtect == PAGE_READWRITE);
for (int x=5;x<10;x++)
cout << x << " squared: " << memory[x] << endl;
Computer Operating Systems
Memory.19
Gerard C. Weatherby
__try {
//attempt to change memory
cout << "Attempt to write to memory" << endl;
memory[10] = 3;
//never actually executes...
cout << "10 value is " << memory[10] << endl;
}
__except(EXCEPTION_EXECUTE_HANDLER) { cout << "Write failed" <<
endl; }
MEMORY_BASIC_INFORMATION meminfo;
VirtualQuery(memory,&meminfo,sizeof(meminfo));
cout << "base address " << meminfo.BaseAddress << endl;
cout << "allocation address " <<meminfo.AllocationBase << endl;
cout << "region size " << meminfo.RegionSize << endl;
cout << "initial protection " << decodeProtect(meminfo.AllocationProtect) <<
endl;
cout << "current protection " << decodeProtect(meminfo.Protect) << endl;
cout << "state " << decodeState(meminfo.State) << endl;
cout << "type " << decodeType(meminfo.Type) << endl; }
Computer Operating Systems
Memory.20
Gerard C. Weatherby
• Sample output:
allocate request 0x00010000
allocate return 0x00010000
5 squared: 25
6 squared: 36
7 squared: 49
8 squared: 64
9 squared: 81
Attempt to write to memory
Write failed
base address 0x00010000
allocation address 0x00010000
region size 4096
initial protection PAGE_READWRITE
current protection PAGE_READONLY
state MEM_COMMIT
type MEM_PRIVATE
Computer Operating Systems
Memory.21
Gerard C. Weatherby
Windows Heap functions
• malloc/free new/delete operate using a default heap
• Can explicitly operate on a heap
Performance: give each thread its own heap and avoid concurrency checking
Simplicity: create complex memory structures in a dedicated heap. Delete entire heap instead of invidual pointers.
• Following flags are used by several routines
HEAP_GENERATE_EXCEPTIONS - allocation failure
raises operating system exception instead of returning null
HEAP_NO_SERIALIZE - no concurrency checks
HEAP_ZERO_MEMORY - self-explanatory
Computer Operating Systems
Memory.22
Gerard C. Weatherby
• GetProcessHeap - access the default heap
HANDLE GetProcessHeap( );
• HeapCreate - create a new heap
HANDLE HeapCreate(
DWORD flOptions, (exceptions, no serialize)
DWORD dwInitialSize, // initial heap size
DWORD dwMaximumSize); // maximum heap size, (0 for unlimited)
Note: sizes are rounded up to nearest page size
• HeapAlloc - allocate memory from a heap
LPVOID HeapAlloc(
HANDLE hHeap, // handle to heap
DWORD dwFlags, // control flags (exceptions, no serialize, zero memory)
DWORD dwBytes); // number of bytes to allocate
Computer Operating Systems
Memory.23
Gerard C. Weatherby
• HeapReAlloc - reallocate memory
LPVOID HeapReAlloc(
HANDLE hHeap, // handle to heap
DWORD dwFlags, // control flags (exceptions, no serialize, zero memory)
LPVOID lpMem, // pointer to the memory to reallocate
DWORD dwBytes );// number of bytes to reallocate
• HeapFree - release memory
BOOL HeapFree(
HANDLE hHeap, // handle to heap
DWORD dwFlags, // no serialize or 0
LPVOID lpMem // pointer to the memory to free
);
• HeapDestroy - release entire heap
BOOL HeapDestroy(
HANDLE hHeap); // handle to the heap returned from HeapCreate
Computer Operating Systems
Memory.24
Gerard C. Weatherby
• Additonial heap functions
HeapValidate - check integrity of a heap
HeapWalk - step through allocations of a heap
HeapCompact - try to make free blocks bigger
HeapLock - calling thread attempts to gain exclusive access
to heap
HeapUnlock - release lock
HeapSize - get size of heap
Computer Operating Systems
Memory.25
Gerard C. Weatherby
UNIX memory control
memcntl - memory management control
int memcntl(caddr_t addr, //address to alter; must be multiple of pagesize
size_t len, //length to alter
int cmd, //MC_LOCK,MC_LOCKAS,MC_SYNC,MC_UNLOCK,MC_UNLOCKAS
caddr_t arg, //MCL_CURRENT, MCL_FUTURE
int attr, /*SHARED, PRIVATE, PROT_READ,PROT_WRITE,PROT_EXEC,
PROC_TEXT,PROC_DATA */
int mask ); //always 0
If cmd is MCL_LOCKAS
arg - MCL_CURRENT, MCL_FUTURE
If cmd is MC_SYNC
arg - MC_ASYNC,MC_SYNC,MS_INVALIDATE
Only MC_SYNC does not require superuser privilege.
Computer Operating Systems
Memory.26
Gerard C. Weatherby
mlock - lock pages into memory (keep from swapping)
munlock - unlock pages
mlockall - lock all a processes pages
munlockall - unlock all pages
plock - lock based on segment
int mlock(const void * addr, size_t len);
int munlock(const void * addr, size_t len);
int mlockall(int flags); //MCL_CURRENT, MCL_FUTURE
int munlockall( );
int plock(int op); //PROCLOCK (text & data),TXTLOCK,DATLOCK,UNLOCK
Locking pages may degrade system performance; all functions require superuser permission
Computer Operating Systems
Memory.27
Gerard C. Weatherby
• getpagesize - get size of page
int getpagesize( );
Some memory management calls require even pagesize
addresses
• mprotect - change accesses of specified pages
int mprotect(void *addr, //address to protect; must be pagesize interval
size_t len, //number bytes to protect
int prot); //PROT_READ, PROT_WRITE,PROT_EXEC,PROT_NONE
Computer Operating Systems
Memory.28
Gerard C. Weatherby
• mprotect example (simplified)
int main( ){
const int pagesize = getpagesize( );
cout << "pagesize " << pagesize << endl;
const int length= 100;
//must get even page boundary to allow protection
int raw = reinterpret_cast<int>(malloc(2 *pagesize));
int *array = reinterpret_cast<int *>((1 + raw/pagesize)*pagesize);
for (int i=0;i<length;i++)array[i] = i * i;
mprotect(reinterpret_cast<char *>(array),
length * sizeof(int),
PROT_READ);
cout << "5 squared is " << array[5] << endl;
array[5] = 10;
cout << "memory written" << endl;
cout << "5 squared is " << array[5] << endl; }
pagesize 8192
5 squared is 25
bmem[4]: 9516 Segmentation Fault(coredump)
Computer Operating Systems
Memory.29
Gerard C. Weatherby
UNIX shared memory
Can share memory between processes
Fastest means of interprocess communication
Typically use sempahore to guard access
• shmget - get (create or attach to) shared memory identifier
int shmget(key_t key, //IPC_PRIVATE or return from ftok
size_t size, //size of memory to allocate
int shmflg); //IPC_CREAT, permissions
Note size and shmflg ignored if attaching to existing memory
• shmat - create or attach to shared memory region
void * shmat(int shmid, //identifier returned from shmget
const void * shmaddr, //address to allocate (perhaps)
int shmflg); //SHM_SHAR_MMU,SHM_RND,SHM_READONLY
Computer Operating Systems
Memory.30
Gerard C. Weatherby
• shmctl - control operations on shared memory
int shmctl(int shmid, //identifier returned from shmget
int cmd, //IPC_STAT, IPC_SET, IPC_RMID, SHM_LOCK,SHM_LOCK
struct shmid_ds *buf);
shmid_ds struct
filled by IPC_STAT
IPC_SET uses shm_perm
struct ipc_perm shm_perm;
int
/* operation permission struct */
shm_segsz;
struct region
/* size of segment */
*shm_reg;
/* ptr to region structure */
char
pad[4];
/* for swap compatibility */
pid_t
shm_lpid;
/* pid of last operation */
pid_t
shm_cpid;
/* creator pid */
ushort_t
shm_nattch; /* number of current attaches */
ushort_t
shm_cnattch; /* used only for shminfo */
Computer Operating Systems
Memory.31
Gerard C. Weatherby
time_t
shm_atime;
/* last attach time */
time_t
shm_dtime;
/* last detach time */
time_t
shm_ctime;
/* last change time */
SHM_LOCK and SHM_UNLOCK require superuser
IPC_RMID most common.
Shared memory not automatically released when
a process exits -- can degrade system if not
cleaned up.
ipcs / ipcrm command line utilities may be used to
cleanup up semaphores and shared memory
Computer Operating Systems
Memory.32
Gerard C. Weatherby
• Example - first process (simplified)
#include "sem.h"// setSem, semWait
int main( ) {
const int key = ftok("keyfile",'a');
const int shmid = shmget(key,sizeof(int),IPC_CREAT|0644);
void *shared = shmat(shmid,0,0);
cout << "Shared is " << shared << endl;
const int semid = semget(key,1,IPC_CREAT|0666);
setSem(semid,0); //sets semaphore to 0
//wait for other process
semWait(semid);
int *pvalue = static_cast<int*>(shared);
cout << "shared value is " << *pvalue << endl;
shmctl(shmid,IPC_RMID,0);
semctl(semid,IPC_RMID,0);
}
Computer Operating Systems
Memory.33
Gerard C. Weatherby
• Example - second process (simplified)
#include "sem.h" //semSignal
int main(int argc , char *argv[])
{
const int key = ftok("keyfile",'a');
const int shmid = shmget(key,sizeof(int),0644);
void *shared = shmat(shmid,0,0);
int *pvalue = static_cast<int *>(shared);
const int semid = semget(key,1,0666);
const int value = atoi(argv[1]);
cout << "Setting " << shared << " to " << value << endl;
*pvalue = value;
//signal other process
semSignal(semid);
}
Computer Operating Systems
Memory.34
Gerard C. Weatherby
Security
• Displaying windows error messages
• C / C++ approach to coding
• NT security model
Computer Operating Systems
Security.1
Gerard C. Weatherby
Printing Windows error messages
• Unix offers perror for failed system calls -- prints error message to standard error.
• Windows does not have a single call, but it can be replicated:
#include <windows.h>
#include <stdio.h>
win_perror(char *msg)
{
# define BLEN 512
char buffer[BLEN];
long hr;
hr = GetLastError( );
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,hr,0,buffer,BLEN,0);
fprintf(stderr,"%s: %s\n",msg,buffer);
}
void main( )
Computer Operating Systems
Security.2
Gerard C. Weatherby
{
HANDLE hFile = CreateFile("d:\\notthere.txt", GENERIC_READ |
GENERIC_WRITE,
0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
win_perror("Create File");
}
produces
Create File: The system cannot find the file specified.
Security.3
Computer Operating Systems
Gerard C. Weatherby
NT model
Access token -- user
Security descriptor -- lock
Security
Descriptor
?
Access token
key
lock
created,
assigned
logs in
User
object
Computer Operating Systems
Security.4
Gerard C. Weatherby
Example program C
#include <windows.h>
#include <iostream.h>
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
BYTE aclbuf[1024], SIDbuf[100];;
PACL pacl=(PACL)&aclbuf;
PSID psid=(PSID) &SIDbuf;
DWORD SIDbufSize = 100;
DWORD domainbufsz = 80;
char domainbuf[80];
SID_NAME_USE snu;
HANDLE hFile;
void main(void)
{
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
InitializeAcl(pacl, 1024, ACL_REVISION);
Computer Operating Systems
Security.5
Gerard C. Weatherby
LookupAccountName(0, "guest", psid, &SIDbufSize, domainbuf,
&domainbufsz, &snu);
AddAccessAllowedAce(pacl, ACL_REVISION, GENERIC_READ, psid);
SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
hFile = CreateFile("d:\\testacl.txt", GENERIC_READ | GENERIC_WRITE,
0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
CloseHandle(hFile);
}
Computer Operating Systems
Security.6
Gerard C. Weatherby
Example program, C++
#include <windows.h>
#include "securitydescriptor.h"
#include "sid.h"
#include "acl.h"
#include "securityattributes.h"
#include "err.h"
void main(void)
{
try {
Sid sid("guest");
Acl acl(sid);
acl.AddAccessAllowed(GENERIC_READ);
SecurityDescriptor sd;
sd.SetDacl(acl);
SecurityAttributes sa(sd);
HANDLE hFile = CreateFile("d:\\testacl.txt", GENERIC_READ |
GENERIC_WRITE,
Computer Operating Systems
Security.7
Gerard C. Weatherby
0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
ShowErr("CreateFile");
CloseHandle(hFile);
} catch (const char *msg)
{
ShowErr(msg);
}
}
Computer Operating Systems
Security.8
Download