void Track::parse (void) { int i; pSB (header); name = currPos; currPos += 40; pSI (numStrings); for (i = 0; i < numStrings; i ++) { tuneTable.push_back (*(struct Gp5StringTune*)currPos); currPos += sizeof (struct Gp5StringTune); } pSI (port); pSI (channel); pSI (effectChannel); pSI (numFrets); pSI (capoHeight); color = *(struct Gp5Color*)currPos; currPos += sizeof (struct Gp5Color); size = currPos - start; }
/* \brief Writes a simple stack trace to the XBMC user directory. It needs a valid .pdb file to show the method, filename and line number where the exception took place. */ bool win32_exception::write_stacktrace(EXCEPTION_POINTERS* pEp) { #define STACKWALK_MAX_NAMELEN 1024 std::string dumpFileName, strOutput; std::wstring dumpFileNameW; CHAR cTemp[STACKWALK_MAX_NAMELEN]; DWORD dwBytes; SYSTEMTIME stLocalTime; GetLocalTime(&stLocalTime); bool returncode = false; STACKFRAME64 frame = { 0 }; HANDLE hCurProc = GetCurrentProcess(); IMAGEHLP_SYMBOL64* pSym = NULL; HANDLE hDumpFile = INVALID_HANDLE_VALUE; tSC pSC = NULL; HMODULE hDbgHelpDll = ::LoadLibrary(L"DBGHELP.DLL"); if (!hDbgHelpDll) { goto cleanup; } tSI pSI = (tSI) GetProcAddress(hDbgHelpDll, "SymInitialize" ); tSGO pSGO = (tSGO) GetProcAddress(hDbgHelpDll, "SymGetOptions" ); tSSO pSSO = (tSSO) GetProcAddress(hDbgHelpDll, "SymSetOptions" ); pSC = (tSC) GetProcAddress(hDbgHelpDll, "SymCleanup" ); tSW pSW = (tSW) GetProcAddress(hDbgHelpDll, "StackWalk64" ); tSGSFA pSGSFA = (tSGSFA) GetProcAddress(hDbgHelpDll, "SymGetSymFromAddr64" ); tUDSN pUDSN = (tUDSN) GetProcAddress(hDbgHelpDll, "UnDecorateSymbolName" ); tSGLFA pSGLFA = (tSGLFA) GetProcAddress(hDbgHelpDll, "SymGetLineFromAddr64" ); tSFTA pSFTA = (tSFTA) GetProcAddress(hDbgHelpDll, "SymFunctionTableAccess64" ); tSGMB pSGMB = (tSGMB) GetProcAddress(hDbgHelpDll, "SymGetModuleBase64" ); if(pSI == NULL || pSGO == NULL || pSSO == NULL || pSC == NULL || pSW == NULL || pSGSFA == NULL || pUDSN == NULL || pSGLFA == NULL || pSFTA == NULL || pSGMB == NULL) goto cleanup; dumpFileName = StringUtils::Format("kodi_stacktrace-%s-%04d%02d%02d-%02d%02d%02d.txt", mVersion.c_str(), stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); dumpFileName = CWIN32Util::SmbToUnc(URIUtils::AddFileToFolder(CWIN32Util::GetProfilePath(), CUtil::MakeLegalFileName(dumpFileName))); dumpFileNameW = KODI::PLATFORM::WINDOWS::ToW(dumpFileName); hDumpFile = CreateFileW(dumpFileNameW.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if (hDumpFile == INVALID_HANDLE_VALUE) { goto cleanup; } frame.AddrPC.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing frame.AddrStack.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing frame.AddrFrame.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing #if defined(_X86_) frame.AddrPC.Offset = pEp->ContextRecord->Eip; // Current location in program frame.AddrStack.Offset = pEp->ContextRecord->Esp; // Stack pointers current value frame.AddrFrame.Offset = pEp->ContextRecord->Ebp; // Value of register used to access local function variables. #else frame.AddrPC.Offset = pEp->ContextRecord->Rip; // Current location in program frame.AddrStack.Offset = pEp->ContextRecord->Rsp; // Stack pointers current value frame.AddrFrame.Offset = pEp->ContextRecord->Rbp; // Value of register used to access local function variables. #endif if(pSI(hCurProc, NULL, TRUE) == FALSE) goto cleanup; DWORD symOptions = pSGO(); symOptions |= SYMOPT_LOAD_LINES; symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; symOptions &= ~SYMOPT_UNDNAME; symOptions &= ~SYMOPT_DEFERRED_LOADS; symOptions = pSSO(symOptions); pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); if (!pSym) goto cleanup; memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; IMAGEHLP_LINE64 Line; memset(&Line, 0, sizeof(Line)); Line.SizeOfStruct = sizeof(Line); IMAGEHLP_MODULE64 Module; memset(&Module, 0, sizeof(Module)); Module.SizeOfStruct = sizeof(Module); int seq=0; strOutput = StringUtils::Format("Thread %d (process %d)\r\n", GetCurrentThreadId(), GetCurrentProcessId()); WriteFile(hDumpFile, strOutput.c_str(), strOutput.size(), &dwBytes, NULL); while(pSW(IMAGE_FILE_MACHINE_I386, hCurProc, GetCurrentThread(), &frame, pEp->ContextRecord, NULL, pSFTA, pSGMB, NULL)) { if(frame.AddrPC.Offset != 0) { DWORD64 symoffset=0; DWORD lineoffset=0; strOutput = StringUtils::Format("#%2d", seq++); if(pSGSFA(hCurProc, frame.AddrPC.Offset, &symoffset, pSym)) { if(pUDSN(pSym->Name, cTemp, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE)>0) strOutput.append(StringUtils::Format(" %s", cTemp)); } if(pSGLFA(hCurProc, frame.AddrPC.Offset, &lineoffset, &Line)) strOutput.append(StringUtils::Format(" at %s:%d", Line.FileName, Line.LineNumber)); strOutput.append("\r\n"); WriteFile(hDumpFile, strOutput.c_str(), strOutput.size(), &dwBytes, NULL); } } returncode = true; cleanup: if (pSym) free( pSym ); if (hDumpFile != INVALID_HANDLE_VALUE) CloseHandle(hDumpFile); if(pSC) pSC(hCurProc); if (hDbgHelpDll) FreeLibrary(hDbgHelpDll); return returncode; }