いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-334 (uber-go/nilaway)(nilの可能性をチェックしてくれる静的解析ツール)(うまく動かなかった・・)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。忘れない内にメモメモ。。。

以下、一旦試してみたのですが、まだちゃんと動いてくれない感じでした。

多分公開直後でまだ調整されていないのでしょう。今後に期待ってことで試した経緯も残しておきます

2023-08-01 追記 修正された模様でちゃんとインストール出来るようになってました。なので、以下の記事内容はもう発生しません。

ここからメモスタート。

たまたまですが、以下のリポジトリを発見。

github.com

nilな変数にアクセスして panic になってしまうのを防ぐための静的解析ツールみたいですね。

標準の nilless アナライザよりもいろんな点で優れているとのこと。

ちょっと試してみました。

試してみる

インストール

$ go install go.uber.org/nilaway/cmd/nilaway@latest
go: go.uber.org/nilaway/cmd/nilaway@latest: unrecognized import path "go.uber.org/nilaway/cmd/nilaway": reading https://go.uber.org/nilaway/cmd/nilaway?go-get=1: 404 Not Found
        server response: 404 page not found

えっ・・・。

あー、READMEに載ってるドメインが間違っているのね。おけおけ

$ go install github.com/uber-go/nilaway/cmd/nilaway@latest
go: github.com/uber-go/nilaway/cmd/nilaway@latest: github.com/uber-go/nilaway@v0.0.0-20230728224449-33e080ad2c45: parsing go.mod:
        module declares its path as: go.uber.org/nilaway
                but was required as: github.com/uber-go/nilaway

えっ・・・。

go.mod 間違えてるやん・・。

てことで、試したいだけなので、clone してちょっと調整してみます。

$ git clone https://github.com/uber-go/nilaway.git
Cloning into 'nilaway'...
remote: Enumerating objects: 406, done.
remote: Counting objects: 100% (406/406), done.
remote: Compressing objects: 100% (195/195), done.
remote: Total 406 (delta 148), reused 381 (delta 134), pack-reused 0
Receiving objects: 100% (406/406), 280.50 KiB | 7.01 MiB/s, done.
Resolving deltas: 100% (148/148), done.

$ cd nilaway

#
# モジュールパスを調整
#
$ go mod edit -module=github.com/uber-go/nilaway
$ cat go.mod | head -n 1
module github.com/uber-go/nilaway

#
# ソース内のモジュールパスを調整
#
$ grep -rl 'go.uber.org/nilaway' . | xargs sed -i 's/go.uber.org\/nilaway/github.com\/uber-go\/nilaway/g'


#
# インストール
#
$ go install ./cmd/nilaway
$ ls -1 $(go env GOPATH)/bin/nil*
/workspace/go/bin/nilaway

ってことで、とりあえずビルドしてインストール出来ました。

nilの可能性があるソースで試してみる

以下のようなソースを用意。

package main

import (
    "fmt"
    "time"
)

type myStruct struct {
    v int
}

func main() {
    var p *myStruct
    if cond() {
        p = &myStruct{100}
    }

    fmt.Println(p.v)
}

func cond() bool {
    return time.Now().Second()%2 == 0
}

動かした時間によって、nilアクセスでpanicしたりしなかったりします。

$ task run
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4880be]

goroutine 1 [running]:
main.main()
        /workspace/gotmp/main.go:18 +0x3e
exit status 2
task: Failed to run task "run": exit status 1


$ task run
100

これに nilaway をかけてみます。

$ nilaway ./...
$

えっ・・・。何も出力されないぞ。。

ソースが良くないのかな?同じパッケージからだと無理なのかも。

てことでちょっと分割しました。

package my

import "time"

type St struct {
    V int
}

func Cond() bool {
    return time.Now().Second()%2 == 0
}
package main

import (
    "app/pkg/my"
)

func main() {
    Run()
}

func Run() error {
    var p *my.St
    if my.Cond() {
        p = &my.St{V: 100}
    }
    print(p.V)

    return nil
}

おけ。再度実行。

$ nilaway ./...
$

・・・・。まだ公開直後でうまく動いていないのでしょう。

とりあえずメモだけ残しておくってことで。。(¯―¯٥)

参考情報

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。