diff options
author | Jacek Antonelli | 2009-02-12 02:06:41 -0600 |
---|---|---|
committer | Jacek Antonelli | 2009-02-12 02:06:45 -0600 |
commit | 61f97b33f9850d21965d397b947a298c16ba576d (patch) | |
tree | a2edff0a7fbc83e2259eda952511b0fbdbea290b /linden/indra/newview/llwindebug.cpp | |
parent | Second Life viewer sources 1.22.7-RC (diff) | |
download | meta-impy-61f97b33f9850d21965d397b947a298c16ba576d.zip meta-impy-61f97b33f9850d21965d397b947a298c16ba576d.tar.gz meta-impy-61f97b33f9850d21965d397b947a298c16ba576d.tar.bz2 meta-impy-61f97b33f9850d21965d397b947a298c16ba576d.tar.xz |
Second Life viewer sources 1.22.8-RC
Diffstat (limited to 'linden/indra/newview/llwindebug.cpp')
-rw-r--r-- | linden/indra/newview/llwindebug.cpp | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/linden/indra/newview/llwindebug.cpp b/linden/indra/newview/llwindebug.cpp index b595073..4e326ed 100644 --- a/linden/indra/newview/llwindebug.cpp +++ b/linden/indra/newview/llwindebug.cpp | |||
@@ -121,6 +121,14 @@ MODULE32_NEST Module32Next_; | |||
121 | #define CALL_TRACE_MAX ((DUMP_SIZE_MAX - 2000) / (MAX_PATH + 40)) //max number of traced calls | 121 | #define CALL_TRACE_MAX ((DUMP_SIZE_MAX - 2000) / (MAX_PATH + 40)) //max number of traced calls |
122 | #define NL L"\r\n" //new line | 122 | #define NL L"\r\n" //new line |
123 | 123 | ||
124 | |||
125 | typedef struct STACK | ||
126 | { | ||
127 | STACK * Ebp; | ||
128 | PBYTE Ret_Addr; | ||
129 | DWORD Param[0]; | ||
130 | } STACK, * PSTACK; | ||
131 | |||
124 | BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr); | 132 | BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr); |
125 | void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, | 133 | void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, |
126 | const CONTEXT* context_record, | 134 | const CONTEXT* context_record, |
@@ -337,6 +345,31 @@ PBYTE get_valid_frame(PBYTE esp) | |||
337 | 345 | ||
338 | return NULL; | 346 | return NULL; |
339 | } | 347 | } |
348 | |||
349 | bool shouldUseStackWalker(PSTACK Ebp, int max_depth) | ||
350 | { | ||
351 | WCHAR Module_Name[MAX_PATH]; | ||
352 | PBYTE Module_Addr = 0; | ||
353 | int depth = 0; | ||
354 | |||
355 | while (depth < max_depth) | ||
356 | { | ||
357 | if (IsBadReadPtr(Ebp, sizeof(PSTACK)) || | ||
358 | IsBadReadPtr(Ebp->Ebp, sizeof(PSTACK)) || | ||
359 | Ebp->Ebp < Ebp || | ||
360 | Ebp->Ebp - Ebp > 0xFFFFFF || | ||
361 | IsBadCodePtr(FARPROC(Ebp->Ebp->Ret_Addr)) || | ||
362 | !Get_Module_By_Ret_Addr(Ebp->Ebp->Ret_Addr, Module_Name, Module_Addr)) | ||
363 | { | ||
364 | return true; | ||
365 | } | ||
366 | depth++; | ||
367 | Ebp = Ebp->Ebp; | ||
368 | } | ||
369 | |||
370 | return false; | ||
371 | } | ||
372 | |||
340 | //****************************************************************** | 373 | //****************************************************************** |
341 | void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, | 374 | void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, |
342 | const CONTEXT* context_record, | 375 | const CONTEXT* context_record, |
@@ -354,17 +387,10 @@ void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, | |||
354 | 387 | ||
355 | bool fake_frame = false; | 388 | bool fake_frame = false; |
356 | bool ebp_used = false; | 389 | bool ebp_used = false; |
357 | const int HEURISTIC_MAX_WALK = 10; | 390 | const int HEURISTIC_MAX_WALK = 20; |
358 | int heuristic_walk_i = 0; | 391 | int heuristic_walk_i = 0; |
359 | int Ret_Addr_I = 0; | 392 | int Ret_Addr_I = 0; |
360 | 393 | ||
361 | typedef struct STACK | ||
362 | { | ||
363 | STACK * Ebp; | ||
364 | PBYTE Ret_Addr; | ||
365 | DWORD Param[0]; | ||
366 | } STACK, * PSTACK; | ||
367 | |||
368 | STACK Stack = {0, 0}; | 394 | STACK Stack = {0, 0}; |
369 | PSTACK Ebp; | 395 | PSTACK Ebp; |
370 | 396 | ||
@@ -433,10 +459,9 @@ void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, | |||
433 | 459 | ||
434 | // is next ebp valid? | 460 | // is next ebp valid? |
435 | // only run if we've never found a good ebp | 461 | // only run if we've never found a good ebp |
462 | // and make sure the one after is valid as well | ||
436 | if( !ebp_used && | 463 | if( !ebp_used && |
437 | (IsBadReadPtr(Ebp->Ebp, sizeof(PSTACK)) || | 464 | shouldUseStackWalker(Ebp, 2)) |
438 | IsBadCodePtr(FARPROC(Ebp->Ebp->Ret_Addr)) || | ||
439 | !Get_Module_By_Ret_Addr(Ebp->Ebp->Ret_Addr, Module_Name, Module_Addr))) | ||
440 | { | 465 | { |
441 | heuristic_walk_i++; | 466 | heuristic_walk_i++; |
442 | PBYTE new_ebp = get_valid_frame(Esp); | 467 | PBYTE new_ebp = get_valid_frame(Esp); |
@@ -451,9 +476,9 @@ void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, | |||
451 | Ebp = Ebp->Ebp; | 476 | Ebp = Ebp->Ebp; |
452 | } | 477 | } |
453 | } | 478 | } |
454 | 479 | /* TODO remove or turn this code back on to edit the stack after i see a few raw ones. -Palmer | |
455 | // Now go back through and edit out heuristic stacks that could very well be bogus. | 480 | // Now go back through and edit out heuristic stacks that could very well be bogus. |
456 | // Leave the top and the last stack chosen by the heuristic, however. | 481 | // Leave the top and the last 3 stack chosen by the heuristic, however. |
457 | if(heuristic_walk_i > 2) | 482 | if(heuristic_walk_i > 2) |
458 | { | 483 | { |
459 | info["CallStack"][0] = tmp_info["CallStack"][0]; | 484 | info["CallStack"][0] = tmp_info["CallStack"][0]; |
@@ -470,7 +495,10 @@ void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, | |||
470 | { | 495 | { |
471 | info = tmp_info; | 496 | info = tmp_info; |
472 | } | 497 | } |
473 | 498 | */ | |
499 | info = tmp_info; | ||
500 | info["HeuristicWalkI"] = heuristic_walk_i; | ||
501 | info["EbpUsed"] = ebp_used; | ||
474 | 502 | ||
475 | } //Get_Call_Stack | 503 | } //Get_Call_Stack |
476 | 504 | ||