class: center, middle
-
I ran across this monkey patching library the other day:
-
I realized this library must be modifying function bodies to achieve this.
-
That got me thinking that I could use arbitrary read/write access to memory to better understand Go's implementation and some of its quirks.
- typed
nilinterfacesnil != nil?
- struct field alignment
- memory consumption
- atomic panics
Keep these in mind as we learn about accessing raw memory.
Before we get into it:
- These techniques for accessing raw memory are unsafe.
- They should not be used in real code.
- This is for educational purposes only.
- Remember...
class: center, middle
-
The
unsafepackage contains operations that step around the type safety of Go programs. -
Programs that use
unsafemay be non-portable and might break with newer compilers. -
unsafehas magical behaviour based on how you use it. For instance:syscall.Syscall(SYS_READ, uintptr(fd), u, uintptr(n))is not the same as:
ptr := uintptr(fd) syscall.Syscall(SYS_READ, ptr, u, uintptr(n))The first invocation will ensure the memory pointed at by
fdis not moved or garbage collected until the syscall completes. The second invocation is invalid. -
Make sure to read the docs and run
go vet!
unsafe.Pointer-
A type representing a pointer to any value.
-
Any pointer type can be converted into
unsafe.Pointer:unsafe.Pointer(&i) -
unsafe.Pointercan be cast into any pointer type:(*int)(p) -
A reference to an
unsafe.Pointerwill keep the underlying object from being garbage collected.
-
uintptr-
An integer type that is large enough to contain a pointer.
-
Any
unsafe.Pointercan be converted into auintptr:uintptr(p) -
Any
uintptrcan be converted into anunsafe.Pointer:unsafe.Pointer(p) -
References contained inside
uintptrare not considered by the garbage collector. -
The memory pointed at by the
uintptrcan be moved or reclaimed.
-
Endianess with memory deals with the ordering of bytes.
address 00 01 02 03
byte 16 a5 7d 6f
- Little endian:
- 00 (16) is least significant
- 03 (6f) is most significant
- Big endian:
- 03 (6f) is least significant
- 00 (16) is most significant
- int
- numeric types
- array
- string
- slice header
- pointer to array
- length
- capacity
- x86 vs amd64
- nil
- typed nil
- error value
- mutating write protected values
class: center, middle
Thanks to Bouke van der Bijl for inspiring this talk.
Library: https://github.com/bouk/monkey
Blog Post: https://bou.ke/blog/monkey-patching-in-go/
