Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typecheck: false positive "unused variable" and "unused import" in fairly standard code #2014

Closed
3 of 4 tasks
cyphar opened this issue May 25, 2021 · 3 comments
Closed
3 of 4 tasks
Labels
bug Something isn't working

Comments

@cyphar
Copy link

cyphar commented May 25, 2021

  • Yes, I'm using a binary release within 2 latest major releases. Only such installations are supported.
  • Yes, I've searched similar issues on GitHub and didn't find any.
  • Yes, I've included all information below (version, config, etc).
  • Yes, I've tried with the standalone linter if available. (https://golangci-lint.run/usage/linters/)
Description of the problem

Currently there are a couple of false-positive typecheck errors when running golang-ci on the runc codebase. I haven't tried to reduce these to a minimum test case, so these are snippets from the source tree.

The following code from runc trips up typecheck.

// newProcess returns a new libcontainer Process with the arguments from the
// spec and stdio from the current process.
func newProcess(p specs.Process, init bool, logLevel string) (*libcontainer.Process, error) {
	lp := &libcontainer.Process{
		Args: p.Args,
		Env:  p.Env,
		// TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
		User:            fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
		Cwd:             p.Cwd,
		Label:           p.SelinuxLabel,
		NoNewPrivileges: &p.NoNewPrivileges,
		AppArmorProfile: p.ApparmorProfile,
		Init:            init,
		LogLevel:        logLevel,
	}

	if p.ConsoleSize != nil {
		lp.ConsoleWidth = uint16(p.ConsoleSize.Width)
		lp.ConsoleHeight = uint16(p.ConsoleSize.Height)
	}

	if p.Capabilities != nil {
		lp.Capabilities = &configs.Capabilities{}
		lp.Capabilities.Bounding = p.Capabilities.Bounding
		lp.Capabilities.Effective = p.Capabilities.Effective
		lp.Capabilities.Inheritable = p.Capabilities.Inheritable
		lp.Capabilities.Permitted = p.Capabilities.Permitted
		lp.Capabilities.Ambient = p.Capabilities.Ambient
	}
	for _, gid := range p.User.AdditionalGids {
		lp.AdditionalGroups = append(lp.AdditionalGroups, strconv.FormatUint(uint64(gid), 10))
	}
	for _, rlimit := range p.Rlimits {
		rl, err := createLibContainerRlimit(rlimit)
		if err != nil {
			return nil, err
		}
		lp.Rlimits = append(lp.Rlimits, rl)
	}
	return lp, nil
}
utils_linux.go:129:9: gid declared but not used (typecheck)
        for _, gid := range p.User.AdditionalGids {
               ^
utils_linux.go:133:3: rl declared but not used (typecheck)
                rl, err := createLibContainerRlimit(rlimit)
                ^

And something similar happens with a syscall import:

import (
	"syscall"
)

// ... snip ...

// runContainer runs the container with the specific config and arguments
//
// buffers are returned containing the STDOUT and STDERR output for the run
// along with the exit code and any go error
func runContainer(t *testing.T, config *configs.Config, console string, args ...string) (buffers *stdBuffers, exitCode int, err error) {
	container, err := newContainer(t, config)
	if err != nil {
		return nil, -1, err
	}
	defer destroyContainer(container)
	buffers = newStdBuffers()
	process := &libcontainer.Process{
		Cwd:    "/",
		Args:   args,
		Env:    standardEnvironment,
		Stdin:  buffers.Stdin,
		Stdout: buffers.Stdout,
		Stderr: buffers.Stderr,
		Init:   true,
	}

	err = container.Run(process)
	if err != nil {
		return buffers, -1, err
	}
	ps, err := process.Wait()
	if err != nil {
		return buffers, -1, err
	}
	status := ps.Sys().(syscall.WaitStatus)
	if status.Exited() {
		exitCode = status.ExitStatus()
	} else if status.Signaled() {
		exitCode = -int(status.Signal())
	} else {
		return buffers, -1, err
	}
	return
}
libcontainer/integration/utils_test.go:14:2: "syscall" imported but not used (typecheck)
        "syscall"
        ^
Version of golangci-lint
$ golangci-lint --version
golangci-lint has version 1.40.1 built from 625445b1 on 2021-05-14T11:44:45Z
Config file
$ cat .golangci.yml
run:
  build-tags:
    - seccomp

linters:
  enable:
    - gofmt
Go environment
$ go version && go env
go version go1.16.4 linux/amd64
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/cyphar/.cache/go-build"
GOENV="/home/cyphar/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/cyphar/.local/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/cyphar/.local"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib64/go/1.16"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib64/go/1.16/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.4"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/cyphar/.local/src/github.com/opencontainers/runc/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build4179905305=/tmp/go-build -gno-record-gcc-switches"
Verbose output of running
$ golangci-lint cache clean
$ golangci-lint run -v
INFO [config_reader] Config search paths: [./ /home/cyphar/.local/src/github.com/opencontainers/runc /home/cyphar/.local/src/github.com/opencontainers /home/cyphar/.local/src/github.com /home/cyphar/.local/src /home/cyphar/.local /home/cyphar /home /]
INFO [config_reader] Used config file .golangci.yml
INFO [lintersdb] Active 11 linters: [deadcode errcheck gofmt gosimple govet ineffassign staticcheck structcheck typecheck unused varcheck]
INFO [loader] Using build tags: [seccomp]
INFO [loader] Go packages loading at mode 575 (exports_file|imports|name|types_sizes|compiled_files|files|deps) took 954.28777ms
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 33.217745ms
INFO [linters context/goanalysis] analyzers took 18.186819328s with top 10 stages: buildir: 11.987374878s, inspect: 642.888036ms, nilness: 522.874145ms, fact_purity: 422.115043ms, ctrlflow: 385.837038ms, printf: 344.867245ms, fact_deprecated: 314.402418ms, gofmt: 307.800085ms, typedness: 171.428095ms, directives: 170.726644ms
INFO [runner] Issues before processing: 756, after processing: 3
INFO [runner] Processors filtering stat (out/in): filename_unadjuster: 738/738, skip_files: 738/738, skip_dirs: 738/738, identifier_marker: 738/738, diff: 3/3, path_shortener: 3/3, path_prettifier: 738/738, exclude: 738/738, max_same_issues: 3/3, max_from_linter: 3/3, path_prefixer: 3/3, cgo: 738/756, autogenerated_exclude: 738/738, exclude-rules: 668/738, nolint: 399/668, uniq_by_line: 3/399, max_per_file_from_linter: 3/3, source_code: 3/3, severity-rules: 3/3, sort_results: 3/3
INFO [runner] processing took 46.600434ms with stages: exclude-rules: 22.597687ms, identifier_marker: 15.041987ms, nolint: 5.644105ms, path_prettifier: 1.69729ms, autogenerated_exclude: 898.324µs, skip_dirs: 430.279µs, source_code: 84.378µs, cgo: 78.11µs, filename_unadjuster: 60.411µs, uniq_by_line: 53.35µs, max_same_issues: 5.65µs, path_shortener: 2.539µs, max_from_linter: 2.106µs, max_per_file_from_linter: 1.639µs, exclude: 541ns, diff: 536ns, severity-rules: 453ns, sort_results: 414ns, skip_files: 405ns, path_prefixer: 230ns
INFO [runner] linters took 5.541844945s with stages: goanalysis_metalinter: 5.495077059s
utils_linux.go:129:9: gid declared but not used (typecheck)
        for _, gid := range p.User.AdditionalGids {
               ^
utils_linux.go:133:3: rl declared but not used (typecheck)
                rl, err := createLibContainerRlimit(rlimit)
                ^
libcontainer/integration/utils_test.go:14:2: "syscall" imported but not used (typecheck)
        "syscall"
        ^
INFO File cache stats: 2 entries of total size 17.1KiB
INFO Memory: 67 samples, avg is 228.5MB, max is 410.4MB
INFO Execution took 6.536389745s
Code example or link to a public repository

I've listed the code above, and the repo is https://github.com/opencontainers/runc.

@cyphar cyphar added the bug Something isn't working label May 25, 2021
@boring-cyborg
Copy link

boring-cyborg bot commented May 25, 2021

Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.

@cyphar
Copy link
Author

cyphar commented May 25, 2021

Sorry, this seems to have been some weird issue caused by cgo build requirements (libseccomp in particular) not being present. This still seems like a bug -- but it's not really affecting me anymore so feel free to close this.

@ldez
Copy link
Member

ldez commented May 25, 2021

Hello,

typecheck is not a real linter, it's just a way to display compilation error.

As the problem seems to be fixed for you, I close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants