Description:
updated box for windows to prevent error modal dialog
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r131:d5c4e1d8daa2 - - 1 file changed: 3 inserted, 0 deleted

@@ -112,339 +112,342
112 112 return 0;
113 113 }
114 114
115 115 do {
116 116 if(strcasecmp(pe32.szExeFile ,pname)==0)
117 117 pid = pe32.th32ProcessID;
118 118 } while( Process32Next( hProcessSnap, &pe32 ) );
119 119
120 120 CloseHandle( hProcessSnap );
121 121 return pid;
122 122 }
123 123
124 124 DWORD get_ntvdm_pid()
125 125 {
126 126 return get_process_id("ntvdm.exe");
127 127 }
128 128
129 129 void kill_error_report()
130 130 {
131 131 DWORD pid;
132 132 do {
133 133 if((pid = get_process_id("dwwin.exe"))!=0) {
134 134 fprintf(stderr," -- with error report (pid: %ld)\n",pid);
135 135 HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid);
136 136 if(hProcess!=NULL) {
137 137 TerminateProcess(hProcess, 0);
138 138 Sleep(500);
139 139 while(get_process_id("dwwin.exe")==pid) {
140 140 fprintf(stderr,"wait for dwwin.exe to die...\n");
141 141 Sleep(500);
142 142 }
143 143 } else
144 144 fprintf(stderr,"do not have permission (%d)\n",
145 145 GetLastError());
146 146 }
147 147 } while(get_process_id("dwwin.exe")!=0);
148 148 }
149 149
150 150 void wait_dialog()
151 151 {
152 152 kill_error_report();
153 153 if(check_ntvdm_dialog()) {
154 154 fprintf(stderr,"Some dialog opens; please MANUALLY kill it.");
155 155 fflush(stderr);
156 156 do {
157 157 Sleep(1000);
158 158 } while(check_ntvdm_dialog());
159 159 fprintf(stderr,"... done\n");
160 160 }
161 161 }
162 162
163 163 void setstartupinfo(STARTUPINFO *si, char *inname, char *outname)
164 164 {
165 165 SECURITY_ATTRIBUTES sa;
166 166
167 167 ZeroMemory(&sa, sizeof(sa));
168 168 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
169 169 sa.lpSecurityDescriptor = NULL;
170 170 sa.bInheritHandle = TRUE;
171 171
172 172 si->dwFlags = STARTF_USESTDHANDLES;
173 173 if((inname!=0) && (strcmp(inname,"-")!=0)) {
174 174 si->hStdInput = CreateFile(inname,
175 175 FILE_READ_DATA,
176 176 FILE_SHARE_READ,
177 177 &sa,
178 178 OPEN_EXISTING,
179 179 FILE_ATTRIBUTE_NORMAL,
180 180 NULL);
181 181 } else
182 182 si->hStdInput = NULL;
183 183
184 184 if((outname!=0) && (strcmp(outname,"-")!=0)) {
185 185 si->hStdOutput = CreateFile(outname,
186 186 FILE_WRITE_DATA,
187 187 FILE_SHARE_READ,
188 188 &sa,
189 189 CREATE_ALWAYS,
190 190 FILE_ATTRIBUTE_NORMAL,
191 191 NULL);
192 192 } else
193 193 si->hStdOutput = NULL;
194 194
195 195 si->hStdError = NULL;
196 196 }
197 197
198 198 // taken from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx
199 199 void PrintMemoryInfo(DWORD processID)
200 200 {
201 201 HANDLE hProcess;
202 202 PROCESS_MEMORY_COUNTERS pmc;
203 203
204 204 // Print the process identifier.
205 205
206 206 printf("\nProcess ID: %u\n", processID);
207 207
208 208 // Print information about the memory usage of the process.
209 209
210 210 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
211 211 PROCESS_VM_READ,
212 212 FALSE,processID);
213 213 if(hProcess == NULL)
214 214 return;
215 215
216 216 if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
217 217 printf("\tPageFaultCount: %d\n",pmc.PageFaultCount);
218 218 printf("\tPeakWorkingSetSize: %d\n",
219 219 pmc.PeakWorkingSetSize);
220 220 printf("\tWorkingSetSize: %d\n",pmc.WorkingSetSize);
221 221 printf("\tQuotaPeakPagedPoolUsage: %d\n",
222 222 pmc.QuotaPeakPagedPoolUsage);
223 223 printf("\tQuotaPagedPoolUsage: %d\n",
224 224 pmc.QuotaPagedPoolUsage);
225 225 printf("\tQuotaPeakNonPagedPoolUsage: %d\n",
226 226 pmc.QuotaPeakNonPagedPoolUsage);
227 227 printf("\tQuotaNonPagedPoolUsage: %d\n",
228 228 pmc.QuotaNonPagedPoolUsage);
229 229 printf("\tPagefileUsage: %d\n",pmc.PagefileUsage);
230 230 printf("\tPeakPagefileUsage: %d\n",
231 231 pmc.PeakPagefileUsage);
232 232 }
233 233 CloseHandle( hProcess );
234 234 }
235 235
236 236 int check_memory_usage(DWORD pid, int max_mem, int *actual_usage) {
237 237 // modified from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx
238 238 //PrintMemoryInfo(pid);
239 239 HANDLE hProcess;
240 240 PROCESS_MEMORY_COUNTERS pmc;
241 241
242 242 if((max_mem==0) || (pid==0))
243 243 return 1;
244 244
245 245 if(pid == get_ntvdm_pid()) {
246 246 fprintf(stderr,"ntvdm: ignored\n");
247 247 return 1;
248 248 }
249 249
250 250 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
251 251 PROCESS_VM_READ,
252 252 FALSE, pid);
253 253 if(hProcess == NULL)
254 254 return 1;
255 255
256 256 int max_mem_usage = 0;
257 257 if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
258 258 max_mem_usage = pmc.PeakWorkingSetSize;
259 259 if(pmc.PeakPagefileUsage > max_mem_usage)
260 260 max_mem_usage = pmc.PeakPagefileUsage;
261 261 }
262 262 CloseHandle(hProcess);
263 263 if(actual_usage != NULL)
264 264 (*actual_usage) = max_mem_usage;
265 265 return (max_mem_usage <= max_mem);
266 266 }
267 267
268 268 void report_stat(double time_used, int memory_used)
269 269 {
270 270 fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n",
271 271 time_used,
272 272 time_used, (double)0,
273 273 memory_used);
274 274 }
275 275
276 276 double get_process_time_usage(HANDLE hProcess)
277 277 {
278 278 FILETIME creation_time;
279 279 FILETIME exit_time;
280 280 FILETIME kernel_time;
281 281 FILETIME user_time;
282 282 GetProcessTimes(hProcess,
283 283 &creation_time,
284 284 &exit_time,
285 285 &kernel_time,
286 286 &user_time);
287 287
288 288 SYSTEMTIME sys_kernel_time;
289 289 SYSTEMTIME sys_user_time;
290 290 FileTimeToSystemTime(&kernel_time, &sys_kernel_time);
291 291 FileTimeToSystemTime(&user_time, &sys_user_time);
292 292
293 293 double time_used =
294 294 ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) +
295 295 (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0));
296 296 return time_used;
297 297 }
298 298
299 299 int execute(char *exname, char *inname, char *outname, double t, int max_mem)
300 300 {
301 301 STARTUPINFO si;
302 302 PROCESS_INFORMATION pi;
303 303 int ifsuccess = EXE_RESULT_OK;
304 +
305 + SetErrorMode(SEM_FAILCRITICALERRORS);
306 + SetErrorMode(SEM_NOGPFAULTERRORBOX);
304 307
305 308 ZeroMemory(&si, sizeof(si));
306 309 si.cb = sizeof(si);
307 310 ZeroMemory(&pi, sizeof(pi));
308 311
309 312 setstartupinfo(&si, inname, outname);
310 313
311 314 if(!CreateProcess( NULL, // No module name (use command line).
312 315 TEXT(exname), // Command line.
313 316 NULL, // Process handle not inheritable.
314 317 NULL, // Thread handle not inheritable.
315 318 TRUE, // Set handle inheritance to FALSE.
316 319 0, // No creation flags.
317 320 NULL, // Use parent's environment block.
318 321 NULL, // Use parent's starting directory.
319 322 &si, // Pointer to STARTUPINFO structure.
320 323 &pi)) // Pointer to PROCESS_INFORMATION structure.
321 324 {
322 325 //printf( "CreateProcess failed (%d).\n", GetLastError() );
323 326 fprintf(stderr, "Process creation error.\n");
324 327 report_stat(0,0);
325 328 return EXE_RESULT_ERROR;
326 329 }
327 330 //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId);
328 331 //fprintf(stderr,"time limit = %d\n",t);
329 332
330 333 // checking memory usage
331 334 // wait 0.1 sec before checking mem usage
332 335
333 336 SetProcessWorkingSetSize(pi.hProcess,
334 337 1,
335 338 max_mem);
336 339 int actual_memory_usage = 0;
337 340
338 341 Sleep(INITIAL_WAIT_FOR_MEM_CHECK);
339 342 if(!check_memory_usage(pi.dwProcessId,max_mem,&actual_memory_usage)) {
340 343 // using too much memory
341 344 fprintf(stderr,"Memory limit exceeded.\n");
342 345 //PrintMemoryInfo(pi.dwProcessId);
343 346 ifsuccess = EXE_RESULT_MEMORY;
344 347 }
345 348
346 349 //printf("PID: %d\n", pi.dwProcessId);
347 350
348 351 if(ifsuccess != EXE_RESULT_MEMORY) {
349 352 int based_time = (int)(t*1000) + 1 - INITIAL_WAIT_FOR_MEM_CHECK;
350 353 bool major_timed_out = (WaitForSingleObject(pi.hProcess,
351 354 based_time)==WAIT_TIMEOUT);
352 355 if(major_timed_out) {
353 356 // wait some more for user time.
354 357 double time_used = get_process_time_usage(pi.hProcess);
355 358 while(time_used <= t) {
356 359 int iter_time = 100;
357 360 if(t - time_used < 200)
358 361 iter_time = 20;
359 362 bool iter_timed_out = (WaitForSingleObject(pi.hProcess,
360 363 iter_time)==WAIT_TIMEOUT);
361 364 if(!iter_timed_out)
362 365 break;
363 366
364 367 time_used = get_process_time_usage(pi.hProcess);
365 368 //printf("%lf\n",time_used);
366 369 }
367 370 ifsuccess = EXE_RESULT_TIMEOUT;
368 371 }
369 372 }
370 373
371 374 if((ifsuccess == EXE_RESULT_MEMORY) || (ifsuccess == EXE_RESULT_TIMEOUT)) {
372 375 // Kill process, because (1) it used too much memory, or (2) time limit
373 376 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
374 377
375 378 if(ifsuccess != EXE_RESULT_MEMORY)
376 379 fprintf(stderr,"Time limit exceeded.\n");
377 380 if(hProcess != NULL) {
378 381 fprintf(stderr,"killing pid: %ld\n",pi.dwProcessId);
379 382 TerminateProcess(hProcess, 0);
380 383 wait_dialog();
381 384 } else {
382 385 DWORD dwNtvdmId = get_ntvdm_pid();
383 386 fprintf(stderr,"killing (ntvdm) pid: %ld\n",dwNtvdmId);
384 387 if(dwNtvdmId!=0) {
385 388 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwNtvdmId);
386 389 TerminateProcess(hProcess, 0);
387 390 } else {
388 391 fprintf(stderr,"killing process error\n");
389 392 }
390 393
391 394 if(get_ntvdm_pid()!=0) {
392 395 fprintf(stderr,"killing error, ntvdm.exe still remains;");
393 396 fprintf(stderr,"please MANUALLY kill it.");
394 397 fflush(stderr);
395 398 do {
396 399 Sleep(1000);
397 400 } while(get_ntvdm_pid()!=0);
398 401 fprintf(stderr,"... done\n");
399 402 wait_dialog();
400 403 }
401 404 }
402 405 if(ifsuccess != EXE_RESULT_MEMORY)
403 406 ifsuccess = EXE_RESULT_TIMEOUT;
404 407 }
405 408
406 409 // check memory after terminated
407 410 if((ifsuccess==EXE_RESULT_OK) &&
408 411 (!check_memory_usage(pi.dwProcessId,max_mem, &actual_memory_usage))) {
409 412 // using too much memory
410 413 ifsuccess = EXE_RESULT_MEMORY;
411 414 }
412 415
413 416 // check return code
414 417 if(ifsuccess==EXE_RESULT_OK) {
415 418 DWORD exitcode;
416 419 GetExitCodeProcess(pi.hProcess, &exitcode);
417 420 if(exitcode!=0) {
418 421 fprintf(stderr,"Exit status %d.\n", (int)exitcode);
419 422 ifsuccess = EXE_RESULT_ERROR;
420 423 }
421 424 }
422 425
423 426 wait_dialog();
424 427
425 428 if(si.hStdInput!=NULL)
426 429 CloseHandle(si.hStdInput);
427 430 if(si.hStdOutput!=NULL)
428 431 CloseHandle(si.hStdOutput);
429 432
430 433 if(ifsuccess==EXE_RESULT_OK)
431 434 fprintf(stderr,"OK\n");
432 435 else if(ifsuccess==EXE_RESULT_TIMEOUT)
433 436 fprintf(stderr,"Time limit exceeded.\n");
434 437 else if(ifsuccess==EXE_RESULT_MEMORY)
435 438 fprintf(stderr,"Memory limit exceeded.\n");
436 439
437 440 double actual_time_usage = get_process_time_usage(pi.hProcess);
438 441 /*
439 442 if(ifsuccess==EXE_RESULT_TIMEOUT)
440 443 actual_time_usage = t+1;
441 444 else
442 445 actual_time_usage = t;
443 446 */
444 447
445 448 report_stat(actual_time_usage,
446 449 (actual_memory_usage + 1023)/1024);
447 450
448 451 return ifsuccess;
449 452 }
450 453
You need to be logged in to leave comments. Login now