Skip to content

Instantly share code, notes, and snippets.

@mihai-vlc
Created July 10, 2022 11:23
Show Gist options
  • Save mihai-vlc/2cac74619af8ea83a036141919918986 to your computer and use it in GitHub Desktop.
Save mihai-vlc/2cac74619af8ea83a036141919918986 to your computer and use it in GitHub Desktop.
Attempt to reload dll in a golang program

I found that when we attempt to use the DLL generated by GO we get the following error:

fatal error: bad sweepgen in refill

runtime stack:
runtime.throw({0x807f8e?, 0xc0000c3df8?})
        C:/Program Files/Go/src/runtime/panic.go:992 +0x76
runtime.(*mcache).refill(0x271caaf0a28, 0x2)
        C:/Program Files/Go/src/runtime/mcache.go:156 +0x1ec
runtime.(*mcache).nextFree(0x271caaf0a28, 0x2)
        C:/Program Files/Go/src/runtime/malloc.go:886 +0x85
runtime.mallocgc(0x8, 0x7f69a0, 0x1)
        C:/Program Files/Go/src/runtime/malloc.go:1085 +0x40c
runtime.growslice(0x7f69a0, {0x0?, 0x76ad79?, 0x7be52d?}, 0xec7e1ff708?)
        C:/Program Files/Go/src/runtime/slice.go:278 +0x28d
runtime.doaddtimer(0x1c000032a00, 0xc0000e0000)
        C:/Program Files/Go/src/runtime/time.go:295 +0x95
runtime.modtimer(0xc0000e0000, 0x5af67e66487c, 0x0, 0x80d220, {0x7f6160?, 0xc00004a000}, 0x0)
        C:/Program Files/Go/src/runtime/time.go:493 +0x27c
runtime.resettimer(0x86a618?, 0x86a040?)
        C:/Program Files/Go/src/runtime/time.go:540 +0x2d
runtime.resetForSleep(0xc00004a000?, 0x400000002?)
        C:/Program Files/Go/src/runtime/time.go:203 +0x25
runtime.park_m(0xc00004a000?)
        C:/Program Files/Go/src/runtime/proc.go:3325 +0x8b
runtime.mcall()
        C:/Program Files/Go/src/runtime/asm_amd64.s:425 +0x4a

goroutine 1 [sleep]:
time.Sleep(0x3b9aca00)

When generating the DLL with g++ the module replacement works as expected. And it's possible to replace the function while the main program is still running.

Relevant reported issues:

Alternatives (to review in the future):

if ($IsWindows) {
Push-Location ./lib
# C:\tools\msys64\usr\bin\env.exe `
# MSYSTEM=MINGW64 `
# CHERE_INVOKING=1 `
# /usr/bin/bash -lc "go build -buildmode=c-shared -gcflags='all=-N -l' -o ../dist/lib.dll ."
C:\tools\msys64\usr\bin\env.exe `
MSYSTEM=MINGW64 `
CHERE_INVOKING=1 `
/usr/bin/bash -lc "g++ -shared -o ../dist/lib.dll mathlib.c"
Pop-Location
if ($args[0] -eq 'all') {
Push-Location ./uselib
C:\tools\msys64\usr\bin\env.exe `
MSYSTEM=MINGW64 `
CHERE_INVOKING=1 `
/usr/bin/bash -lc "go build -gcflags='all=-N -l' -o ../dist/uselib.exe ."
Pop-Location
}
}
package main
import "C"
//export Add
func Add(a, b int) int {
return a + b + 80
}
func main() {}
// go build -buildmode=c-shared -gcflags='all=-N -l' -o ../dist/lib.dll .
#include <windows.h>
#include <stdlib.h>
extern "C" int Add(int a, int b)
{
return a + b;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
return TRUE;
}
// g++ -shared -o ../dist/lib.dll mathlib.c
package main
import (
"io"
"os"
"syscall"
"time"
)
func main() {
var lastModified time.Time
var add *syscall.Proc
var mathLib *syscall.DLL
for {
dllName := "lib.dll"
file, err := os.Stat(dllName)
if err != nil {
println("Failed read the DLL file")
return
}
modTime := file.ModTime()
if modTime != lastModified {
println(modTime.GoString(), lastModified.GoString())
lastModified = modTime
if mathLib != nil {
mathLib.Release()
}
tmpDllName := lastModified.Format("0405") + "_" + dllName
err := Copy(dllName, tmpDllName)
if err != nil {
println("Failed to copy the dll file")
}
mathLib = syscall.MustLoadDLL(tmpDllName)
add = mathLib.MustFindProc("Add")
}
res, _, _ := add.Call(4, 7)
println(res)
time.Sleep(1 * time.Second)
}
}
// Copy the src file to dst. Any existing file will be overwritten and will not
// copy file attributes.
func Copy(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment