Vous êtes sur la page 1sur 5

5/30/2017 GoFunctionCallsReduxHackerNoon

Phil Pearl Follow


software, fraud, bicyclesFighting bad people at ravelin.com
Mar 18 3 min read

Go Function CallsRedux
SometimeagoinapreviouspostIpromisedtotakeafurtherlookat
howfunctioncallsandcallstacksinGowork.Ivethinkfoundaneat
waytomakegoodonthatpromise,soheregoes.

Sowhatisacallstack?Well,itsanareaofmemoryusedtoholdlocal
variablesandcallparameters,andtotrackwherefunctionsshould
returnto.Eachgoroutinehasitsownstack.Youcouldalmostsaya
goroutineisitsstack.

HeresthecodeImgoingtousetoshowthestackinaction.Itsjusta
sequenceofsimplefunctioncalls. main() calls f1(0xdeadbeef) ,
whichthencalls f2(0xabad1dea) ,whichcalls f3(0xbaddcafe) .
f3() thenaddsonetoitsparameter,andstoresitinalocalvariable
called local .Itthentakestheaddressof local andprintsout
memorystartingatthataddress.Because local isonthestack,this
printsthestack.

https://hackernoon.com/gofunctioncallsredux609fdd1c90fd 1/6
5/30/2017 GoFunctionCallsReduxHackerNoon

