Go module dependency debugging workflow

171 views
Skip to first unread message

gonutz

unread,
Apr 9, 2021, 11:38:12 AM4/9/21
to golang-nuts
I was referred here from my closed Github issue ( https://github.com/golang/go/issues/45467 ). I have a practical question about debugging in the world of Go modules.

The scenario: I am creating module mp3player, my main program. It uses library module mp3. While debugging I insert print statements in my main program. They show. Now I need to go deeper and want to insert a print statement in the library code. How do I do that?

I found that the code that is actually compiled is the copy of the library with the version specified by my go.mod file in the go mod cache (GOPATH/pkg/mod). The file tree in the mod cache is read-only (for good reasons) so while changing it works, it is not the way to go.

I could create a local commit to the library or create a new debug branch in my local copy of the library. Then I insert my debug code and commit it. Then I point my main program's go.mod file at the new commit/branch, adding a replace along the way to use my local copy. Then when I am done debugging I roll everything back. This works but is very annoying for just a temporary print statement here and there.

I also tried temporarily vendoring my main program but then it would not build at all. Concretely I use GLFW which contains C files but they are not copied over by go mod vendor so the library does not compile anymore. Then even if vendoring would work correctly, I still consider this too much work for debugging and the go module reference says not to change vendored files anyway.

In GOPATH mode debugging a library was as simple as changing it, running the main program and see the output. Of course I see the benefits of Go modules and want to use them but this common use case seems hard to do now.

How do you do this?

Best Regards
gonutz

Carla Pfaff

unread,
Apr 9, 2021, 12:20:46 PM4/9/21
to golang-nuts
On Friday, 9 April 2021 at 17:38:12 UTC+2 gonutz wrote:
I could create a local commit to the library or create a new debug branch in my local copy of the library. Then I insert my debug code and commit it. Then I point my main program's go.mod file at the new commit/branch, adding a replace along the way to use my local copy. Then when I am done debugging I roll everything back. This works but is very annoying for just a temporary print statement here and there.

Use the local replace with the v0.0.0-unpublished pseudo-version number, then you don't have to commit and roll back all the time.

gonutz

unread,
Apr 9, 2021, 2:21:36 PM4/9/21
to golang-nuts
Oh thanks a lot Carla Pfaff! I did not even know a v0.0.0-unpublished pseudo-version existed. It is not mentioned in the Go Modules Reference https://golang.org/ref/mod for whatever reason. This really takes the edge off.

I was also pointed at the replace by some people on StackOverflow and while I could swear that it did not work for me last week, when I create a fresh example project and use a replace it really deos seem to use my local changes, no matter what version is specified in the require statement. I am not sure how this all works, all I know is that Go modules are really really complicated, the most complicated thing about Go right now in my opinion. I loved Go because of its simplicity and while I really value the option to have reproducible builds - as this has been a pain point for me as well - this solution is way to complex for my taste. Maybe this complexity is inherent to the problem, maybe not, I do not know as I have not created a dependency tool like this myself. All I know is that it is really hard to use and makes creating Go code harder overall.
Reply all
Reply to author
Forward
0 new messages