Description:
updated box for windows to prevent error modal dialog
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r131:d5c4e1d8daa2 - - 1 file changed: 3 inserted, 0 deleted
@@ -208,192 +208,195 | |||||
|
208 | // Print information about the memory usage of the process. |
|
208 | // Print information about the memory usage of the process. |
|
209 |
|
209 | ||
|
210 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | |
|
210 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | |
|
211 | PROCESS_VM_READ, |
|
211 | PROCESS_VM_READ, |
|
212 | FALSE,processID); |
|
212 | FALSE,processID); |
|
213 | if(hProcess == NULL) |
|
213 | if(hProcess == NULL) |
|
214 | return; |
|
214 | return; |
|
215 |
|
215 | ||
|
216 | if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { |
|
216 | if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { |
|
217 | printf("\tPageFaultCount: %d\n",pmc.PageFaultCount); |
|
217 | printf("\tPageFaultCount: %d\n",pmc.PageFaultCount); |
|
218 | printf("\tPeakWorkingSetSize: %d\n", |
|
218 | printf("\tPeakWorkingSetSize: %d\n", |
|
219 | pmc.PeakWorkingSetSize); |
|
219 | pmc.PeakWorkingSetSize); |
|
220 | printf("\tWorkingSetSize: %d\n",pmc.WorkingSetSize); |
|
220 | printf("\tWorkingSetSize: %d\n",pmc.WorkingSetSize); |
|
221 | printf("\tQuotaPeakPagedPoolUsage: %d\n", |
|
221 | printf("\tQuotaPeakPagedPoolUsage: %d\n", |
|
222 | pmc.QuotaPeakPagedPoolUsage); |
|
222 | pmc.QuotaPeakPagedPoolUsage); |
|
223 | printf("\tQuotaPagedPoolUsage: %d\n", |
|
223 | printf("\tQuotaPagedPoolUsage: %d\n", |
|
224 | pmc.QuotaPagedPoolUsage); |
|
224 | pmc.QuotaPagedPoolUsage); |
|
225 | printf("\tQuotaPeakNonPagedPoolUsage: %d\n", |
|
225 | printf("\tQuotaPeakNonPagedPoolUsage: %d\n", |
|
226 | pmc.QuotaPeakNonPagedPoolUsage); |
|
226 | pmc.QuotaPeakNonPagedPoolUsage); |
|
227 | printf("\tQuotaNonPagedPoolUsage: %d\n", |
|
227 | printf("\tQuotaNonPagedPoolUsage: %d\n", |
|
228 | pmc.QuotaNonPagedPoolUsage); |
|
228 | pmc.QuotaNonPagedPoolUsage); |
|
229 | printf("\tPagefileUsage: %d\n",pmc.PagefileUsage); |
|
229 | printf("\tPagefileUsage: %d\n",pmc.PagefileUsage); |
|
230 | printf("\tPeakPagefileUsage: %d\n", |
|
230 | printf("\tPeakPagefileUsage: %d\n", |
|
231 | pmc.PeakPagefileUsage); |
|
231 | pmc.PeakPagefileUsage); |
|
232 | } |
|
232 | } |
|
233 | CloseHandle( hProcess ); |
|
233 | CloseHandle( hProcess ); |
|
234 | } |
|
234 | } |
|
235 |
|
235 | ||
|
236 | int check_memory_usage(DWORD pid, int max_mem, int *actual_usage) { |
|
236 | int check_memory_usage(DWORD pid, int max_mem, int *actual_usage) { |
|
237 | // modified from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx |
|
237 | // modified from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx |
|
238 | //PrintMemoryInfo(pid); |
|
238 | //PrintMemoryInfo(pid); |
|
239 | HANDLE hProcess; |
|
239 | HANDLE hProcess; |
|
240 | PROCESS_MEMORY_COUNTERS pmc; |
|
240 | PROCESS_MEMORY_COUNTERS pmc; |
|
241 |
|
241 | ||
|
242 | if((max_mem==0) || (pid==0)) |
|
242 | if((max_mem==0) || (pid==0)) |
|
243 | return 1; |
|
243 | return 1; |
|
244 |
|
244 | ||
|
245 | if(pid == get_ntvdm_pid()) { |
|
245 | if(pid == get_ntvdm_pid()) { |
|
246 | fprintf(stderr,"ntvdm: ignored\n"); |
|
246 | fprintf(stderr,"ntvdm: ignored\n"); |
|
247 | return 1; |
|
247 | return 1; |
|
248 | } |
|
248 | } |
|
249 |
|
249 | ||
|
250 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | |
|
250 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | |
|
251 | PROCESS_VM_READ, |
|
251 | PROCESS_VM_READ, |
|
252 | FALSE, pid); |
|
252 | FALSE, pid); |
|
253 | if(hProcess == NULL) |
|
253 | if(hProcess == NULL) |
|
254 | return 1; |
|
254 | return 1; |
|
255 |
|
255 | ||
|
256 | int max_mem_usage = 0; |
|
256 | int max_mem_usage = 0; |
|
257 | if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { |
|
257 | if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { |
|
258 | max_mem_usage = pmc.PeakWorkingSetSize; |
|
258 | max_mem_usage = pmc.PeakWorkingSetSize; |
|
259 | if(pmc.PeakPagefileUsage > max_mem_usage) |
|
259 | if(pmc.PeakPagefileUsage > max_mem_usage) |
|
260 | max_mem_usage = pmc.PeakPagefileUsage; |
|
260 | max_mem_usage = pmc.PeakPagefileUsage; |
|
261 | } |
|
261 | } |
|
262 | CloseHandle(hProcess); |
|
262 | CloseHandle(hProcess); |
|
263 | if(actual_usage != NULL) |
|
263 | if(actual_usage != NULL) |
|
264 | (*actual_usage) = max_mem_usage; |
|
264 | (*actual_usage) = max_mem_usage; |
|
265 | return (max_mem_usage <= max_mem); |
|
265 | return (max_mem_usage <= max_mem); |
|
266 | } |
|
266 | } |
|
267 |
|
267 | ||
|
268 | void report_stat(double time_used, int memory_used) |
|
268 | void report_stat(double time_used, int memory_used) |
|
269 | { |
|
269 | { |
|
270 | fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n", |
|
270 | fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n", |
|
271 | time_used, |
|
271 | time_used, |
|
272 | time_used, (double)0, |
|
272 | time_used, (double)0, |
|
273 | memory_used); |
|
273 | memory_used); |
|
274 | } |
|
274 | } |
|
275 |
|
275 | ||
|
276 | double get_process_time_usage(HANDLE hProcess) |
|
276 | double get_process_time_usage(HANDLE hProcess) |
|
277 | { |
|
277 | { |
|
278 | FILETIME creation_time; |
|
278 | FILETIME creation_time; |
|
279 | FILETIME exit_time; |
|
279 | FILETIME exit_time; |
|
280 | FILETIME kernel_time; |
|
280 | FILETIME kernel_time; |
|
281 | FILETIME user_time; |
|
281 | FILETIME user_time; |
|
282 | GetProcessTimes(hProcess, |
|
282 | GetProcessTimes(hProcess, |
|
283 | &creation_time, |
|
283 | &creation_time, |
|
284 | &exit_time, |
|
284 | &exit_time, |
|
285 | &kernel_time, |
|
285 | &kernel_time, |
|
286 | &user_time); |
|
286 | &user_time); |
|
287 |
|
287 | ||
|
288 | SYSTEMTIME sys_kernel_time; |
|
288 | SYSTEMTIME sys_kernel_time; |
|
289 | SYSTEMTIME sys_user_time; |
|
289 | SYSTEMTIME sys_user_time; |
|
290 | FileTimeToSystemTime(&kernel_time, &sys_kernel_time); |
|
290 | FileTimeToSystemTime(&kernel_time, &sys_kernel_time); |
|
291 | FileTimeToSystemTime(&user_time, &sys_user_time); |
|
291 | FileTimeToSystemTime(&user_time, &sys_user_time); |
|
292 |
|
292 | ||
|
293 | double time_used = |
|
293 | double time_used = |
|
294 | ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) + |
|
294 | ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) + |
|
295 | (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0)); |
|
295 | (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0)); |
|
296 | return time_used; |
|
296 | return time_used; |
|
297 | } |
|
297 | } |
|
298 |
|
298 | ||
|
299 | int execute(char *exname, char *inname, char *outname, double t, int max_mem) |
|
299 | int execute(char *exname, char *inname, char *outname, double t, int max_mem) |
|
300 | { |
|
300 | { |
|
301 | STARTUPINFO si; |
|
301 | STARTUPINFO si; |
|
302 | PROCESS_INFORMATION pi; |
|
302 | PROCESS_INFORMATION pi; |
|
303 | int ifsuccess = EXE_RESULT_OK; |
|
303 | int ifsuccess = EXE_RESULT_OK; |
|
|
304 | + | ||
|
|
305 | + SetErrorMode(SEM_FAILCRITICALERRORS); | ||
|
|
306 | + SetErrorMode(SEM_NOGPFAULTERRORBOX); | ||
|
304 |
|
307 | ||
|
305 | ZeroMemory(&si, sizeof(si)); |
|
308 | ZeroMemory(&si, sizeof(si)); |
|
306 | si.cb = sizeof(si); |
|
309 | si.cb = sizeof(si); |
|
307 | ZeroMemory(&pi, sizeof(pi)); |
|
310 | ZeroMemory(&pi, sizeof(pi)); |
|
308 |
|
311 | ||
|
309 | setstartupinfo(&si, inname, outname); |
|
312 | setstartupinfo(&si, inname, outname); |
|
310 |
|
313 | ||
|
311 | if(!CreateProcess( NULL, // No module name (use command line). |
|
314 | if(!CreateProcess( NULL, // No module name (use command line). |
|
312 | TEXT(exname), // Command line. |
|
315 | TEXT(exname), // Command line. |
|
313 | NULL, // Process handle not inheritable. |
|
316 | NULL, // Process handle not inheritable. |
|
314 | NULL, // Thread handle not inheritable. |
|
317 | NULL, // Thread handle not inheritable. |
|
315 | TRUE, // Set handle inheritance to FALSE. |
|
318 | TRUE, // Set handle inheritance to FALSE. |
|
316 | 0, // No creation flags. |
|
319 | 0, // No creation flags. |
|
317 | NULL, // Use parent's environment block. |
|
320 | NULL, // Use parent's environment block. |
|
318 | NULL, // Use parent's starting directory. |
|
321 | NULL, // Use parent's starting directory. |
|
319 | &si, // Pointer to STARTUPINFO structure. |
|
322 | &si, // Pointer to STARTUPINFO structure. |
|
320 | &pi)) // Pointer to PROCESS_INFORMATION structure. |
|
323 | &pi)) // Pointer to PROCESS_INFORMATION structure. |
|
321 | { |
|
324 | { |
|
322 | //printf( "CreateProcess failed (%d).\n", GetLastError() ); |
|
325 | //printf( "CreateProcess failed (%d).\n", GetLastError() ); |
|
323 | fprintf(stderr, "Process creation error.\n"); |
|
326 | fprintf(stderr, "Process creation error.\n"); |
|
324 | report_stat(0,0); |
|
327 | report_stat(0,0); |
|
325 | return EXE_RESULT_ERROR; |
|
328 | return EXE_RESULT_ERROR; |
|
326 | } |
|
329 | } |
|
327 | //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId); |
|
330 | //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId); |
|
328 | //fprintf(stderr,"time limit = %d\n",t); |
|
331 | //fprintf(stderr,"time limit = %d\n",t); |
|
329 |
|
332 | ||
|
330 | // checking memory usage |
|
333 | // checking memory usage |
|
331 | // wait 0.1 sec before checking mem usage |
|
334 | // wait 0.1 sec before checking mem usage |
|
332 |
|
335 | ||
|
333 | SetProcessWorkingSetSize(pi.hProcess, |
|
336 | SetProcessWorkingSetSize(pi.hProcess, |
|
334 | 1, |
|
337 | 1, |
|
335 | max_mem); |
|
338 | max_mem); |
|
336 | int actual_memory_usage = 0; |
|
339 | int actual_memory_usage = 0; |
|
337 |
|
340 | ||
|
338 | Sleep(INITIAL_WAIT_FOR_MEM_CHECK); |
|
341 | Sleep(INITIAL_WAIT_FOR_MEM_CHECK); |
|
339 | if(!check_memory_usage(pi.dwProcessId,max_mem,&actual_memory_usage)) { |
|
342 | if(!check_memory_usage(pi.dwProcessId,max_mem,&actual_memory_usage)) { |
|
340 | // using too much memory |
|
343 | // using too much memory |
|
341 | fprintf(stderr,"Memory limit exceeded.\n"); |
|
344 | fprintf(stderr,"Memory limit exceeded.\n"); |
|
342 | //PrintMemoryInfo(pi.dwProcessId); |
|
345 | //PrintMemoryInfo(pi.dwProcessId); |
|
343 | ifsuccess = EXE_RESULT_MEMORY; |
|
346 | ifsuccess = EXE_RESULT_MEMORY; |
|
344 | } |
|
347 | } |
|
345 |
|
348 | ||
|
346 | //printf("PID: %d\n", pi.dwProcessId); |
|
349 | //printf("PID: %d\n", pi.dwProcessId); |
|
347 |
|
350 | ||
|
348 | if(ifsuccess != EXE_RESULT_MEMORY) { |
|
351 | if(ifsuccess != EXE_RESULT_MEMORY) { |
|
349 | int based_time = (int)(t*1000) + 1 - INITIAL_WAIT_FOR_MEM_CHECK; |
|
352 | int based_time = (int)(t*1000) + 1 - INITIAL_WAIT_FOR_MEM_CHECK; |
|
350 | bool major_timed_out = (WaitForSingleObject(pi.hProcess, |
|
353 | bool major_timed_out = (WaitForSingleObject(pi.hProcess, |
|
351 | based_time)==WAIT_TIMEOUT); |
|
354 | based_time)==WAIT_TIMEOUT); |
|
352 | if(major_timed_out) { |
|
355 | if(major_timed_out) { |
|
353 | // wait some more for user time. |
|
356 | // wait some more for user time. |
|
354 | double time_used = get_process_time_usage(pi.hProcess); |
|
357 | double time_used = get_process_time_usage(pi.hProcess); |
|
355 | while(time_used <= t) { |
|
358 | while(time_used <= t) { |
|
356 | int iter_time = 100; |
|
359 | int iter_time = 100; |
|
357 | if(t - time_used < 200) |
|
360 | if(t - time_used < 200) |
|
358 | iter_time = 20; |
|
361 | iter_time = 20; |
|
359 | bool iter_timed_out = (WaitForSingleObject(pi.hProcess, |
|
362 | bool iter_timed_out = (WaitForSingleObject(pi.hProcess, |
|
360 | iter_time)==WAIT_TIMEOUT); |
|
363 | iter_time)==WAIT_TIMEOUT); |
|
361 | if(!iter_timed_out) |
|
364 | if(!iter_timed_out) |
|
362 | break; |
|
365 | break; |
|
363 |
|
366 | ||
|
364 | time_used = get_process_time_usage(pi.hProcess); |
|
367 | time_used = get_process_time_usage(pi.hProcess); |
|
365 | //printf("%lf\n",time_used); |
|
368 | //printf("%lf\n",time_used); |
|
366 | } |
|
369 | } |
|
367 | ifsuccess = EXE_RESULT_TIMEOUT; |
|
370 | ifsuccess = EXE_RESULT_TIMEOUT; |
|
368 | } |
|
371 | } |
|
369 | } |
|
372 | } |
|
370 |
|
373 | ||
|
371 | if((ifsuccess == EXE_RESULT_MEMORY) || (ifsuccess == EXE_RESULT_TIMEOUT)) { |
|
374 | if((ifsuccess == EXE_RESULT_MEMORY) || (ifsuccess == EXE_RESULT_TIMEOUT)) { |
|
372 | // Kill process, because (1) it used too much memory, or (2) time limit |
|
375 | // Kill process, because (1) it used too much memory, or (2) time limit |
|
373 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); |
|
376 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); |
|
374 |
|
377 | ||
|
375 | if(ifsuccess != EXE_RESULT_MEMORY) |
|
378 | if(ifsuccess != EXE_RESULT_MEMORY) |
|
376 | fprintf(stderr,"Time limit exceeded.\n"); |
|
379 | fprintf(stderr,"Time limit exceeded.\n"); |
|
377 | if(hProcess != NULL) { |
|
380 | if(hProcess != NULL) { |
|
378 | fprintf(stderr,"killing pid: %ld\n",pi.dwProcessId); |
|
381 | fprintf(stderr,"killing pid: %ld\n",pi.dwProcessId); |
|
379 | TerminateProcess(hProcess, 0); |
|
382 | TerminateProcess(hProcess, 0); |
|
380 | wait_dialog(); |
|
383 | wait_dialog(); |
|
381 | } else { |
|
384 | } else { |
|
382 | DWORD dwNtvdmId = get_ntvdm_pid(); |
|
385 | DWORD dwNtvdmId = get_ntvdm_pid(); |
|
383 | fprintf(stderr,"killing (ntvdm) pid: %ld\n",dwNtvdmId); |
|
386 | fprintf(stderr,"killing (ntvdm) pid: %ld\n",dwNtvdmId); |
|
384 | if(dwNtvdmId!=0) { |
|
387 | if(dwNtvdmId!=0) { |
|
385 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwNtvdmId); |
|
388 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwNtvdmId); |
|
386 | TerminateProcess(hProcess, 0); |
|
389 | TerminateProcess(hProcess, 0); |
|
387 | } else { |
|
390 | } else { |
|
388 | fprintf(stderr,"killing process error\n"); |
|
391 | fprintf(stderr,"killing process error\n"); |
|
389 | } |
|
392 | } |
|
390 |
|
393 | ||
|
391 | if(get_ntvdm_pid()!=0) { |
|
394 | if(get_ntvdm_pid()!=0) { |
|
392 | fprintf(stderr,"killing error, ntvdm.exe still remains;"); |
|
395 | fprintf(stderr,"killing error, ntvdm.exe still remains;"); |
|
393 | fprintf(stderr,"please MANUALLY kill it."); |
|
396 | fprintf(stderr,"please MANUALLY kill it."); |
|
394 | fflush(stderr); |
|
397 | fflush(stderr); |
|
395 | do { |
|
398 | do { |
|
396 | Sleep(1000); |
|
399 | Sleep(1000); |
|
397 | } while(get_ntvdm_pid()!=0); |
|
400 | } while(get_ntvdm_pid()!=0); |
|
398 | fprintf(stderr,"... done\n"); |
|
401 | fprintf(stderr,"... done\n"); |
|
399 | wait_dialog(); |
|
402 | wait_dialog(); |
You need to be logged in to leave comments.
Login now