1 packagemain
2
3 import(
4 "fmt"
5 "runtime"
6 "unsafe"
7 )
8
9 funcmain(){
10 f1(0xdeadbeef)
11 }
12
13 funcf1(valint){
14 f2(0xabad1dea)
15 }
16
17 funcf2(valint){
18 f3(0xbaddcafe)
19 }
20
21 funcf3(valint){
22 local:=val+1
23
24 display(uintptr(unsafe.Pointer(&local)))
25 }
26
27 funcdisplay(ptruintptr){
28 mem:=*(*[20]uintptr)(unsafe.Pointer(ptr))
29 fori,x:=rangemem{

Herestheoutputoftheprogram.Itisadumpofmemorystartingat
theaddressof local ,shownasalistof8byteintegersinhex.The
addressofeachintegerisontheleft,andtheintattheaddressisonthe
right.

Weknow local shouldequal0xBADDCAFE+1,or0xBADDCAFF,


andthisisindeedwhatweseeatthestartofthedump.

C42003FF28:BADDCAFF
C42003FF30:C42003FF48
C42003FF38:1088BEB
C42003FF40:BADDCAFE
C42003FF48:C42003FF60
C42003FF50:1088BAB
C42003FF58:ABAD1DEA

https://hackernoon.com/gofunctioncallsredux609fdd1c90fd 2/6
5/30/2017 GoFunctionCallsReduxHackerNoon

C42003FF60:C42003FF78
C42003FF68:1088B6B
C42003FF70:DEADBEEF
C42003FF78:C42003FFD0
C42003FF80:102752A
C42003FF88:C420064000
C42003FF90:0
C42003FF98:C420064000
C42003FFA0:0
C42003FFA8:0
C42003FFB0:0
C42003FFB8:0
C42003FFC0:C4200001A0

1088BEBismain.f2
/Users/phil/go/src/github.com/philpearl/stack/main.go19

1088BABismain.f1
/Users/phil/go/src/github.com/philpearl/stack/main.go15

1088B6Bismain.main
/Users/phil/go/src/github.com/philpearl/stack/main.go11

102752Aisruntime.main
/usr/local/Cellar/go/1.8/libexec/src/runtime/proc.go194

Thenextnumberis0xC42003FF48,whichistheaddressofthe
5thlineofthedump.

Afterthatwehave0x1088BEB.Itturnsoutthisisanaddressof
executablecode,andifwefeeditinto runtime.FuncForPC we
seeitistheaddressofline19ofmain.go,whichisthelastlineof
f2() .Thisistheaddresswereturntowhen f3() returns.

Nextwehave0xBADDCAFE,theparametertoourcallto f3()

Ifwecarryonwecontinuetoseethispattern.BelowIvemarkedup
thememorydumpshowinghowthestackpointerstrackbackthrough
thedumpandwherethefunctionparametersandreturnaddressessit.

C42003FF28:BADDCAFFLocalvariableinf3()
+C42003FF30:C42003FF48
|C42003FF38:1088BEBreturntof2()main.goline19
|C42003FF40:BADDCAFEf3()parameter
+C42003FF48:C42003FF60
|C42003FF50:1088BABreturntof1()main.goline15
|C42003FF58:ABAD1DEAf2()parameter
+C42003FF60:C42003FF78
|C42003FF68:1088B6Breturntomain()main.goline
11
|C42003FF70:DEADBEEFf1()parameter
+C42003FF78:C42003FFD0

https://hackernoon.com/gofunctioncallsredux609fdd1c90fd 3/6
5/30/2017 GoFunctionCallsReduxHackerNoon

C42003FF80:102752Areturntoruntime.main()

Fromthiswecanseemanythings.

First,thestackstartsatahighaddress,andthestackaddress
reducesasfunctioncallsaremade.

Whenafunctioncallismade,thecallerpushestheparameters
ontothestack,thenthereturnaddress(theaddressofthenext
instructioninthecallingfunction),thenapointertoahigherpoint
inthestack.

Thispointerisusedtofindthepreviousfunctioncallonthestack
whenunwindingthestackwhenthecallreturns.

Localvariablesarestoredafterthestackpointer.

Wecanusethesametechniquetolookatsomeslightlymore
complicatedfunctioncalls.Iveaddedmoreparameters,andsome
returnvaluesto f2() inthisversion.

1 packagemain
2
3 import(
4 "fmt"
5 "runtime"
6 "unsafe"
7 )
8
9 funcmain(){
10 f1(0xdeadbeef)
11 }
12
13 funcf1(valint){
14 f2(0xabad1dea0001,0xabad1dea0002)
15 }
16
17 funcf2(val1,val2int)(r1,r2int){
18 f3(0xbaddcafe)

ThistimeIvejumpedstraighttothemarkedupoutput.

https://hackernoon.com/gofunctioncallsredux609fdd1c90fd 4/6
5/30/2017 GoFunctionCallsReduxHackerNoon

C42003FF10:BADDCAFFlocalvariableinf3()
+C42003FF18:C42003FF30
|C42003FF20:1088BFBreturntof2()
|C42003FF28:BADDCAFEf3()parameter
+C42003FF30:C42003FF60
|C42003FF38:1088BBFreturntof1()
|C42003FF40:ABAD1DEA0001f2()firstparameter
|C42003FF48:ABAD1DEA0002f2()secondparameter
|C42003FF50:110A100spaceforf2()returnvalue
|C42003FF58:C42000E240spaceforf2()returnvalue
+C42003FF60:C42003FF78
|C42003FF68:1088B6Breturntomain()
|C42003FF70:DEADBEEFf1()parameter
+C42003FF78:C42003FFD0
C42003FF80:102752Areturntoruntime.main()

Fromthiswecanseethat

thecallingfunctionmakesspaceforthereturnvaluesofthecalled
functionbeforethefunctionparameters.(Notethevaluesare
uninitialisedbecausethefunctionhasntreturnedyet!)

parametersarepushedontothestackinreverseorder.

Hopefullyallthatmadesense!Ifyougotthisfarandenjoyeditor
learnedsomething,pleasehitthatheartbutton.Icantearninternet
pointswithoutyou.

Byday,Philfightscrimeatravelin.com.Youcanjoinhim:
https://angel.co/ravelin/jobs

https://hackernoon.com/gofunctioncallsredux609fdd1c90fd 5/6

Vous aimerez peut-être aussi