Process Tracing Using Ptrace
2007-05-12 12:41
399 查看
"LinuxGazette...makingLinuxjustalittlemorefun!"
ProcessTracingUsingPtrace
BySandeepS
Theptracesystemcalliscrucialtotheworkingofdebuggerprogramslikegdb-yetitsbehaviourisnotverywelldocumented-unlessyoubelievethatthebestdocumentationiskernelsourceitself!Ishallattempttodemonstratehowptracecanbeusedtoimplementsomeofthefunctionalityavailableintoolslikegdb.1.Introduction
ptrace()isasystemcallthatenablesoneprocesstocontroltheexecutionofanother.Italsoenablesaprocesstochangethecoreimageofanotherprocess.Thetracedprocessbehavesnormallyuntilasignaliscaught.Whenthatoccurstheprocessentersstoppedstateandinformsthetracingprocessbyawait()call.Thentracingprocessdecideshowthetracedprocessshouldrespond.TheonlyexceptionisSIGKILLwhichsurelykillstheprocess.Thetracedprocessmayalsoenterthestoppedstateinresponsetosomespecificeventsduringitscourseofexecution.Thishappensonlyifthetracingprocesshassetanyeventflagsinthecontextofthetracedprocess.Thetracingprocesscanevenkillthetracedonebysettingtheexitcodeofthetracedprocess.Aftertracing,thetracerprocessmaykillthetracedoneorleavetocontinuewithitsexecution.
Note:Ptrace()ishighlydependentonthearchitectureoftheunderlyinghardware.Applicationsusingptracearenoteasilyportableacrossdifferentarchitecturesandimplementations.
2.MoreDetails
Theprototypeofptrace()isasfollows.#include<sys/ptrace.h>
longintptrace(enum__ptrace_requestrequest,pid_tpid,
void*addr,void*data)
Ofthefourarguments,thevalueofrequestdecideswhattobedone.PidistheIDoftheprocesstobetraced.Addristheoffsetintheuserspaceofthetracedprocesstowherethedataiswrittenwheninstructedtodoso.Itistheoffsetinuserspaceofthetracedprocessfromwhereawordisreadandreturnedastheresultofthecall.
TheparentcanforkachildprocessandtraceitbycallingptracewithrequestasPTRACE_TRACEME.ParentcanalsotraceanexistingprocessusingPTRACE_ATTACH.Thedifferentvaluesofrequestarediscussedbelow.
2.1Howdoesptrace()work.
Wheneverptraceiscalled,whatitfirstdoesistolockthekernel.Justbeforereturningitunlocksthekernel.Let'sseeitsworkinginbetweenthisfordifferentvaluesofrequest.PTRACE_TRACEME:
Thisiscalledwhenthechildistobetracedbytheparent.Assaidabove,anysignals(exceptSIGKILL),eitherdeliveredfromoutsideorfromtheexeccallsmadebytheprocess,causesittostopandletstheparentdecidehowtoproceed.Insideptrace(),theonlythingthatischeckediswhethertheptraceflagofthecurrentprocessisset.Ifnot,permissionisgrantedandtheflagisset.Alltheparametersotherthanrequestareignored.PTRACE_ATTACH:
Hereaprocesswantstocontrolanother.Onethingtorememberisthatnobodyisallowedtotrace/controltheinitprocess.Aprocessisnotallowedtocontrolitself.Thecurrentprocess(caller)becomestheparentoftheprocesswithprocessIDpid.Butagetpid()bythechild(theonebeingtraced)returnstheprocessIDoftherealparent.Whatgoesbehindthescenesisthatwhenacallismade,theusualpermissionchecksaremadealongwithwhethertheprocessisinitorcurrentoritisalreadytraced.Ifthereisnoproblem,permissionisgivenandtheflagisset.Nowthelinksofthechildprocessarerearranged;e.g.,thechildisremovedfromthetaskqueueanditsparentprocessfieldischanged(theoriginalparentremainsthesame).Itisputtothequeueagaininsuchapositionthatinitcomesnexttoit.FinallyaSIGSTOPsignalisdeliveredtoit.Hereaddranddataareignored.
PTRACE_DETACH:
Stoptracingaprocess.Thetracermaydecidewhetherthechildshouldcontinuetolive.ThisundoesalltheeffectsmadebyPTRACE_ATTACH/PTRACE_TRACEME.Theparentsendstheexitcodeforthechildindata.Ptraceflagofthechildisreset.Thenthechildismovedtoitsoriginalpositioninthetaskqueue.Thepidofrealparentiswrittentotheparentfield.Thesingle-stepbitwhichmighthavebeensetisreset.Finallythechildiswokenupasnothinghadhappenedtoit;addrisignored.PTRACE_PEEKTEXT,PTRACE_PEEKDATA,PTRACE_PEEKUSER:
Theseoptionsreaddatafromchild'smemoryanduserspace.PTRACE_PEEKTEXTandPTRACE_PEEKDATAreaddatafrommemoryandboththeseoptionshavethesameeffect.PTRACE_PEEKUSERreadsfromtheuserspaceofchild.Awordisreadandplacedintoatemporarydatastructure,andwiththehelpofput_user()(whichcopiesastringfromthekernel'smemorysegmenttotheprocess'memorysegment)therequireddataiswrittentodataandreturns0onsuccess.InthecaseofPTRACE_PEEKTEXT/PTRACE_PEEKDATA,addristheaddressofthelocationtobereadfromchild'smemory.InPTRACE_PEEKUSERaddristheoffsetofthewordinchild'suserspace;dataisignored.
PTRACE_POKETEXT,PTRACE_POKEDATA,PTRACE_POKEUSER:
Theseoptionsareanalogoustothethreeexplainedabove.Thedifferenceisthattheseareusedtowritethedatatothememory/userspaceoftheprocessbeingtraced.InPTRACE_POKETEXTandPTRACE_POKEDATAawordfromlocationdataiscopiedtothechild'smemorylocationaddr.InPTRACE_POKEUSERwearetryingtomodifysomelocationsinthe
task_structoftheprocess.Astheintegrityofthekernelhastobemaintained,weneedtobeverycareful.Afteralotofsecuritychecksmadebyptrace,onlycertainportionsofthetask_structisallowedtochange.Hereaddristheoffsetinchild'suserarea.
PTRACE_SYSCALL,PTRACE_CONT:
Boththesewakesupthestoppedprocess.PTRACE_SYSCALLmakesthechildtostopafterthenextsystemcall.PTRACE_CONTjustallowsthechildtocontinue.Inboth,theexitcodeofthechildprocessissetbytheptrace()wheretheexitcodeiscontainedindata.Allthishappensonlyifthesignal/exitcodeisavalidone.Ptrace()resetsthesinglestepbitofthechild,sets/resetsthesyscalltracebit,andwakesuptheprocess;addrisignored.PTRACE_SINGLESTEP;
DoesthesameasPTRACE_SYSCALLexceptthatthechildisstoppedaftereveryinstruction.Thesinglestepbitofthechildisset.Asabovedatacontainstheexitcodeforthechild;addrisignored.PTRACE_KILL:
Whenthechildistobeterminated,PTRACE_KILLmaybeused.Howthemurderoccursisasfollows.Ptrace()checkswhetherthechildisalreadydeadornot.Ifalive,theexitcodeofthechildissettosigkill.Thesinglestepbitofthechildisreset.Nowthechildiswokenupandwhenitstartstoworkitgetskilledaspertheexitcode.2.2Moremachine-dependentcalls
Thevaluesofrequestdiscussedabovewereindependentonthearchitectureandimplementationofthesystem.Thevaluesdiscussedbelowarethosethatallowthetracingprocesstoget/set(i.e.,toread/write)theregistersofchildprocess.Theseregisterfetching/settingoptionsaremoredirectlydependentonthearchitectureofthesystem.Thesetofregistersincludegeneralpurposeregisters,floatingpointregistersandextendedfloatingpointregisters.Thesemoremachine-dependentoptionsarediscussedbelow.Whentheseoptionsaregiven,adirectinteractionbetweentheregisters/segmentsofthesystemisrequired.PTRACE_GETREGS,PTRACE_GETFPREGS,PTRACE_GETFPXREGS:
Thesevaluesgivethevalueofgeneralpurpose,floatingpoint,extendedfloatingpointregistersofthechildprocess.Theregistersarereadtothelocationdataintheparent.Theusualchecksforaccessontheregistersaremade.Thentheregistervaluesarecopiedtothelocationspecifiedbydatawiththehelpofgetreg()and__put_user()functions;addrisignored.PTRACE_SETREGS,PTRACE_SETFPREGS,PTRACE_SETFPXREGS:
Thesearevaluesofrequestthatallowthetracingprocesstosetthegeneralpurpose,floatingpoint,extendedfloatingpointregistersofthechildrespectively.Therearesomerestrictionsinthecaseofsettingtheregisters.Somearenotallowedtobechanged.Thedatatobecopiedtotheregisterswillbetakenfromthelocationdataoftheparent.Herealsoaddrisignored.2.3Returnvaluesofptrace()
Asuccessfulptrace()returnszero.Errorsmakeitreturn-1andseterrno.SincethereturnvalueofasuccessfulPEEKDATA/PEEKTEXTmaybe-1,itisbettertochecktheerrno.TheerrorsareEPERM:Therequestedprocesscouldn'tbetraced.Permissiondenied.
ESRCH:Therequestedprocessdoesn'texistorisbeingtraced.
EIO:Therequestwasinvalidorread/writewasmadefrom/toinvalidareaofmemory.
EFAULT:Read/writewasmadefrom/tomemorywhichwasnotreallymapped.
ItisreallyhardtodistinguishbetweenthereasonsofEIOandEFAULT.Thesearereturnedforalmostidenticalerrors.
3.Asmallexample.
Ifyoufoundtheparameterdescriptiontobeabitdry,don'tdespair.Ishallnotattemptanythingofthatsortagain.Iwilltrytowritesimpleprogramswhichillustratemanyofthepointsdiscussedabove.Hereisthefirstone.Theparentprocesscountsthenumberofinstructionsexecutedbythetestprogramrunbythechild.
Herethetestprogramislistingtheentriesofthecurrentdirectory.
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<syscall.h>
#include<sys/ptrace.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<errno.h>
intmain(void)
{
longlongcounter=0;/*machineinstructioncounter*/
intwait_val;/*child'sreturnvalue*/
intpid;/*child'sprocessid*/
puts("Pleasewait");
switch(pid=fork()){
case-1:
perror("fork");
break;
case0:/*childprocessstarts*/
ptrace(PTRACE_TRACEME,0,0,0);
/*
*mustbecalledinordertoallowthe
*controloverthechildprocess
*/
execl("/bin/ls","ls",NULL);
/*
*executestheprogramandcauses
*thechildtostopandsendasignal
*totheparent,theparentcannow
*switchtoPTRACE_SINGLESTEP
*/
break;
/*childprocessends*/
default:/*parentprocessstarts*/
wait(&wait_val);
/*
*parentwaitsforchildtostopatnext
*instruction(execl())
*/
while(wait_val==1407){
counter++;
if(ptrace(PTRACE_SINGLESTEP,pid,0,0)!=0)
perror("ptrace");
/*
*switchtosinglesteptracingand
*releasechild
*ifunablecallerror.
*/
wait(&wait_val);
/*waitfornextinstructiontocomplete*/
}
/*
*continuetostop,waitandreleaseuntil
*thechildisfinished;wait_val!=1407
*Low=0177LandHigh=05(SIGTRAP)
*/
}
printf("Numberofmachineinstructions:%lld/n",counter);
return0;
}
openyourfavouriteeditorandwritetheprogram.Thenrunitbytyping
ccfile.c
a.out
Youcanseethenumberofinstructionsneededforlistingofyourcurrentdirectory.
cdtosomeotherdirectoryandruntheprogramfromthereandseewhetherthereisanydifference.(notethatitmaytakesometimefortheoutputtoappear,ifyouareusingaslowmachine).
4.Conclusion
Ptrace()isheavilyusedfordebugging.Itisalsousedforsystemcalltracing.Thedebuggerforksandthechildprocesscreatedistracedbytheparent.Theprogramwhichistobedebuggedisexec'dbythechild(intheaboveprogramitwas"ls")andaftereachinstructiontheparentcanexaminetheregistervaluesoftheprogrambeingrun.Ishalldemonstrateprogramswhichexploitptrace'sversatilityinthenextpartofthisseries.Goodbyetillthen.
SandeepS
IamafinalyearstudentofGovernmentEngineeringCollegeinThrissur,Kerala,India.MyareasofinterestsincludeFreeBSD,NetworkingandalsoTheoreticalComputerScience.SandeepS
Copyright©2002,SandeepS.
Copyinglicense
PublishedinIssue81ofLinuxGazette,August2002
相关文章推荐
- Process Tracing Using Ptrace
- Trace Application Engine Processes Using Process Definitions
- End-to-End Tracing of Ajax/Java Applications Using DTrace
- Tracing mysqld Using DTrace
- Tracing mysqld Using DTrace
- Tracing mysqld Using DTrace
- End-to-End Tracing of Ajax/Java Applications Using DTrace
- Trace Application Engine Processes Using Process Definitions
- [Chapter 3 Process]Practice 3.5 When a process creates a new process using the fork() operation
- How to generate Oracle Net tracing for a DBMS_JOB using a database link
- 【ABAP】Creat a client-server demo to process a http request using SAP Web AS
- Process Engineering and Design Using Visual Basic
- SOLARIS: Determining Background Process Size using pmap (文档 ID 107750.1)
- Trace the process of the start of Linux
- Fatal error in launcher: Unable to create process using '"' 问题
- unable to lock the administration directory (/var/lib/dpkg/) is another process using it
- Troubleshooting Failed Requests Using Tracing in IIS 7
- How to debug user-mode process using kernel-mode windbg in Win7
- Fatal error in launcher: Unable to create process using '"D:\pytghon2.7\python.exe" "D:\python2.7\S
- Using the Adobe AIR 2 NativeProcess API to create a screen recorder