/** * @brief Copy input color image to ouput image, with respect to mask image * @param imIn : input color image * @param imMask : mask image * @param [out] imOut : output color image */ template<typename Tin, typename Tmask, typename Tout> void ImCopy(const DipImage<Tin> & imIn, const DipImage<Tmask> & imMask, DipImage<Tout> & imOut) { dbi.WriteEnter("Entering ImCopy_WithMask\n"); //~ const int w = imIn.width(), h = imIn.height(); //~ for(int i = 0; i < w; i++){ //~ for(int j = 0; j< h; j++){ //~ if(imMask(i,j) != 255){ //~ imOut(i,j) = imIn(i,j); //~ } //~ else{ //~ imOut(i,j) = 0; //~ } //~ } //~ } if (sizeof(Tin) <= sizeof(Tout)){ const Tin * p_in = &imIn(0,0); const Tin * p_inend = p_in + imIn.width() * imIn.height(); const Tmask * p_mask = &imMask(0,0); Tout * p_out = &imOut(0,0); for (; p_in != p_inend; p_in++, p_out++, p_mask++){ if (*p_mask != 0){ *p_out = Tout(*p_in); } } } dbi.WriteOut("Leaving ImCopy_WithMask\n"); }
/** * @brief Copy input color image to ouput image, with respect to mask image * @param imIn : input color image * @param [out] imOut : output color image */ template<typename Tin,typename Tout> void ImCopy(const DipColorImage<Tin> & imIn, DipColorImage<Tout> & imOut) { dbi.WriteEnter("Entering ImCopy_WithMask\n"); DipImage<uchar> imMask(imIn.width(), imIn.height()); imMask.init(255); ImCopy(imIn, imMask, imOut); dbi.WriteOut("Leaving ImCopy_WithMask\n"); }
void LinExceptionHandler(int sig) { if (SETTINGS.global.submit_debug_data == 1) { DebugInfo di; di.SendReplay(); di.SendStackTrace(); } abort(); }
bool operator<(const DebugInfo &other) const { int64_t pcPad = pc() - other.pc(); if (pcPad) return pcPad < 0; if (tag() == 'file' && other.tag() != 'file' ) return true; return false; }
LONG WINAPI #else void #endif WinExceptionHandler( #ifdef _MSC_VER LPEXCEPTION_POINTERS info #else int sig #endif ) { if(GLOBALVARS.isTest) { std::cerr << std::endl << "ERROR: Test failed!" << std::endl; _exit(1); #ifdef _MSC_VER return(EXCEPTION_EXECUTE_HANDLER); #endif } if ((SETTINGS.global.submit_debug_data == 1) || MessageBoxA(NULL, _("RttR crashed. Would you like to send debug information to RttR to help us avoiding this crash in the future? Thank you very much!"), _("Error"), MB_YESNO | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND) == IDYES) { VIDEODRIVER.DestroyScreen(); DebugInfo di; di.SendReplay(); di.SendStackTrace( #ifdef _MSC_VER info->ContextRecord #endif ); } if(SETTINGS.global.submit_debug_data == 0) MessageBoxA(NULL, _("RttR crashed. Please restart the application!"), _("Error"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); _exit(1); #ifdef _MSC_VER return(EXCEPTION_EXECUTE_HANDLER); #endif }
static sInt GetBStr(BSTR str,sChar *defString,DebugInfo &to) { sChar *normalStr = BStrToString(str); sInt result = to.MakeString(normalStr); delete[] normalStr; return result; }
void LinExceptionHandler(int /*sig*/) { if(GLOBALVARS.isTest) { std::cerr << std::endl << "ERROR: Test failed!" << std::endl; abort(); } if (SETTINGS.global.submit_debug_data == 1) { DebugInfo di; di.SendReplay(); di.SendStackTrace(); } abort(); }
/** * @brief Copy input color image to ouput image, with respect to mask image * @param imIn : input color image * @param imMask : mask image * @param [out] imOut : output color image */ template<typename Tin, typename Tmask, typename Tout> void ImCopy(const DipColorImage<Tin> & imIn, const DipImage<Tmask> & imMask, DipColorImage<Tout> & imOut) { dbi.WriteEnter("Entering ImCopy_WithMask\n"); const int w = imIn.width(), h = imIn.height(); if (sizeof(Tin) <= sizeof(Tout)){ imOut.init(0); for(int i = 0 ;i < w;i++){ for(int j = 0;j < h;j++){ if(imMask(i,j) !=0){ imOut(i,j)[0] = Tout(imIn(i,j)[0]); imOut(i,j)[1] = Tout(imIn(i,j)[1]); imOut(i,j)[2] = Tout(imIn(i,j)[2]); } } } } dbi.WriteOut("Leaving ImCopy_WithMask\n"); }
sInt MAPFileReader::ScanString(sChar *&string,DebugInfo &to) { sChar buffer[3072]; sInt i; i = 0; while(*string && *string!=' ' && *string!='\r' && *string!='\n' && i<3071) buffer[i++] = *string++; buffer[i++] = 0; return to.MakeString(buffer); }
int main( int argc, char** argv ) { if( argc < 2 ) { fprintf( stderr, "Usage: Sizer <exefile>\n" ); return 1; } DebugInfo info; clock_t time1 = clock(); info.Init(); PDBFileReader pdb; fprintf( stderr, "Reading debug info file %s ...\n", argv[1] ); bool pdbok = pdb.ReadDebugInfo( argv[1], info ); if( !pdbok ) { fprintf( stderr, "ERROR reading file via PDB\n" ); return 1; } fprintf( stderr, "\nProcessing info...\n" ); info.FinishedReading(); info.StartAnalyze(); info.FinishAnalyze(); fprintf( stderr, "Generating report...\n" ); std::string report = info.WriteReport(); clock_t time2 = clock(); float secs = float(time2-time1) / CLOCKS_PER_SEC; fprintf( stderr, "Printing...\n" ); puts( report.c_str() ); fprintf( stderr, "Done in %.2f seconds!\n", secs ); return 0; }
void PDBFileReader::ProcessSymbol(IDiaSymbol *symbol,DebugInfo &to) { DWORD section,offset,rva; enum SymTagEnum tag; ULONGLONG length = 0; sU32 compilandId; IDiaSymbol *compiland = 0; BSTR name = 0, sourceName = 0; sBool codeFlag; symbol->get_symTag((DWORD *) &tag); symbol->get_relativeVirtualAddress(&rva); symbol->get_length(&length); symbol->get_addressSection(§ion); symbol->get_addressOffset(&offset); // is the previous symbol desperately looking for a length? we can help! if(DanglingLengthStart) { to.Symbols[to.Symbols.Count - 1].Size = rva - DanglingLengthStart; DanglingLengthStart = 0; } // get length from type for data if(tag == SymTagData) { IDiaSymbol *type; if(symbol->get_type(&type) == S_OK) { type->get_length(&length); type->Release(); } // if length still zero, just guess and take number of bytes between // this symbol and the next one. if(!length) DanglingLengthStart = rva; } compilandId = CompilandFromSectionOffset(section,offset,codeFlag); Session->symbolById(compilandId,&compiland); if(compiland) compiland->get_name(&sourceName); symbol->get_name(&name); // fill out structure sChar *nameStr = BStrToString(name,"<no name>"); sChar *sourceStr = BStrToString(sourceName,"<no source>"); if(tag == SymTagPublicSymbol) { length = 0; DanglingLengthStart = rva; } DISymbol *outSym = to.Symbols.Add(); outSym->Name.Index = outSym->MangledName.Index = to.MakeString(nameStr); outSym->FileNum = to.GetFileByName(sourceStr); outSym->VA = rva; outSym->Size = (sU32) length; outSym->Class = codeFlag ? DIC_CODE : DIC_DATA; outSym->NameSpNum = to.GetNameSpaceByName(nameStr); // clean up delete[] nameStr; delete[] sourceStr; if(compiland) compiland->Release(); if(sourceName) SysFreeString(sourceName); if(name) SysFreeString(name); }
std::vector<DebugInfo::InfoGroup> DebugInfo::objectInfo() { DebugInfo debugInfo; return debugInfo.collectObjectInfo(); }
void DebugInfo::TokenizeCallback(void *user,sInt uncompSize,sF32 compSize) { DebugInfo *info; DISymbol *sym; sU32 addr; sInt leftSize,availSize,len; ReorderItem *reord; info = (DebugInfo *) user; leftSize = uncompSize; while(leftSize) { // setup availSize = leftSize; addr = info->Address; // find out whether there is a remapping for the current address range if(info->Reorder) { if(!info->Reorder->Find(addr,&reord)) // no match { if(reord) len = sMin<sInt>(availSize,reord->NewVA - addr); else len = availSize; info->Address += len; leftSize -= len; } else { len = sMin<sInt>(availSize,reord->NewVA + reord->NewSize - addr); info->Address += len; leftSize -= len; // just a crude approximation here, gotta fix it somehow availSize = reord->OldSize * len / reord->NewSize; addr = reord->OldVA + (reord->OldSize * (addr - reord->NewVA) + reord->NewSize/2) / reord->NewSize; } } else { info->Address += availSize; leftSize -= availSize; } // try to find symbol for current address while(availSize) { if(!info->FindSymbol(addr,&sym)) // no match { if(sym) // skip to next symbol or everything if there's no next symbol len = sMin<sInt>(availSize,sym->VA - addr); else len = availSize; addr += len; availSize -= len; } else // match with symbol { len = sMin<sInt>(availSize,sym->VA + sym->Size - addr); addr += len; availSize -= len; sym->PackedSize += compSize * 0.125f * len / uncompSize; } } } }
sBool MAPFileReader::ReadDebugInfo(sChar *fileName,DebugInfo &to) { PUnDecorateSymbolName UnDecorateSymbolName = 0; // determine map file name sChar fileBuf[260]; sChar *text; sInt i; sCopyString(fileBuf,fileName,256); for(i=sGetStringLen(fileBuf)-1;i>=0 && fileBuf[i] != '.';i--); if(i > 0) sCopyString(fileBuf + i,".map",260-i); else sAppendString(fileBuf,".map",260); text = (sChar *) sSystem->LoadFile(fileBuf); if(!text) return sFALSE; // load dbghelp.dll to resolve symbol names if available void *module = LoadLibraryA("dbghelp.dll"); if(module) UnDecorateSymbolName = (PUnDecorateSymbolName) GetProcAddress(module,"UnDecorateSymbolName"); // actual reading code sChar *line,buffer[2048]; sInt j,code,data; sInt snum,offs,type,name,VA,fname; sInt symStart = to.Symbols.Count; Section *sec; DISymbol *sym; Sections.Init(); code = to.MakeString("CODE"); data = to.MakeString("DATA"); while(*text) { // find end of line line = text; while(*text && *text != '\n') text++; if(text[-1] == '\r' && text[0] == '\n') text[-1] = 0; if(*text) *text++ = 0; // parse this line of text if(line[0]==' ' && IsHexString(line+1,4) && line[5]==':' && IsHexString(line+6,8) && line[14]==' ') { if(IsHexString(line+15,8)) // section definition { sec = Sections.Add(); line += 1; sec->Num = sScanHex(line); line += 1; sec->Start = sScanHex(line); line += 1; sec->Length = sScanHex(line); line += 2; sec->Name.Index = ScanString(line,to); sScanSpace(line); type = ScanString(line,to); if(type == code) sec->Class = DIC_CODE; else if(type == data) sec->Class = DIC_DATA; else sec->Class = DIC_UNKNOWN; sec->Seen = sFALSE; } else // assume name definition { line += 1; snum = sScanHex(line); line += 1; offs = sScanHex(line); sec = GetSection(snum,offs); if(sec) { sScanSpace(line); name = ScanString(line,to); sScanSpace(line); VA = sScanHex(line); line += 5; fname = ScanString(line,to); if(!sec->Seen) { sym = to.Symbols.Add(); sSPrintF(buffer,2048,"__end%s",to.GetStringPrep(sec->Name.Index)); sym->Name.Index = to.MakeString(buffer); sym->FileNum = -1; sym->VA = VA-offs+sec->Start+sec->Length; sym->Size = 0; sym->Class = DIC_END; sec->Seen = sTRUE; } if(UnDecorateSymbolName) UnDecorateSymbolName(to.GetStringPrep(name),buffer,2048,0x1800); else sCopyString(buffer,to.GetStringPrep(name),2048); // add symbol sym = to.Symbols.Add(); sym->Name.Index = to.MakeString(buffer); sym->MangledName.Index = name; sym->FileNum = to.GetFile(fname); sym->VA = VA; sym->Size = 0; sym->Class = sec->Class; sym->NameSpNum = to.GetNameSpaceByName(buffer); } } } else if(!sCmpMem(line," Preferred load address is ",28) && IsHexString(line+28,8)) { line += 28; sU32 base = sScanHex(line); to.SetBaseAddress(base); } } // sort symbols by virtual address for(i=symStart+1;i<to.Symbols.Count;i++) for(j=i;j>symStart;j--) if(to.Symbols[j].VA<to.Symbols[j-1].VA) sSwap(to.Symbols[j],to.Symbols[j-1]); // calc sizes for(i=symStart;i<to.Symbols.Count;i++) { sym = &to.Symbols[i]; if(sym->Class!=DIC_END) { sVERIFY(i != to.Symbols.Count-1); sym->Size = sym[1].VA - sym->VA; } } // cleanup Sections.Exit(); delete[] text; return sTRUE; }
void PDBFileReader::ReadEverything(DebugInfo &to) { ULONG celt; Contribs = 0; nContribs = 0; // read section table IDiaEnumTables *enumTables; if(Session->getEnumTables(&enumTables) == S_OK) { VARIANT vIndex; vIndex.vt = VT_BSTR; vIndex.bstrVal = SysAllocString(L"Sections"); IDiaTable *secTable; if(enumTables->Item(vIndex,&secTable) == S_OK) { LONG count; secTable->get_Count(&count); Contribs = new SectionContrib[count]; nContribs = 0; IDiaSectionContrib *item; while(SUCCEEDED(secTable->Next(1,(IUnknown **)&item,&celt)) && celt == 1) { SectionContrib &contrib = Contribs[nContribs++]; item->get_addressOffset(&contrib.Offset); item->get_addressSection(&contrib.Section); item->get_length(&contrib.Length); item->get_compilandId(&contrib.Compiland); BOOL code=FALSE,initData=FALSE,uninitData=FALSE; item->get_code(&code); item->get_initializedData(&initData); item->get_uninitializedData(&uninitData); if(code && !initData && !uninitData) contrib.Type = DIC_CODE; else if(!code && initData && !uninitData) contrib.Type = DIC_DATA; else if(!code && !initData && uninitData) contrib.Type = DIC_BSS; else contrib.Type = DIC_UNKNOWN; BSTR objFileName = 0; IDiaSymbol *compiland = 0; item->get_compiland(&compiland); if(compiland) { compiland->get_name(&objFileName); compiland->Release(); } sChar *objFileStr = BStrToString(objFileName,"<noobjfile>"); contrib.ObjFile = to.GetFileByName(objFileStr); delete[] objFileStr; if(objFileName) SysFreeString(objFileName); item->Release(); } secTable->Release(); } SysFreeString(vIndex.bstrVal); enumTables->Release(); } // enumerate symbols by (virtual) address IDiaEnumSymbolsByAddr *enumByAddr; if(SUCCEEDED(Session->getSymbolsByAddr(&enumByAddr))) { IDiaSymbol *symbol; // get first symbol to get first RVA (argh) if(SUCCEEDED(enumByAddr->symbolByAddr(1,0,&symbol))) { DWORD rva; if(symbol->get_relativeVirtualAddress(&rva) == S_OK) { symbol->Release(); // now, enumerate by rva. if(SUCCEEDED(enumByAddr->symbolByRVA(rva,&symbol))) { do { ProcessSymbol(symbol,to); symbol->Release(); if(FAILED(enumByAddr->Next(1,&symbol,&celt))) break; } while(celt == 1); } } else symbol->Release(); } enumByAddr->Release(); } // clean up delete[] Contribs; }
void PDBFileReader::ProcessSymbol(IDiaSymbol *symbol,DebugInfo &to) { // print a dot for each 1000 symbols processed static int counter = 0; ++counter; if( counter == 1000 ) { fputc( '.', stderr ); counter = 0; } DWORD section,offset,rva; enum SymTagEnum tag; ULONGLONG length = 0; BSTR name = 0, srcFileName = 0; symbol->get_symTag((DWORD *) &tag); symbol->get_relativeVirtualAddress(&rva); symbol->get_length(&length); symbol->get_addressSection(§ion); symbol->get_addressOffset(&offset); // get length from type for data if( tag == SymTagData ) { IDiaSymbol *type = NULL; if( symbol->get_type(&type) == S_OK ) // no SUCCEEDED test as may return S_FALSE! { if( FAILED(type->get_length(&length)) ) length = 0; type->Release(); } else length = 0; } const SectionContrib *contrib = ContribFromSectionOffset(section,offset); sInt objFile = 0; sInt sectionType = DIC_UNKNOWN; if(contrib) { objFile = contrib->ObjFile; sectionType = contrib->Type; } symbol->get_name(&name); // fill out structure sChar *nameStr = BStrToString( name, "<noname>", true); to.Symbols.push_back( DISymbol() ); DISymbol *outSym = &to.Symbols.back(); outSym->name = outSym->mangledName = to.MakeString(nameStr); outSym->objFileNum = objFile; outSym->VA = rva; outSym->Size = (sU32) length; outSym->Class = sectionType; outSym->NameSpNum = to.GetNameSpaceByName(nameStr); // clean up delete[] nameStr; if(name) SysFreeString(name); }