Returning an empty string is causing a panic in GO

0

Hoping someone can explain this to me.

I've uploaded the code here:

https://github.com/jherman/golang-bug-0

The code it's panicking on has to do with the func getDevicePath. If I return an empty string, I get a panic, but if I turn the buffer pointer to a string, it returns fine. I also noticed if I comment out the second SetupDiGetDeviceInterfaceDetail, then return an empty string, it then works. I don't get it.

Here is the code that causes the issue:

func getDevicePath(dis HDEVINFO, edata *SP_DEVICE_INTERFACE_DATA) (path string, err error) {
    var (
        bufSize uint32
        cbSize  = uint32(unsafe.Sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA{}))
    )

    // get required buffer size
    err = SetupDiGetDeviceInterfaceDetail(dis, edata, nil, 0, &bufSize, nil)
    if err != windows.ERROR_INSUFFICIENT_BUFFER {
        return
    }

    didd := &SP_DEVICE_INTERFACE_DETAIL_DATA{
        cbSize: cbSize,
    }

    err = SetupDiGetDeviceInterfaceDetail(dis, edata, didd, bufSize, nil, nil)
    if err != nil {
        return
    }

    path = windows.UTF16PtrToString(&didd.DevicePath[0]) // WORKS
    // path = "" //! DOES NOT WORK

    return
}

Here is the panic result:

API server listening at: 127.0.0.1:14344
unexpected fault address 0xffffffffffffffff
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0xffffffffffffffff pc=0xd85116]

goroutine 19 [running]:
runtime.throw(0xdc29b1, 0x5)
    c:/go/src/runtime/panic.go:1117 +0x79 fp=0xc000099bf8 sp=0xc000099bc8 pc=0xc42059
runtime.sigpanic()
    c:/go/src/runtime/signal_windows.go:245 +0x15e fp=0xc000099c28 sp=0xc000099bf8 pc=0xc578de
runtime: unexpected return pc for github.com/jherman/golang-bug-0.getDevicePath called from 0x5f006e00650076
stack: frame={sp:0xc000099c28, fp:0xc000099c30} stack=[0xc000096000,0xc00009a000)
000000c000099b28:  000000c000099b58  0000000000c6ec49 <runtime.writeErr+73> 
000000c000099b38:  0000000000000002  0000000000dd5c59 
000000c000099b48:  0000000000000001  0000000000000001 
000000c000099b58:  000000c000099b90  0000000000c43a35 <runtime.gwrite+181> 
000000c000099b68:  0000000000dd5c59  0000000000000001 
000000c000099b78:  0000000000000001  000000c000099ba0 
000000c000099b88:  0000000000c4223e <runtime.fatalthrow+94>  000000c000099b98 
000000c000099b98:  0000000000c72360 <runtime.fatalthrow.func1+0>  000000c000084600 
000000c000099ba8:  0000000000c42059 <runtime.throw+121>  000000c000099bc8 
000000c000099bb8:  000000c000099be8  0000000000c42059 <runtime.throw+121> 
000000c000099bc8:  000000c000099bd0  0000000000c722c0 <runtime.throw.func1+0> 
000000c000099bd8:  0000000000dc29b1  0000000000000005 
000000c000099be8:  000000c000099c18  0000000000c578de <runtime.sigpanic+350> 
000000c000099bf8:  0000000000dc29b1  0000000000000005 
000000c000099c08:  ffffffffffffffff  000000c000084600 
000000c000099c18:  0026006b00730069  0000000000d85116 <github.com/jherman/golang-bug-0.getDevicePath+406> 
000000c000099c28: <005f006e00650076 >0065006d0076006e 
000000c000099c38:  006f007200700026  0000000000000000 
000000c000099c48:  0000000000000000  0000000000000000 
000000c000099c58:  0000000000000000  0035002300610037 
000000c000099c68:  0034006400320026  0037003800640035 
000000c000099c78:  0026003000260064  0030003000300030 
000000c000099c88:  007b002300300030  0035006600330035 
000000c000099c98:  0037003000330036  006200360062002d 
000000c000099ca8:  00310031002d0066  0039002d00300064 
000000c000099cb8:  002d003200660034  0030006100300030 
000000c000099cc8:  0065003100390063  0062003800620066 
000000c000099cd8:  000000c00000007d  0000000000d845d9 <github.com/jherman/golang-bug-0.FindDevices+377> 
000000c000099ce8:  0000000000dcf698  0000000000000000 
000000c000099cf8:  000000c000099ef8  0000000000000000 
000000c000099d08:  0000000000000000  0000000000000000 
000000c000099d18:  0000025df94e1290  0000000000000000 
000000c000099d28:  0000000000000000 
github.com/jherman/golang-bug-0.getDevicePath(0x65006d0076006e, 0x6f007200700026, 0x0, 0x0, 0x0, 0x0)
    c:/repos/work/github.com/jherman/golang-bug-0/main.go:159 +0x196 fp=0xc000099c30 sp=0xc000099c28 pc=0xd85116
created by testing.(*T).Run
    c:/go/src/testing/testing.go:1238 +0x63c

goroutine 1 [chan receive]:
testing.(*T).Run(0xc000084480, 0xdc50e7, 0xf, 0xdcf6a0, 0x2b75cabc2b75ca00)
    c:/go/src/testing/testing.go:1239 +0x66a
testing.runTests.func1(0xc000084300)
    c:/go/src/testing/testing.go:1511 +0xbd
testing.tRunner(0xc000084300, 0xc0000c9c00)
    c:/go/src/testing/testing.go:1193 +0x1a3
testing.runTests(0xc00009c078, 0xe87fe0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x25df97c0100)
    c:/go/src/testing/testing.go:1509 +0x448
testing.(*M).Run(0xc0000f6000, 0x0)
    c:/go/src/testing/testing.go:1417 +0x514
main.main()
    _testmain.go:43 +0xc8
Process exiting with code: 0

Any help is appreciated.

NOTE: This is a Windows API call - so it should be ran in windows.

NOTE: Please ignore the fact that it works when using this ptr to string, as I normally would not return an empty string. I'm more interested in why it panics on an empty string.

go
panic
asked on Stack Overflow May 26, 2021 by ymerej • edited May 26, 2021 by ymerej

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0