aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llwindebug.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:50 -0500
committerJacek Antonelli2008-08-15 23:45:50 -0500
commit2a4dea528f670b9bb1f77ef27a8a1dd16603d114 (patch)
tree95c68e362703c9099d571ecbdc6142b1cda1e005 /linden/indra/newview/llwindebug.cpp
parentSecond Life viewer sources 1.20.6 (diff)
downloadmeta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.zip
meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.tar.gz
meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.tar.bz2
meta-impy-2a4dea528f670b9bb1f77ef27a8a1dd16603d114.tar.xz
Second Life viewer sources 1.20.7
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llwindebug.cpp154
1 files changed, 67 insertions, 87 deletions
diff --git a/linden/indra/newview/llwindebug.cpp b/linden/indra/newview/llwindebug.cpp
index 1b52a14..aba637c 100644
--- a/linden/indra/newview/llwindebug.cpp
+++ b/linden/indra/newview/llwindebug.cpp
@@ -35,7 +35,6 @@
35 35
36#include <tchar.h> 36#include <tchar.h>
37#include <tlhelp32.h> 37#include <tlhelp32.h>
38#include "llappviewer.h"
39#include "llwindebug.h" 38#include "llwindebug.h"
40#include "llviewercontrol.h" 39#include "llviewercontrol.h"
41#include "lldir.h" 40#include "lldir.h"
@@ -106,6 +105,8 @@ MINIDUMPWRITEDUMP f_mdwp = NULL;
106 105
107#undef UNICODE 106#undef UNICODE
108 107
108static LPTOP_LEVEL_EXCEPTION_FILTER gFilterFunc = NULL;
109
109HMODULE hDbgHelp; 110HMODULE hDbgHelp;
110 111
111// Tool Help functions. 112// Tool Help functions.
@@ -554,14 +555,13 @@ void LLMemoryReserve::release()
554static LLMemoryReserve gEmergencyMemoryReserve; 555static LLMemoryReserve gEmergencyMemoryReserve;
555 556
556// static 557// static
557BOOL LLWinDebug::setupExceptionHandler() 558void LLWinDebug::initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func)
558{ 559{
559 560
560 static BOOL s_first_run = TRUE; 561 static bool s_first_run = true;
561 // Load the dbghelp dll now, instead of waiting for the crash. 562 // Load the dbghelp dll now, instead of waiting for the crash.
562 // Less potential for stack mangling 563 // Less potential for stack mangling
563 564
564 BOOL ok = TRUE;
565 if (s_first_run) 565 if (s_first_run)
566 { 566 {
567 // First, try loading from the directory that the app resides in. 567 // First, try loading from the directory that the app resides in.
@@ -576,15 +576,7 @@ BOOL LLWinDebug::setupExceptionHandler()
576 576
577 if (!hDll) 577 if (!hDll)
578 { 578 {
579 llwarns << "Couldn't find dbghelp.dll!" << llendl; 579 LL_WARNS("AppInit") << "Couldn't find dbghelp.dll!" << LL_ENDL;
580
581 std::string msg = "Couldn't find dbghelp.dll at ";
582 msg += local_dll_name;
583 msg += "!\n";
584
585 //write_debug(msg.c_str());
586
587 ok = FALSE;
588 } 580 }
589 else 581 else
590 { 582 {
@@ -592,18 +584,15 @@ BOOL LLWinDebug::setupExceptionHandler()
592 584
593 if (!f_mdwp) 585 if (!f_mdwp)
594 { 586 {
595 //write_debug("No MiniDumpWriteDump!\n");
596 FreeLibrary(hDll); 587 FreeLibrary(hDll);
597 hDll = NULL; 588 hDll = NULL;
598 ok = FALSE;
599 } 589 }
600 } 590 }
601 591
602 gEmergencyMemoryReserve.reserve(); 592 gEmergencyMemoryReserve.reserve();
603 }
604 593
605 LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; 594 s_first_run = false;
606 prev_filter = SetUnhandledExceptionFilter(LLWinDebug::handleException); 595 }
607 596
608 // Try to get Tool Help library functions. 597 // Try to get Tool Help library functions.
609 HMODULE hKernel32; 598 HMODULE hKernel32;
@@ -612,26 +601,44 @@ BOOL LLWinDebug::setupExceptionHandler()
612 Module32First_ = (MODULE32_FIRST)GetProcAddress(hKernel32, "Module32FirstW"); 601 Module32First_ = (MODULE32_FIRST)GetProcAddress(hKernel32, "Module32FirstW");
613 Module32Next_ = (MODULE32_NEST)GetProcAddress(hKernel32, "Module32NextW"); 602 Module32Next_ = (MODULE32_NEST)GetProcAddress(hKernel32, "Module32NextW");
614 603
615 if (s_first_run) 604 LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
605 prev_filter = SetUnhandledExceptionFilter(filter_func);
606
607 if(prev_filter != gFilterFunc)
616 { 608 {
617 // We're fine, this is the first run. 609 LL_WARNS("AppInit")
618 s_first_run = FALSE; 610 << "Replacing unknown exception (" << (void *)prev_filter << ") with (" << (void *)filter_func << ") !" << LL_ENDL;
619 return ok;
620 } 611 }
621 if (!prev_filter) 612
613 gFilterFunc = filter_func;
614}
615
616bool LLWinDebug::checkExceptionHandler()
617{
618 bool ok = true;
619 LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
620 prev_filter = SetUnhandledExceptionFilter(gFilterFunc);
621
622 if (prev_filter != gFilterFunc)
622 { 623 {
623 llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl; 624 LL_WARNS("AppInit") << "Our exception handler (" << (void *)gFilterFunc << ") replaced with " << prev_filter << "!" << LL_ENDL;
624 ok = FALSE; 625 ok = false;
625 } 626 }
626 if (prev_filter != LLWinDebug::handleException) 627
628 if (prev_filter == NULL)
627 { 629 {
628 llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl;
629 ok = FALSE; 630 ok = FALSE;
631 if (gFilterFunc == NULL)
632 {
633 LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL;
634 }
635 else
636 {
637 LL_WARNS("AppInit") << "Our exception handler (" << (void *)gFilterFunc << ") replaced with NULL!" << LL_ENDL;
638 }
630 } 639 }
631 640
632 return ok; 641 return ok;
633 // Internal builds don't mess with exception handling.
634 //return TRUE;
635} 642}
636 643
637void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const char *filename) 644void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const char *filename)
@@ -644,7 +651,7 @@ void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMAT
644 else 651 else
645 { 652 {
646 std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, 653 std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
647 filename); 654 filename);
648 655
649 HANDLE hFile = CreateFileA(dump_path.c_str(), 656 HANDLE hFile = CreateFileA(dump_path.c_str(),
650 GENERIC_WRITE, 657 GENERIC_WRITE,
@@ -672,20 +679,26 @@ void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMAT
672} 679}
673 680
674// static 681// static
675LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop) 682void LLWinDebug::generateCrashStacks(struct _EXCEPTION_POINTERS *exception_infop)
676{ 683{
677 // *NOTE:Mani - This method is no longer the initial exception handler. 684 // *NOTE:Mani - This method is no longer the exception handler.
678 // It is called from viewer_windows_exception_handler() and other places. 685 // Its called from viewer_windows_exception_handler() and other places.
679 686
680 // 687 //
681 // Let go of a bunch of reserved memory to give library calls etc 688 // Let go of a bunch of reserved memory to give library calls etc
682 // a chance to execute normally in the case that we ran out of 689 // a chance to execute normally in the case that we ran out of
683 // memory. 690 // memory.
684 // 691 //
685 gEmergencyMemoryReserve.release(); 692 LLSD info;
693 std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
694 "SecondLifeException");
695 std::string log_path = dump_path + ".log";
686 696
687 if (exception_infop) 697 if (exception_infop)
688 { 698 {
699 // Since there is exception info... Release the hounds.
700 gEmergencyMemoryReserve.release();
701
689 if(gSavedSettings.getControl("SaveMinidump") != NULL && gSavedSettings.getBOOL("SaveMinidump")) 702 if(gSavedSettings.getControl("SaveMinidump") != NULL && gSavedSettings.getBOOL("SaveMinidump"))
690 { 703 {
691 _MINIDUMP_EXCEPTION_INFORMATION ExInfo; 704 _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
@@ -698,67 +711,34 @@ LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop)
698 writeDumpToFile((MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, "SecondLifePlus.dmp"); 711 writeDumpToFile((MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, "SecondLifePlus.dmp");
699 } 712 }
700 713
701
702 std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
703 "SecondLifeException");
704
705 std::string log_path = dump_path + ".log";
706
707 LLSD info;
708 info = Get_Exception_Info(exception_infop); 714 info = Get_Exception_Info(exception_infop);
715 }
709 716
717 LLSD threads;
718 std::vector<DWORD> thread_ids;
719 GetProcessThreadIDs(GetCurrentProcessId(), thread_ids);
710 720
711 LLSD threads; 721 for(std::vector<DWORD>::iterator th_itr = thread_ids.begin();
712 std::vector<DWORD> thread_ids; 722 th_itr != thread_ids.end();
713 GetProcessThreadIDs(GetCurrentProcessId(), thread_ids); 723 ++th_itr)
714 724 {
715 for(std::vector<DWORD>::iterator th_itr = thread_ids.begin(); 725 LLSD thread_info;
716 th_itr != thread_ids.end(); 726 if(*th_itr != GetCurrentThreadId())
717 ++th_itr)
718 { 727 {
719 LLSD thread_info; 728 GetThreadCallStack(*th_itr, thread_info);
720 if(*th_itr != GetCurrentThreadId())
721 {
722 GetThreadCallStack(*th_itr, thread_info);
723 }
724
725 if(thread_info)
726 {
727
728 threads[llformat("ID %d", *th_itr)] = thread_info;
729 }
730 } 729 }
731 730
731 if(thread_info)
732 {
733 threads[llformat("ID %d", *th_itr)] = thread_info;
734 }
735 }
732 736
733 info["Threads"] = threads; 737 info["Threads"] = threads;
734
735 if (info)
736 {
737 std::ofstream out_file(log_path.c_str());
738 LLSDSerialize::toPrettyXML(info, out_file);
739 out_file.close();
740 }
741 }
742 else
743 {
744 // We're calling this due to a network error, not due to an actual exception.
745 // It doesn't realy matter what we return.
746 return EXCEPTION_CONTINUE_SEARCH;
747 }
748
749 //handle viewer crash must be called here since
750 //we don't return handling of the application
751 //back to the process.
752 LLAppViewer::handleViewerCrash();
753 738
754 // 739 std::ofstream out_file(log_path.c_str());
755 // At this point, we always want to exit the app. There's no graceful 740 LLSDSerialize::toPrettyXML(info, out_file);
756 // recovery for an unhandled exception. 741 out_file.close();
757 //
758 // Just kill the process.
759 LONG retval = EXCEPTION_EXECUTE_HANDLER;
760
761 return retval;
762} 742}
763 743
764#endif 744#endif