[Go] 마초는'근육맨'이 아니에요.

10800 단어 Gotech
이 글은 Go 4 Advent Calendar 2020 25일째 되는 글이다.
마호패키지 봤어?이것은 마초이기 때문에 제목에서 호칭을 정확하게 이해하지 못하는 사람은 주의해야 한다.

배경: Performance regression이라는 Go1.15on MacOS의 Issue


동료 @budougumi0617은'내가 Go의 소스 코드를 읽을 때의 Tips'에서 Go Code Driving이 계속 개최하는 일을 소개했다.
https://devblog.thebase.in/entry/go-code-reading
이에 비해 당사는 BASE 구성원들과 정기적으로 Go Code Dreation 파티를 개최합니다.
한 사람이 해결할 수 없는 일은 모두 함께 보면 해결의 실마리를 찾을 수 있고, 다른 멤버들의 편집기를 훔칠 수도 있다.
12월 25일 오늘.ZU씨를 게스트로 모시고 테스팅 패키지 내 캐시 행동에 관해 읽은 뒤 잡담에서 "vim의 슬랙에서 예전에 @itchyny씨가 Go1.15에 도착했을 때 맥OS가 좀 느린 것 같아서 대단했다고 하더라"고 말했다.이 이슈인가'라는 주제로 진행된다.
https://github.com/golang/go/issues/40727
응, 이 아이슈는 어떻게 해결했지?이게 시작이야.

248719: [release-branch.go1.15] cmd/link: link dynamic library automatically


제목의 Issue입니다.
https://go-review.googlesource.com/c/go/+/248719/
이 아이슈의 차이는 다음과 같은 if문이다.
src/cmd/oldlink/internal/ld/go.go
if lib != "" && ctxt.HeadType == objabi.Hdarwin {
	machoadddynlib(lib, ctxt.LinkMode)
}
https://go-review.googlesource.com/c/go/+/248719/2/src/cmd/link/internal/ld/go.go
현재 버전의 코드가 좀 이상합니다.if-else의 처리입니다.
src/cmd/oldlink/internal/ld/go.go
if local == "_" && remote == "_" {
	// allow #pragma dynimport _ _ "foo.so"
	// to force a link of foo.so.
	havedynamic = 1

	if ctxt.HeadType == objabi.Hdarwin {
		machoadddynlib(lib, ctxt.LinkMode)
	} else {
		dynlib = append(dynlib, lib)
	}
	continue
}
objabi.Hdarwin의 경우 즉 맥OS에 맞는 운영체제의 경우 machoadddynlib() 함수라고 하고 그렇지 않으면dynamic import을 진행한다는 내용이다.
Issue는 다음을 나타냅니다.
Remove the unconditional imports in the runtime. Now,
Security.framework and CoreFoundation.framework are only linked
when the x509 package is imported (or otherwise specified).
모종의 경우처럼 필요 없는 import을 없애는 취지이기 때문에, Security.framework 및 CoreFoundation.프레임워크가 이런 행위를 제거한 것으로 추정된다.
이거, 동료 @glassemonkey씨 Swift씨CoreFoundation에서 잘 사용하고 있어요. 이런 정보 제공은 회의에서 그거에 맞는 녀석이라고 했어요.
이 PR의src/runtime/sys_darwin.go도 그 뜻을 이해할 수 있는 주석을 삭제하는 것을 확인할 수 있다.

https://go-review.googlesource.com/c/go/+/248719/2/src/runtime/sys_darwin.go

machoadddynlib


여기 나오는 macho은 어떤 화제인가.결론적으로'근육남'은 아니다.
이것은 "Mach-O"입니다.는 macOS 표준의 바이너리 파일 형식으로 사용되는 파일 형식입니다.
https://ja.wikipedia.org/wiki/Mach-O
이번 이슈는 맥OS에 대한runtime이기 때문에'맥시-O'의 연관성은 점과 점에서 밀접하게 연결되어 있다.
포장은 debug/macho처럼 강력한 포장이 있다.

macho는 "표시·O"입니다.


마르크

여담: 테스트 포장과 gocachest


처음에 Testing Package에 대한 사연을 썼어요.budougumi0617에 이런 기사가 있어요~ Go 런타임 디버깅을 지원하는 환경 변수by@mattn랑 공유했어요.gocachetest는 캐시 테스트 결과에 대해 다시 사용할지 여부를 표시하는 옵션입니다.이것은 실제 내부에서 어떤 사용을 하는지에 대해 조금만 읽었다.
우선 gochachetest를 사용하면 다음 코드의 DebugTest가 사실입니다.
src/cmd/go/internal/cache/cache.go
func initEnv() {
	verify = false
	debugHash = false
	debug := strings.Split(os.Getenv("GODEBUG"), ",")
	for _, f := range debug {
		if f == "gocacheverify=1" {
			verify = true
		}
		if f == "gocachehash=1" {
			debugHash = true
		}
		if f == "gocachetest=1" {
			DebugTest = true
		}
	}
}
https://golang.org/src/cmd/go/internal/cache/cache.go#L130
이후 테스트를 실행할 때 DebugTest를 보고 로그를 출력하는 지점 코드를 분산시켰다.
cmd/go/internal/test/test.go
func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bool {
	if len(pkgArgs) == 0 {
		// Caching does not apply to "go test",
		// only to "go test foo" (including "go test .").
		if cache.DebugTest {
			fmt.Fprintf(os.Stderr, "testcache: caching disabled in local directory mode\n")
		}
		c.disableCache = true
		return false
	}
https://golang.org/src/cmd/go/internal/test/test.go#L1304
그럼 Gopher 여러분 메리 크리스마스!

좋은 웹페이지 즐겨찾기