gots icon indicating copy to clipboard operation
gots copied to clipboard

NewPESHeader causes memory escape

Open ZloyDyadka opened this issue 6 years ago • 0 comments

Version of go

go version go1.12 linux/amd64

Example:

package main

import (
	"encoding/hex"

	"github.com/Comcast/gots/packet"
	"github.com/Comcast/gots/pes"
)

func main() {
	pkt := parseHexString(
		"4740661a000001c006ff80800521dee9ca57fff94c801d2000210995341d9d43" +
			"61089848180b0884626048901425ddc09249220129d2fce728111c987e67ecb7" +
			"4284af5099181d8cd095b841b0c7539ad6c06260536e137615560052369fc984" +
			"0b3af532418b3924a6b28d6208a6a9e3d22d533ec89646246c734a696407a95e" +
			"3bf230404a4ad0000201038cf0c6a2e32abda45b7effe9f79280a137ed120fd3" +
			"bd8252e07cddadbe6d2b60084208500e06f6ceb6acf2c43011c5938b")

	test(&pkt)
}

func test(pkt *packet.Packet) {
	data, err := packet.PESHeader(pkt)
	if err != nil {
		panic(err)
	}

	pesHeaderData := make([]byte, packet.PacketSize)
	copy(pesHeaderData, data)

	_, err = pes.NewPESHeader(pesHeaderData[:len(data)])
	if err != nil {
		panic(err)
	}
}

func parseHexString(h string) packet.Packet {
	b, err := hex.DecodeString(h)
	if err != nil {
		panic("bad test: " + h)
	}
	var pkt packet.Packet
	if copy(pkt[:], b) != packet.PacketSize {
		panic("bad test (wrong length): " + h)
	}

	return pkt
}
go build --gcflags '-m -l' escape.go 
# command-line-arguments
./escape.go:40:22: "bad test: " + h escapes to heap
./escape.go:44:37: "bad test (wrong length): " + h escapes to heap
./escape.go:37:21: parseHexString h does not escape
./escape.go:43:13: parseHexString pkt does not escape
./escape.go:28:23: make([]byte, packet.PacketSize) escapes to heap
./escape.go:22:11: test pkt does not escape
./escape.go:19:7: main &pkt does not escape

Solution options:

  • Use sync.Pool for pESHeader.data
  • Use copy of pesBytes for pESHeader.data
  • Something else?

ZloyDyadka avatar Oct 22 '19 14:10 ZloyDyadka