1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: dbg_Break.cpp 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 48011 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/Result.h> 17 #include <nn/dbg/dbg_Break.h> 18 #include <nn/dbg/dbg_DebugString.h> 19 #include <nn/svc.h> 20 #include <nn/config.h> 21 #include <cstdarg> 22 23 using namespace nn::dbg; 24 25 namespace 26 { 27 nn::dbg::BreakHandler s_pBreakHandler = NULL; 28 PrintErrorMessageHeader(nndbgBreakReason reason,const char * filename,int lineno)29 void PrintErrorMessageHeader(nndbgBreakReason reason, const char* filename, int lineno) 30 { 31 detail::TPrintf("----\n"); 32 if( reason == NN_DBG_BREAK_REASON_ASSERT ) 33 { 34 detail::TPrintf("Assertion failure at %s:%d\n ", filename, lineno); 35 } 36 else 37 { 38 detail::TPrintf("Panic at %s:%d\n ", filename, lineno); 39 } 40 } 41 CallBreakHandler(BreakReason reason,nn::Result * pResult,const char * filename,int lineno,const char * fmt,std::va_list args)42 void CallBreakHandler(BreakReason reason, nn::Result* pResult, const char* filename, int lineno, const char* fmt, std::va_list args) 43 { 44 nn::dbg::BreakHandler pBreakHandler = s_pBreakHandler; 45 46 if( pBreakHandler != NULL ) 47 { 48 s_pBreakHandler = NULL; 49 pBreakHandler(reason, pResult, filename, lineno, fmt, args); 50 } 51 } 52 CallBreakHandler(nndbgBreakReason reason,nnResult result,const char * filename,int lineno,const char * fmt,std::va_list args)53 void CallBreakHandler(nndbgBreakReason reason, nnResult result, const char* filename, int lineno, const char* fmt, std::va_list args) 54 { 55 nn::Result resultCpp = result; 56 CallBreakHandler(static_cast<BreakReason>(reason), &resultCpp, filename, lineno, fmt, args); 57 } 58 CallBreakHandler(nndbgBreakReason reason,const char * filename,int lineno,const char * fmt,std::va_list args)59 void CallBreakHandler(nndbgBreakReason reason, const char* filename, int lineno, const char* fmt, std::va_list args) 60 { 61 CallBreakHandler(static_cast<BreakReason>(reason), NULL, filename, lineno, fmt, args); 62 } 63 CallBreakHandler(BreakReason reason)64 void CallBreakHandler(BreakReason reason) 65 { 66 std::va_list args; 67 CallBreakHandler(reason, NULL, NULL, 0, NULL, args); 68 } 69 } 70 71 extern "C" { 72 nndbgBreak(int reason)73 nnResult nndbgBreak(int reason) 74 { 75 return nn::dbg::Break(static_cast<nn::dbg::BreakReason>(reason)); 76 } 77 nndbgPanic()78 void nndbgPanic() 79 { 80 Panic(); 81 } 82 nndbgBreakWithMessage_(nndbgBreakReason reason,const char * filename,int lineno,const char * fmt,...)83 void nndbgBreakWithMessage_ (nndbgBreakReason reason, const char* filename, int lineno, const char* fmt, ...) 84 { 85 va_list arg; 86 va_start(arg, fmt); 87 PrintErrorMessageHeader(reason, filename, lineno); 88 detail::VPrintf(fmt, arg); 89 detail::TPrintf("\n"); 90 va_end(arg); 91 92 va_start(arg, fmt); 93 CallBreakHandler(reason, filename, lineno, fmt, arg); 94 va_end(arg); 95 96 Break(static_cast<BreakReason>(reason)); 97 } 98 nndbgBreakWithTMessage_(nndbgBreakReason reason,const char * filename,int lineno,const char * fmt,...)99 void nndbgBreakWithTMessage_(nndbgBreakReason reason, const char* filename, int lineno, const char* fmt, ...) 100 { 101 va_list arg; 102 va_start(arg, fmt); 103 PrintErrorMessageHeader(reason, filename, lineno); 104 detail::TVPrintf(fmt, arg); 105 detail::TPrintf("\n"); 106 va_end(arg); 107 108 va_start(arg, fmt); 109 CallBreakHandler(reason, filename, lineno, fmt, arg); 110 va_end(arg); 111 112 Break(static_cast<BreakReason>(reason)); 113 } 114 nndbgBreakWithResultMessage_(nndbgBreakReason reason,nnResult result,const char * filename,int lineno,const char * fmt,...)115 void nndbgBreakWithResultMessage_ (nndbgBreakReason reason, nnResult result, const char* filename, int lineno, const char* fmt, ...) 116 { 117 va_list arg; 118 va_start(arg, fmt); 119 PrintErrorMessageHeader(reason, filename, lineno); 120 detail::VPrintf(fmt, arg); 121 detail::TPrintf("\n"); 122 detail::PrintResult(result); 123 va_end(arg); 124 125 va_start(arg, fmt); 126 CallBreakHandler(reason, result, filename, lineno, fmt, arg); 127 va_end(arg); 128 129 Break(static_cast<BreakReason>(reason)); 130 } 131 nndbgBreakWithResultTMessage_(nndbgBreakReason reason,nnResult result,const char * filename,int lineno,const char * fmt,...)132 void nndbgBreakWithResultTMessage_(nndbgBreakReason reason, nnResult result, const char* filename, int lineno, const char* fmt, ...) 133 { 134 va_list arg; 135 va_start(arg, fmt); 136 PrintErrorMessageHeader(reason, filename, lineno); 137 detail::TVPrintf(fmt, arg); 138 detail::TPrintf("\n"); 139 detail::PrintResult(result); 140 va_end(arg); 141 142 va_start(arg, fmt); 143 CallBreakHandler(reason, result, filename, lineno, fmt, arg); 144 va_end(arg); 145 146 Break(static_cast<BreakReason>(reason)); 147 } 148 } 149 150 namespace nn { namespace dbg { 151 Break(BreakReason reason)152 Result Break(BreakReason reason) 153 { 154 CallBreakHandler(reason); 155 return nn::svc::Break(reason, NULL, 0); 156 } 157 Panic()158 void Panic() 159 { 160 Break(BREAK_REASON_PANIC); 161 } 162 SetBreakHandler(BreakHandler handler)163 void SetBreakHandler(BreakHandler handler) 164 { 165 NN_POINTER_TASSERT_(handler); 166 s_pBreakHandler = handler; 167 } 168 169 namespace detail 170 { NotifyDllLoadedToDebugger(const void * pDllInfo,size_t size)171 Result NotifyDllLoadedToDebugger(const void* pDllInfo, size_t size) 172 { 173 return nn::svc::Break(BREAK_REASON_LOAD_RO, pDllInfo, size); 174 } 175 NotifyDllUnloadingToDebugger(const void * pDllInfo,size_t size)176 Result NotifyDllUnloadingToDebugger(const void* pDllInfo, size_t size) 177 { 178 return nn::svc::Break(BREAK_REASON_UNLOAD_RO, pDllInfo, size); 179 } 180 } 181 182 }} 183