dyninst codecoverage
codeCoverage.c/**AsimplecodecoveragetoolusingDyninstAPI**ThistoolusesDyninstAPItoinstrumentthefunctionsandbasicblocksin*anexecutableanditssharedlibrariesinordertorecordcodecoverage*datawhentheexecutableisrun.Thiscodecoveragedataisoutputwhenthe*rewrittenexecutablefinishesrunning.**TheintentofthistoolistodemonstratesomecapabilitiesofDyninstAPI;*itshouldserveasagoodsteppingstonetobuildingamorefeature-rich*codecoveragetoolontopofDyninst.*/#include<cstdlib>#include<iostream>#include<vector>#include<string>usingnamespacestd;//Commandlineparsing#include<getopt.h>//DyninstAPIincludes#include"BPatch.h"#include"BPatch_binaryEdit.h"#include"BPatch_flowGraph.h"#include"BPatch_function.h"#include"BPatch_point.h"usingnamespaceDyninst;staticconstchar*USAGE="[-bpsa]<binary><outputbinary>\n\-b:Basicblocklevelcodecoverage\n\-p:Printallfunctions(includingfunctionsthatareneverexecuted)\n\-s:Instrumentsharedlibrariesalso\n\-a:Sortresultsalphabeticallybyfunctionname\n";staticconstchar*OPT_STR="bpsa";//configurationoptionschar*inBinary=NULL;char*outBinary=NULL;boolincludeSharedLib=false;intprintAll=0;boolbbCoverage=false;intalphabetical=0;set<string>skipLibraries;voidinitSkipLibraries(){/*Listofsharedlibrariestoskipinstrumenting*//*Donotinstrumenttheinstrumentationlibrary*/skipLibraries.insert("libInst.so");skipLibraries.insert("libc.so.6");skipLibraries.insert("libc.so.7");skipLibraries.insert("ld-2.5.so");skipLibraries.insert("ld-linux.so.2");skipLibraries.insert("ld-lsb.so.3");skipLibraries.insert("ld-linux-x86-64.so.2");skipLibraries.insert("ld-lsb-x86-64.so");skipLibraries.insert("ld-elf.so.1");skipLibraries.insert("ld-elf32.so.1");skipLibraries.insert("libstdc++.so.6");return;}boolparseArgs(intargc,char*argv[]){intc;while((c=getopt(argc,argv,OPT_STR))!=-1){switch((char)c){case'b':bbCoverage=true;break;case'p':printAll=1;break;case's':/*ifincludeSharedLibisset,*alllibrarieslinkedtothebinarywillalsobeinstrumented*/includeSharedLib=true;break;case'a':alphabetical=1;break;default:cerr<<"Usage:"<<argv[0]<<USAGE;returnfalse;}}intendArgs=optind;if(endArgs>=argc){cerr<<"Inputbinarynotspecified."<<endl<<"Usage:"<<argv[0]<<USAGE;returnfalse;}/*InputBinary*/inBinary=argv[endArgs];endArgs++;if(endArgs>=argc){cerr<<"Outputbinarynotspecified."<<endl<<"Usage:"<<argv[0]<<USAGE;returnfalse;}/*RewrittenBinary*/outBinary=argv[endArgs];returntrue;}BPatch_function*findFuncByName(BPatch_p_w_picpath*appImage,char*funcName){/*fundFunctionsreturnsalistofallfunctionswiththename'funcName'inthebinary*/BPatch_Vector<BPatch_function*>funcs;if(NULL==appImage->findFunction(funcName,funcs)||!funcs.size()||NULL==funcs[0]){cerr<<"Failedtofind"<<funcName<<"functionintheinstrumentationlibrary"<<endl;returnNULL;}returnfuncs[0];}boolinsertFuncEntry(BPatch_binaryEdit*appBin,BPatch_function*curFunc,char*funcName,BPatch_function*instIncFunc,intfuncId){/*Findtheinstrumentationpoints*/vector<BPatch_point*>*funcEntry=curFunc->findPoint(BPatch_entry);if(NULL==funcEntry){cerr<<"Failedtofindentryforfunction"<<funcName<<endl;returnfalse;}cout<<"Insertinginstrumentionatfunctionentryof"<<funcName<<endl;/*Createavectorofargumentstothefunction*incCoveragefunctiontakesthefunctionnameasargument*/BPatch_Vector<BPatch_snippet*>instArgs;BPatch_constExprid(funcId);instArgs.push_back(&id);BPatch_funcCallExprinstIncExpr(*instIncFunc,instArgs);/*Insertthesnippetatfunctionentry*/BPatchSnippetHandle*handle=appBin->insertSnippet(instIncExpr,*funcEntry,BPatch_callBefore,BPatch_lastSnippet);if(!handle){cerr<<"Failedtoinsertinstrumentionatfunctionentryof"<<funcName<<endl;returnfalse;}returntrue;}boolinsertBBEntry(BPatch_binaryEdit*appBin,BPatch_function*curFunc,char*funcName,constchar*moduleName,BPatch_function*instBBIncFunc,BPatch_function*registerBB,int*bbIndex,BPatch_Vector<BPatch_snippet*>*registerCalls){BPatch_flowGraph*appCFG=curFunc->getCFG();BPatch_Set<BPatch_basicBlock*>allBlocks;BPatch_Set<BPatch_basicBlock*>::iteratoriter;if(!appCFG){cerr<<"FailedtofindCFGforfunction"<<funcName<<endl;returnEXIT_FAILURE;}if(!appCFG->getAllBasicBlocks(allBlocks)){cerr<<"Failedtofindbasicblocksforfunction"<<funcName<<endl;returnEXIT_FAILURE;}elseif(allBlocks.size()==0){cerr<<"Nobasicblocksforfunction"<<funcName<<endl;returnEXIT_FAILURE;}/*Instrumenttheentryofeverybasicblock*/for(iter=allBlocks.begin();iter!=allBlocks.end();iter++){unsignedlongaddress=(*iter)->getStartAddress();cout<<"InstrumentingBasicBlock0x"<<hex<<address<<"of"<<funcName<<endl;BPatch_Vector<BPatch_snippet*>instArgs;BPatch_constExprbbId(*bbIndex);instArgs.push_back(&bbId);BPatch_point*bbEntry=(*iter)->findEntryPoint();if(NULL==bbEntry){cerr<<"Failedtofindentryforbasicblockat0x"<<hex<<address<<endl;returnfalse;}BPatch_funcCallExprinstIncExpr(*instBBIncFunc,instArgs);BPatchSnippetHandle*handle=appBin->insertSnippet(instIncExpr,*bbEntry,BPatch_callBefore,BPatch_lastSnippet);if(!handle){cerr<<"Failedtoinsertinstrumentioninbasicblockat0x"<<hex<<address<<endl;returnfalse;}/*Createacalltotheregistrationfunctionforthisbasicblock*/BPatch_Vector<BPatch_snippet*>regArgs;BPatch_constExprbbIdReg(*bbIndex);regArgs.push_back(&bbIdReg);BPatch_constExprcoverageFunc(funcName);regArgs.push_back(&coverageFunc);BPatch_constExprcoverageModule(moduleName);regArgs.push_back(&coverageModule);BPatch_constExpraddrArg(address);regArgs.push_back(&addrArg);BPatch_funcCallExpr*regCall=newBPatch_funcCallExpr(*registerBB,regArgs);registerCalls->push_back(regCall);(*bbIndex)++;}returntrue;}intmain(intargc,char*argv[]){if(!parseArgs(argc,argv))returnEXIT_FAILURE;/*Initializelistoflibrariesthatshouldnotbeinstrumented-relevantonlyifincludeSharedLibistrue*/initSkipLibraries();/*EveryDyninstmutatorneedstodeclareoneinstanceofBPatch*/BPatchbpatch;/*Openthespecifiedbinaryforbinaryrewriting.*Whenthesecondparameterissettotrue,allthelibrarydependencies*aswellasthebinaryareopened*/BPatch_binaryEdit*appBin=bpatch.openBinary(inBinary,true);if(appBin==NULL){cerr<<"Failedtoopenbinary"<<endl;returnEXIT_FAILURE;}/*Opentheinstrumentationlibrary.*loadLibraryloadstheinstrumentationlibraryintothebinaryp_w_picpathand*addsitasanewdynamicdependencyintherewrittenlibrary*/constchar*instLibrary="./libInst.so";if(!appBin->loadLibrary(instLibrary)){cerr<<"Failedtoopeninstrumentationlibrary"<<endl;returnEXIT_FAILURE;}BPatch_p_w_picpath*appImage=appBin->getImage();/*Findcodecoveragefunctionsintheinstrumentationlibrary*/BPatch_function*instInitFunc=findFuncByName(appImage,(char*)"initCoverage");BPatch_function*registerFunc=findFuncByName(appImage,(char*)"registerFunc");BPatch_function*instIncFunc=findFuncByName(appImage,(char*)"incFuncCoverage");BPatch_function*registerBB=findFuncByName(appImage,(char*)"registerBB");BPatch_function*instBBIncFunc=findFuncByName(appImage,(char*)"incBBCoverage");BPatch_function*instExitFunc=findFuncByName(appImage,(char*)"exitCoverage");if(!instInitFunc||!instIncFunc||!instExitFunc||!instBBIncFunc||!registerFunc||!registerBB){returnEXIT_FAILURE;}/*Toinstrumenteveryfunctioninthebinary*-->iterateoverallthemodulesinthebinary*-->iterateoverallfunctionsineachmodules*/vector<BPatch_module*>*modules=appImage->getModules();vector<BPatch_module*>::iteratormoduleIter;BPatch_module*defaultModule;BPatch_Vector<BPatch_snippet*>registerCalls;intbbIndex=0;intfuncIndex=0;for(moduleIter=modules->begin();moduleIter!=modules->end();++moduleIter){charmoduleName[1024];(*moduleIter)->getName(moduleName,1024);/*ifincludeSharedLibisnotset,skipinstrumentingdependentlibraries*/if((*moduleIter)->isSharedLib()){if(!includeSharedLib||skipLibraries.find(moduleName)!=skipLibraries.end()){cout<<"Skippinglibrary:"<<moduleName<<endl;continue;}}/*Everybinaryhasonedefaultmodule.*codecoverageinitializeandfinalizefunctionsshouldbecalledonlyonce.*Hencecallthemfromthedefaultmodule*/if(string(moduleName).find("DEFAULT_MODULE")!=string::npos){defaultModule=(*moduleIter);}cout<<"Instrumentingmodule:"<<moduleName<<endl;vector<BPatch_function*>*allFunctions=(*moduleIter)->getProcedures();vector<BPatch_function*>::iteratorfuncIter;/*Insertsnippetsattheentryofeveryfunction*/for(funcIter=allFunctions->begin();funcIter!=allFunctions->end();++funcIter){BPatch_function*curFunc=*funcIter;charfuncName[1024];curFunc->getName(funcName,1024);/**ReplaceDEFAULT_MODULEwiththenameoftheinputbinaryintheoutput*/stringpassedModName(moduleName);if(passedModName.find("DEFAULT_MODULE")!=string::npos){//StripthedirectorypassedModName=inBinary;passedModName=passedModName.substr(passedModName.find_last_of("\\/")+1);}insertFuncEntry(appBin,curFunc,funcName,instIncFunc,funcIndex);/*Createacalltotheregistrationfunction*/BPatch_Vector<BPatch_snippet*>regArgs;BPatch_constExprfuncIdReg(funcIndex);regArgs.push_back(&funcIdReg);BPatch_constExprcoverageFunc(funcName);regArgs.push_back(&coverageFunc);BPatch_constExprcoverageModule(passedModName.c_str());regArgs.push_back(&coverageModule);BPatch_funcCallExpr*regCall=newBPatch_funcCallExpr(*registerFunc,regArgs);registerCalls.push_back(regCall);funcIndex++;if(bbCoverage){insertBBEntry(appBin,curFunc,funcName,passedModName.c_str(),instBBIncFunc,registerBB,&bbIndex,®isterCalls);}}}/*CreateargumentlistforinitCoveragefunction*withthenumberoffunctionsthenumberofbasicblocks*/BPatch_Vector<BPatch_snippet*>instInitArgs;BPatch_constExprnumFuncs(funcIndex);instInitArgs.push_back(&numFuncs);BPatch_constExprnumBBs(bbIndex);instInitArgs.push_back(&numBBs);BPatch_funcCallExprinstInitExpr(*instInitFunc,instInitArgs);//Executethefunctionregistrationandbasicblockregistrationcallsafter//thecalltotheinitializationfunction,i.e.,//initCoverage()//registerFunc()//...//registerBB()//...BPatch_sequenceregisterSequence(registerCalls);BPatch_Vector<BPatch_snippet*>initSequenceVec;initSequenceVec.push_back(&instInitExpr);initSequenceVec.push_back(®isterSequence);BPatch_sequenceinitSequence(initSequenceVec);/*Locate_init*/BPatch_Vector<BPatch_function*>funcs;appImage->findFunction("_init",funcs);if(funcs.size()){BPatch_Vector<BPatch_function*>::iteratorfIter;for(fIter=funcs.begin();fIter!=funcs.end();++fIter){BPatch_module*mod=(*fIter)->getModule();charmodName[1024];mod->getName(modName,1024);if(!mod->isSharedLib()){mod->insertInitCallback(initSequence);cerr<<"insertInitCallbackon"<<modName<<endl;}}}/*InsertinitCoveragefunctionintheinitsectionofthedefaultmodule*tobeexecutedexactlyoncewhenthemoduleisloaded*///if(!defaultModule->insertInitCallback(initSequence)){//cerr<<"Failedtoinsertinitfunctioninthemodule"<<endl;//returnEXIT_FAILURE;//}/*InsertexitCoveragefunctioninthefinisectionofthedefaultmodule*tobeexecutedexactlyoncewhenthemoduleisunloaded*/BPatch_Vector<BPatch_snippet*>instExitArgs;BPatch_constExprvarPrint(printAll);instExitArgs.push_back(&varPrint);BPatch_constExprvarBBPrint(bbCoverage?1:0);instExitArgs.push_back(&varBBPrint);BPatch_constExprvarAlpha(alphabetical);instExitArgs.push_back(&varAlpha);BPatch_funcCallExprinstExitExpr(*instExitFunc,instExitArgs);/*Locate_fini*/funcs.clear();appImage->findFunction("_fini",funcs);if(funcs.size()){BPatch_Vector<BPatch_function*>::iteratorfIter;for(fIter=funcs.begin();fIter!=funcs.end();++fIter){BPatch_module*mod=(*fIter)->getModule();charmodName[1024];mod->getName(modName,1024);if(!mod->isSharedLib()){mod->insertFiniCallback(instExitExpr);cerr<<"insertFiniCallbackon"<<modName<<endl;}}}//if(!defaultModule->insertFiniCallback(instExitExpr)){//cerr<<"Failedtoinsertexitfunctioninthemodule"<<endl;//returnEXIT_FAILURE;//}//Outputtheinstrumentedbinaryif(!appBin->writeFile(outBinary)){cerr<<"Failedtowriteoutputfile:"<<outBinary<<endl;returnEXIT_FAILURE;}returnEXIT_SUCCESS;}
libInst.C
/**TheinstrumentationlibraryforthecodeCoveragetool.Provides*functionsforinitialization,registeringfunctionsandbasic*blocksforcoveragetracking,andoutputtingtheresults.*/#include<cstdlib>#include<cstdio>#include<iostream>#include<cstring>#include<vector>#include<algorithm>usingnamespacestd;classbbRecord{public:stringfuncName;stringmodName;unsignedlongaddress;unsignedlongcount;bbRecord():funcName(""),modName(""),address(0),count(0){}};classfuncRecord{public:stringfuncName;stringmodName;unsignedlongcount;funcRecord():funcName(""),modName(""),count(0){}};//UsedtorecordsviaqsortstaticintcompareFuncRecordByName(constvoid*left,constvoid*right){funcRecord*leftRecord=(funcRecord*)left;funcRecord*rightRecord=(funcRecord*)right;returnleftRecord->funcName.compare(rightRecord->funcName);}staticintcompareFuncRecordByCount(constvoid*left,constvoid*right){funcRecord*leftRecord=(funcRecord*)left;funcRecord*rightRecord=(funcRecord*)right;if(leftRecord->count<rightRecord->count)return1;if(leftRecord->count>rightRecord->count)return-1;return0;}staticintcompareBBRecordByName(constvoid*left,constvoid*right){bbRecord*leftRecord=(bbRecord*)left;bbRecord*rightRecord=(bbRecord*)right;returnleftRecord->funcName.compare(rightRecord->funcName);}staticintcompareBBRecordByCount(constvoid*left,constvoid*right){bbRecord*leftRecord=(bbRecord*)left;bbRecord*rightRecord=(bbRecord*)right;if(leftRecord->count<rightRecord->count)return1;if(leftRecord->count>rightRecord->count)return-1;return0;}//Forefficencyininstrumentation,indexedbyidstaticbbRecord*bbs;staticfuncRecord*funcs;intnumFuncs=0;intnumBBs=0;intenabled=0;//AllocatesspaceforalltrackedfunctionsandbasicblocksvoidinitCoverage(inttotalFuncs,inttotalBBs){numFuncs=totalFuncs;numBBs=totalBBs;funcs=newfuncRecord[numFuncs];bbs=newbbRecord[numBBs];enabled=1;}//PopulatesarecordforafunctionvoidregisterFunc(intid,char*name,char*modName){if(!enabled)return;funcs[id].funcName=name;funcs[id].modName=modName;funcs[id].count=0;}//PopulatesarecordforabasicblockvoidregisterBB(intid,char*name,char*modName,unsignedlongaddr){if(!enabled)return;bbs[id].funcName=name;bbs[id].modName=modName;bbs[id].address=addr;bbs[id].count=0;}//ShouldbecalledonfunctionentryvoidincFuncCoverage(intid){if(!enabled)return;funcs[id].count++;}//ShouldbecalledonbasicblockentryvoidincBBCoverage(intid){if(!enabled)return;bbs[id].count++;}//Printsthecodecoveragestats.tostandardout,alsodisablesanymoretrackingvoidexitCoverage(intprintAll,intprintBasicBlocks,intsortAlphabetical){if(!enabled)return;printf("\n\n**************************CodeCoverage*************************\n\n");intcount=0;if(sortAlphabetical)qsort(funcs,numFuncs,sizeof(funcRecord),&compareFuncRecordByName);elseqsort(funcs,numFuncs,sizeof(funcRecord),&compareFuncRecordByCount);for(inti=0;i<numFuncs;++i){if(funcs[i].count>0)count++;if(printAll||(funcs[i].count>0))printf("%4lu:%s,%s\n",funcs[i].count,funcs[i].funcName.c_str(),funcs[i].modName.c_str());}printf("\n**************CodeCoverage%doutof%dfunctions**************\n\n",count,numFuncs);if(printBasicBlocks){intbbCount=0;printf("\n\n**************************BasicBlockCoverage*************************\n\n");if(sortAlphabetical)qsort(bbs,numBBs,sizeof(bbRecord),&compareBBRecordByName);elseqsort(bbs,numBBs,sizeof(bbRecord),&compareBBRecordByCount);stringcurFunc;stringcurMod;for(inti=0;i<numBBs;++i){if(bbs[i].count>0)bbCount++;elseif(!printAll)continue;if(curFunc!=bbs[i].funcName||curMod!=bbs[i].modName){curFunc=bbs[i].funcName;curMod=bbs[i].modName;printf("(%s,%s)\n",bbs[i].funcName.c_str(),bbs[i].modName.c_str());printf("\t%4lu:0x%-8lx\n",bbs[i].count,bbs[i].address);}else{printf("\t%4lu:0x%-8lx\n",bbs[i].count,bbs[i].address);}}printf("\n**************BasicBlockCoverage%doutof%dblocks**************\n\n",bbCount,numBBs);}enabled=0;}
libtestcc.c
/**AtoylibrarytodemonstratethecodeCoveragetool*/#include"libtestcc.h"staticintotherFunctionCalled=0;staticvoidotherFunction(){otherFunctionCalled=1;}voidlibFooFunction(intcallOtherFunction){if(callOtherFunction)otherFunction();}
libtestcc.h
/**Headerforlibtestcc*/#ifndef__LIB_TESTCC_H__#define__LIB_TESTCC_H__externvoidlibFooFunction(intcallOtherFunction);#endif
Makefile
README
ThisdirectorycontainsasimplecodecoveragetoolbuiltwithDyninstAPI.ThetoolusesDyninsttoinstrumenteveryfunctioninaprogrambinaryaswellasoptionallyinstrumentingeverybasicblocktorecordcodecoveragedata.ThegoalofthistoolistodemonstratesomeofthecapabilitiesofDyninstAPI.Itdoesverylittleprocessingoftherawcodecoveragedata,justsomebasicsortingwhenoutputtingthedata.Thistoolshouldserveasthebasisforcreatingamorefeature-richcodecoveragetoolusingDyninst.Thepresenceofdebugginginformationintheprogrambinaryisrecommendedtoacquirethemostusefulinformationaboutcodecoverage,butitisnotrequired.Withoutdebugginginformation,sourcefileinformationwillnotbeavailableinthecodecoverageoutput.Thistoolmakesuseofaninstrumentationlibrary,libInst,tocollectthecodecoveragedata.Thetooladdsthislibraryasadependencytotheinputexecutableandalsoinsertscallsintothislibraryatfunctionentriesandbasicblockentries.TheprovidedMakefilecanbeusedtobuildtheprogram.TheDYNINST_ROOTenvironmentvariableshouldbesettothedirectorywhereDyninstwasbuilt/installed.ThisdirectoryshouldcontainanincludedirectorywiththeDyninstheadersandalibdirectorywiththeDyninstlibraries.Also,makesuretosettheLD_LIBRARY_PATHenvironmentvariabletoincludethelibrarydirectoryandsettheDYNINSTAPI_RT_LIBenvironmentvariableto${DYNINST_LIBRARY_DIRECTORY}/libdyninstAPI_RT.so.1AlsoincludedinthisdirectoryisatoyprogramthatdemonstratesauseofthecodeCoveragetool:testccandlibtestcc.TheycanbebuiltwiththeprovidedMakefile.AnexampleusageofthecodeCoveragetoolwiththisprogramfollows.Itisassumedthatthefollowingbinarieshavebeenbuilt:codeCoverage,libtestcc,testcc.Also,thisexampleassumesyouareusingcsh/tcsh,butshouldeasilytransfertoanothershell.Beforestarting,thetestccprogramwillnotworkunlessthelibtestcc.solibrarycanbefoundbythedynamiclinker.Amongothersolutions,thiscommandshouldmaketestccexecutesuccessfully.%setenvLD_LIBRARY_PATH${LD_LIBRARY_PATH}:.First,executecodeCoveragewithoutanyargumentstoseetheusage.%./codeCoverageInputbinarynotspecified.Usage:./codeCoverage[-bpsa]<binary><outputbinary>-b:Basicblocklevelcodecoverage-p:Printallfunctions(includingfunctionsthatareneverexecuted)-s:Instrumentsharedlibrariesalso-a:SortresultsalphabeticallybyfunctionnameNow,passthetestccexecutableasinput,instrumentingbasicblocksaswellasasharedlibraryusedbytestcc,libtestcc.so.%./codeCoverage-sb./testcctestcc.inst[Lotsofoutputstatingwhatthetoolisdoing]Youmaynoticethatthetoolskipssomesharedlibraries.Thedefaultbehaviorofthetoolistonotinstrumentstandardlibrariessuchaslibc.Thelastcommandwilloutputarewrittenversionoftestcc,testcc.inst.Itwillalsooverwritetheexistinglibtestcc.sofilewitharewrittenversion.ThedefaultDyninstbehaviorwhenrewrittingthesharedlibrariesofanexecutableistooutputthesharedlibrariesinthesamedirectoryastherewrittenexecutable.Now,runthetestcc.instprogramtogeneratecodecoveragedata.Anabridgedversionoftheoutputfollows.%./testcc.inst**************************CodeCoverage*************************1:_init,testcc1:__do_global_dtors_aux,testcc1:frame_dummy,testcc1:__do_global_ctors_aux,testcc1:_fini,testcc1:two,testcc.c1:one,testcc.c1:main,testcc.c**************CodeCoverage8outof17functions****************************************BasicBlockCoverage*************************[...snip...](two,testcc.c)1:0x4006ab(one,testcc.c)1:0x4006c01:0x4006d6(__do_global_dtors_aux,testcc)1:0x40063c(one,testcc.c)1:0x4006e4(main,testcc.c)1:0x4006f0(__do_global_dtors_aux,testcc)1:0x400643(main,testcc.c)1:0x40071a[...snip...]**************BasicBlockCoverage23outof69blocks**************ENDOUTPUTThefirstsetofdatacontainscountsforthenumberoftimeseachfunctionwascalled.Thesecondsetofdatacontainscountsforthenumberoftimeseachbasicblockwasentered.Ifyouruntheprogramagainwithafewcommandlinearguments,youwillseethatthe'three'functionintestcc.cwasnowcalledaswellasfunctionsinlibtestcc.so.%./testcc.inst12**************************CodeCoverage*************************1:_init,testcc1:three,testcc.c1:two,testcc.c1:one,testcc.c1:main,testcc.c1:otherFunction,libtestcc.so1:libFooFunction,libtestcc.so1:__do_global_dtors_aux,testcc1:frame_dummy,testcc1:__do_global_ctors_aux,testcc1:_fini,testcc**************CodeCoverage11outof17functions**************[...snip...]basicblockoutputnotincludedENDOUTPUTThisoutputshowsthatmorefunctionshavebeencalledwiththisnewinputset.
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。