0

I'm building a windows aplication in Go using pure win32 api functions. My application suddenly hangs or gets stuck out of nowhere randomly. No error message or panic from go debugger. And the worst part is the problem is not appearing all the time but occasionally. I tried to put some 'log.Println' here and there in my program to trace exactly where it's getting stuck at and it appeared it's getting stuck at random places at random function calls but mostly, it's getting stuck at win32 api function calls like 'DefWindowProc' or 'GetMessage'. Over time my project got bigger and the more it got bigger the more often the problem seems to appear. So I tried to minimize the codes, simplify and comment out codes as much possible to see if the problem still occurs and I don't know it isn't helping much cause the problem just occurring randomly and my mind is a mess now.

I can just post codes from my original program but I'm not sure if those would help or not. I can show them if required. Now I've discovered something else which may or may not be related to my original problem. I was thinking if the garbage collector causing it since it gets called randomly if I'm doing something that is not GC friendly. I really don't know but here is this simple code. I never called the GC manually in my original application codes but here I'm doing it for test purpose.

package main

import (
    "log"
    "runtime"
    "syscall"

    "github.com/AllenDang/w32"
)

func main() {

    w32.CreateWindowEx(
        0, syscall.StringToUTF16Ptr("Button"), syscall.StringToUTF16Ptr("Hello World!"),
        w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE,
        100, 100, 1200, 800, 0, 0, 0, nil)

    runtime.GC()

    var msg w32.MSG
    for {
        log.Println("Calling 'GetMessage'")
        if w32.GetMessage(&msg, 0, 0, 0) == 0 {
            break
        }
        log.Println("End Calling 'GetMessage'")
        w32.TranslateMessage(&msg)
        w32.DispatchMessage(&msg)
    }
    return
}

The program doesn't go past the 'GetMessage' it gets stuck there. But if I comment out the 'runtime.GC()' then it does work perfectly. I'm coming from C++ and new to Go. I don't know much about how Go language's garbage collector works and I don't seem find any garbage that's getting collected there in those codes. Please help me out I would greatly appreciate it. Thanks in advance.

13
  • 1
    There is never (practically) a need to call runtime.GC. Commented Mar 4, 2021 at 17:48
  • 1
    Not familiar with win32, but CreateWindowEx call returns a value. Perhaps that call created some data which needs to persist for the lifetime of the object? Commented Mar 4, 2021 at 17:52
  • 2
    If it helps, the garbage collector should not effect the program correctness in any way. If the w32 package is being used correctly and yet is effected by GC, that is a bug in the w32 package. Commented Mar 4, 2021 at 18:03
  • 1
    Another idea, it may only be a side effect of the GC process, not the garbage collection itself. Many systems require thread-local context, and calling the functions from different threads may not work. Try running all the code in a single dedicated goroutine that calls runtime.LockOSThread Commented Mar 4, 2021 at 18:15
  • 1
    @JimB calling runtime.LockOSThread solved my problem. Thanks a lot! :D Commented Mar 4, 2021 at 19:22

1 Answer 1

1

It seems @JimB is right, I need to call runtime.LockOSThread before calling the OS API functions. If I call runtime.LockOSThread before calling them the program doesn't hang anymore. Still a lot to learn for sure.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.