Université BORDEAUX 1 | U.F.R. Mathématiques et Informatique |
Epreuve de J.Bétréma | 20 septembre 2000 |
Durée: 3 heures
Tous documents interdits.
#include <unistd.h> #include <stdlib.h> void *allouer (int n) { void *p = malloc (n); void *b = sbrk (0); printf ("malloc : %u (0x%x) brk : %u (0x%x)\n", p, p, b, b); return p; } void liberer (void *p) { void *b; free (p); b = sbrk (0); printf (" brk : %u (0x%x)\n", b, b); } void main (void) { void *p, *q; allouer (1000); p = allouer (10000); q = allouer (100); liberer (p); liberer (q); allouer (500); getchar (); }et le résultat de son exécution :
malloc : 134519000 (0x80498d8) brk : 134520832 (0x804a000) malloc : 134520008 (0x8049cc8) brk : 134533120 (0x804d000) malloc : 134530016 (0x804c3e0) brk : 134533120 (0x804d000) brk : 134533120 (0x804d000) brk : 134533120 (0x804d000) malloc : 134520008 (0x8049cc8) brk : 134533120 (0x804d000)
Pendant que le programme est bloqué en fin d'exécution, en attente d'un caractère, on entre les commandes suivantes :
+serveur2-1:~$ cd /proc +serveur2-1:/proc$ ps -all | grep allouer F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 000 S 1006 32469 32021 0 60 0 - 271 read_c pts/20 00:00:00 allouer +serveur2-1:/proc$ cd 32469 +serveur2-1:/proc/32469$ cat maps 08048000-08049000 r-xp 00000000 00:05 1699755 /.automount/raid3/export/home/ betrema/systemes/allouer 08049000-0804a000 rw-p 00000000 00:05 1699755 /.automount/raid3/export/home/ betrema/systemes/allouer 0804a000-0804d000 rwxp 00000000 00:00 0 40000000-40012000 r-xp 00000000 08:02 256600 /lib/ld-2.1.2.so 40012000-40013000 rw-p 00012000 08:02 256600 /lib/ld-2.1.2.so 40013000-40015000 rw-p 00000000 00:00 0 4001a000-40105000 r-xp 00000000 08:02 256607 /lib/libc-2.1.2.so 40105000-40109000 rw-p 000ea000 08:02 256607 /lib/libc-2.1.2.so 40109000-4010d000 rw-p 00000000 00:00 0 bfffe000-c0000000 rwxp fffff000 00:00 0 +serveur2-1:/proc/32469$
Note : d'une part ce programme est incomplet, d'autre part on ne peut envisager, dans le cadre de l'examen, son analyse ligne par ligne. Votre réponse doit être soigneusement rédigée, et sera jugée sur sa clarté et son intelligence. La répétition en pseudo-français des instructions du programme ne rapportera aucun point.
typedef struct { HANDLE hNamedPipe; /* Named pipe instance. */ DWORD ThreadId; TCHAR TmpFileName [MAX_PATH]; } THREAD_ARG; typedef THREAD_ARG *LPTHREAD_ARG; main (int argc, LPTSTR argv []) { /* MAX_CLIENTS is defined in ClntSrvr.h. */ THREAD_ARG ThArgs [MAX_CLIENTS]; HANDLE hNp, hSrvrThread [MAX_CLIENTS], hMonitor; DWORD iNp, MonitorId; NumServers = MAX_CLIENTS; for (iNp = 0; iNp < MAX_CLIENTS; iNp++) { hNp = CreateNamedPipe ( SERVER_PIPE, PIPE_ACCESS_DUPLEX, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, MAX_CLIENTS, 0, 0, INFINITE, NULL); if (hNp == INVALID_HANDLE_VALUE) ReportError ("Failure to open named pipe.", 1, TRUE); ThArgs [iNp].hNamedPipe = hNp; GetTempFileName (".", "CLP", 0, ThArgs [iNp].TmpFileName); hSrvrThread [iNp] = (HANDLE) CreateThread (NULL, 0, Server, &ThArgs [iNp], 0, &ThArgs [iNp].ThreadId); if (hSrvrThread [iNp] == NULL) ReportError ("Failure to create server thread.", 2, TRUE); } WaitForMultipleObjects (MAX_CLIENTS, hSrvrThread, TRUE, INFINITE); for (iNp = 0; iNp < MAX_CLIENTS; iNp++) CloseHandle (hSrvrThread [iNp]); WaitForSingleObject (hMonitor, INFINITE); CloseHandle (hMonitor); return 0; } static DWORD WINAPI Server (LPTHREAD_ARG pThArg) { HANDLE hNamedPipe, hTmpFile; DWORD nXfer; TCHAR ShutRqst [] = "$ShutDownServer"; STARTUPINFO StartInfoCh; SECURITY_ATTRIBUTES TempSA = {sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; PROCESS_INFORMATION ProcInfo; FILE *fp; REQUEST Request; RESPONSE Response; GetStartupInfo (&StartInfoCh); hNamedPipe = pThArg->hNamedPipe; /* Wait for a connection. */ ConnectNamedPipe (hNamedPipe, NULL); while (!ShutDown) { hTmpFile = CreateFile (pThArg->TmpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &TempSA, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); while (!ReadFile (hNamedPipe, &Request, RQ_SIZE, &nXfer, NULL)) { DisconnectNamedPipe (hNamedPipe); ConnectNamedPipe (hNamedPipe, NULL); } sscanf (Request.Record, "%s", Command); if (strcmp(Command, ShutRqst) == 0) /* Terminate the system. */ ServerStats (NULL, CS_TERMTHD); else { StartInfoCh.hStdOutput = hTmpFile; StartInfoCh.hStdError = hTmpFile; StartInfoCh.dwFlags = STARTF_USESTDHANDLES; if (!CreateProcess (NULL, Request.Record, NULL, NULL, TRUE, /* Inherit handles. */ 0, NULL, NULL, &StartInfoCh, &ProcInfo)) { PrintMsg (hTmpFile, "Server could not create process.")); ProcInfo.hProcess = NULL; } else { CloseHandle (ProcInfo.hThread); WaitForSingleObject (ProcInfo.hProcess, INFINITE); CloseHandle (ProcInfo.hProcess); } } CloseHandle (hTmpFile); /* Respond a line at a time. It is convenient to use C library line-oriented routines at this point. */ fp = fopen (pThArg->TmpFileName, "r"); if (fp == NULL) perror ("Failure to open command output file."); Response.Status = 0; while ((fgetts (Response.Record, MAX_RQRS_LEN, fp) != NULL)) WriteFile (hNamedPipe, &Response, RS_SIZE, &nXfer, NULL); fclose (fp); /* Send an end of response indicator. */ Response.Status = 1; WriteFile (hNamedPipe, &Response, RS_SIZE, &nXfer, NULL); } /* End of main command loop. */ if (!DisconnectNamedPipe (hNamedPipe) || !CloseHandle (hNamedPipe) || !DeleteFile (pThArg->TmpFileName)) ReportError ("Error shutting down server.", 0, TRUE); ExitThread (0); return 0; }