StackExchange / wmi

WMI for Go
http://godoc.org/github.com/StackExchange/wmi
MIT License
433 stars 172 forks source link

failed to print string array #42

Open changsijay opened 6 years ago

changsijay commented 6 years ago

I am trying to print the gateway of each NetAdapter by following code, It print [] for all netadapters, not sure if this is a bug.

package main

import "github.com/StackExchange/wmi"
import "fmt"

// https://msdn.microsoft.com/en-us/library/aa394217(v=vs.85).aspx
type Win32_NetworkAdapterConfiguration struct {
    IPAddress []string
    DHCPServer string
    MACAddress string
    DefaultIPGateway []string
}

func main() {
    var dst2 []Win32_NetworkAdapterConfiguration
    query := fmt.Sprintf("")
    q := wmi.CreateQuery(&dst2, query)
    err := wmi.Query(q, &dst2)
    if err != nil {
        fmt.Println(err)
    }
    for _, v := range dst2 {
        fmt.Println(v.MACAddress, v.IPAddress, v.DHCPServer, v.DefaultIPGateway)
    }   
}
graf0 commented 5 years ago

The problem is, that oleutil.Value() in this case returns nil - and in wmi.go:288 nil value is ignored. It shouldn't be - default case in switch that follows should take care of nil value and check if it is not array.

troian commented 5 years ago

Guys I'm seeing that panic and looks like it is related to arrays I checked example above with latest master and it gives same panic Seems proposed fix does not solve it This one mentioned in another PR helps avoid panic but does not populates values into array fields This happens if build either GOARCH=386 or GOARCH=amd64

if prop.Value() == nil {
    continue
}
runtime: VirtualAlloc of 68719476736 bytes failed with errno=1455
fatal error: out of memory

runtime stack:
runtime.throw(0x53f9ba, 0xd)
        C:/Go/src/runtime/panic.go:608 +0x79
runtime.sysMap(0xc000400000, 0x1000000000, 0x64bdd8)
        C:/Go/src/runtime/mem_windows.go:122 +0x138
runtime.(*mheap).sysAlloc(0x6330e0, 0x1000000000, 0x3d4fdb0, 0x3d4fd88)
        C:/Go/src/runtime/malloc.go:619 +0x1d9
runtime.(*mheap).grow(0x6330e0, 0x800000, 0x0)
        C:/Go/src/runtime/mheap.go:920 +0x49
runtime.(*mheap).allocSpanLocked(0x6330e0, 0x800000, 0x64bde8, 0x20)
        C:/Go/src/runtime/mheap.go:848 +0x361
runtime.(*mheap).alloc_m(0x6330e0, 0x800000, 0x3d40100, 0x40b3c9)
        C:/Go/src/runtime/mheap.go:692 +0x127
runtime.(*mheap).alloc.func1()
        C:/Go/src/runtime/mheap.go:759 +0x53
runtime.(*mheap).alloc(0x6330e0, 0x800000, 0x3010100, 0x414ef3)
        C:/Go/src/runtime/mheap.go:758 +0x91
runtime.largeAlloc(0x1000000000, 0x440001, 0xc0000902d0)
        C:/Go/src/runtime/malloc.go:1019 +0x9e
runtime.mallocgc.func1()
        C:/Go/src/runtime/malloc.go:914 +0x4d
runtime.systemstack(0x0)
        C:/Go/src/runtime/asm_amd64.s:351 +0x6b
runtime.mstart()
        C:/Go/src/runtime/proc.go:1229

goroutine 4 [running, locked to thread]:
runtime.systemstack_switch()
        C:/Go/src/runtime/asm_amd64.s:311 fp=0xc00006f348 sp=0xc00006f340 pc=0x451080
runtime.mallocgc(0x1000000000, 0x517e40, 0x1, 0x0)
        C:/Go/src/runtime/malloc.go:913 +0x8d5 fp=0xc00006f3e8 sp=0xc00006f348 pc=0x40b985
runtime.makeslice(0x517e40, 0x100000000, 0x100000000, 0x0, 0x0, 0xc00006f490)
        C:/Go/src/runtime/slice.go:70 +0x7e fp=0xc00006f418 sp=0xc00006f3e8 pc=0x43c06e
github.com/go-ole/go-ole.(*SafeArrayConversion).ToValueArray(0xc00006f690, 0x18, 0x50f4a0, 0x55f5e0)
        github.com/go-ole/go-ole/safearrayconversion.go:37 +0x6e fp=0xc00006f500 sp=0xc00006f418 pc=0x4e9cce
github.com/StackExchange/wmi.(*Client).loadEntity(0x62fe50, 0x508960, 0xc00008ee70, 0x37f3058, 0x0, 0x0)
        github.com/StackExchange/wmi/wmi.go:378 +0xf46 fp=0xc00006f7c8 sp=0xc00006f500 pc=0x4efec6
github.com/StackExchange/wmi.(*Client).Query.func1(0xc00006f8c8, 0x55f5e0, 0x521680, 0x62fe50, 0xc00006f968, 0xc00006f958, 0x1, 0xc00006f998, 0x0, 0x0)
       github.com/StackExchange/wmi/wmi.go:215 +0xff fp=0xc00006f858 sp=0xc00006f7c8 pc=0x4f1c2f
github.com/StackExchange/wmi.(*Client).Query(0x62fe50, 0xc0000cc0a0, 0x4a, 0x508020, 0xc0000be060, 0xc0000be0a0, 0x2, 0x2, 0x0, 0x0)
        github.com/StackExchange/wmi/wmi.go:230 +0x828 fp=0xc00006f9c0 sp=0xc00006f858 pc=0x4ee9e8
github.com/StackExchange/wmi.Query(0xc0000cc0a0, 0x4a, 0x508020, 0xc0000be060, 0xc0000be0a0, 0x2, 0x2, 0x10, 0xc0000c20e8)
        github.com/StackExchange/wmi/wmi.go:76 +0x10c fp=0xc00006fa20 sp=0xc00006f9c0 pc=0x4ee18c
github.com/StackExchange/wmi.QueryNamespace(0xc0000cc0a0, 0x4a, 0x508020, 0xc0000be060, 0x542534, 0x16, 0x2, 0x0)
        github.com/StackExchange/wmi/wmi.go:59 +0xdf fp=0xc00006fa90 sp=0xc00006fa20 pc=0x4ee03f
...

Here is code

type Msvm_GuestNetworkAdapterConfiguration struct {
    InstanceID  string
    IPAddresses []string
}

func main() {
var q string
    var ips []Msvm_GuestNetworkAdapterConfiguration
    q = wmi.CreateQuery(&ips, "")
    if err = wmi.QueryNamespace(q, &ips, `root\virtualization\v2`); err != nil {
        fmt.Println(err.Error())
    }
}
troian commented 5 years ago

Seems I've found why this panic happens. I'm not windows expert but looks like root cause is captured

at first merged fix looks like right

if prop.VT == 0x0001 {
    continue
}

as far as I got when returning array from syscall prop.VT is always set to 0x200C (VT_ARRAY | VT_VARIANT) regardless there is any data or not In example below request returns 6 entries and in 5 of them IPAddresses not set and crazy value in Upperbounds (4294967295) cases out-of-memory issue. Using some advanced math and filtering techniques I just skipped those values and as result could get valid IPAddresses slice for remaining entry

In bad entries upperbouds looks like overflows it it equals to 0xFFFFFFFF

ole

func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) {
    totalElements, _ := sac.TotalElements(0)
    if totalElements == 4294967296 {
        return
    }

wmi

arr := safeArray.ToValueArray()
if len(arr) > 0 {
query:  SELECT InstanceID, IPAddresses FROM Msvm_GuestNetworkAdapterConfiguration
prop VT 8
prop VT 200c
sac.Array:  {"Dimensions":1,"FeaturesFlag":2176,"ElementsSize":24,"LocksAmount":0,"Data":0,"Bounds":[208,44,15,0,0,0,0,0,0,0,0,0,0,0,0,0]}
LowerBounds: 0, UpperBounds: 4294967295
prop VT 8
prop VT 200c
sac.Array:  {"Dimensions":1,"FeaturesFlag":2176,"ElementsSize":24,"LocksAmount":0,"Data":0,"Bounds":[128,44,15,0,0,0,0,0,0,0,0,0,0,0,0,0]}
LowerBounds: 0, UpperBounds: 4294967295
prop VT 8
prop VT 200c
sac.Array:  {"Dimensions":1,"FeaturesFlag":2176,"ElementsSize":24,"LocksAmount":0,"Data":0,"Bounds":[80,45,15,0,0,0,0,0,0,0,0,0,0,0,0,0]}
LowerBounds: 0, UpperBounds: 4294967295
prop VT 8
prop VT 200c
sac.Array:  {"Dimensions":1,"FeaturesFlag":2176,"ElementsSize":24,"LocksAmount":0,"Data":0,"Bounds":[128,46,15,0,0,0,0,0,0,0,0,0,0,0,0,0]}
LowerBounds: 0, UpperBounds: 4294967295
prop VT 8
prop VT 200c
sac.Array:  {"Dimensions":1,"FeaturesFlag":2176,"ElementsSize":24,"LocksAmount":0,"Data":0,"Bounds":[80,115,16,0,0,0,0,0,2,0,0,0,0,0,0,0]}
LowerBounds: 0, UpperBounds: 1
prop VT 8
prop VT 200c
sac.Array:  {"Dimensions":1,"FeaturesFlag":2176,"ElementsSize":24,"LocksAmount":0,"Data":0,"Bounds":[0,46,15,0,0,0,0,0,0,0,0,0,0,0,0,0]}
LowerBounds: 0, UpperBounds: 4294967295
[{"InstanceID":"Microsoft:GuestNetwork\\060F4EA8-7E79-4ED7-AD81-2CD905872BDC\\3204CD52-19B6-4FA1-8D9C-0BF1AA4C6E26","IPAddresses":null},{"InstanceID":"Microsoft:GuestNetwork\\0D83FB7D-CA0E-41F1-A518-E5CA27A9C619\\5BEC2DF1-13FB-4549-B93E-64D926CDD532","IPAddresses":null},{"InstanceID":"Microsoft:GuestNetwork\\76282C7E-C333-4F03-9FD7-4670FE7F6A9D\\2FB96A1C-1BB6-4B85-8D51-6C7E971E1639","IPAddresses":null},{"InstanceID":"Microsoft:GuestNetwork\\837EF8F6-8B21-45AA-90BB-A4038C11780A\\D219A96A-0AF3-46D8-A7A2-3BD25F1D527F","IPAddresses":null},{"InstanceID":"Microsoft:GuestNetwork\\A5E9BFAF-2C36-4389-999E-BCF1BAE232E4\\CCC717F9-8AFB-4883-BD31-8C8A4628810F","IPAddresses":["192.168.86.137","fe80::215:5dff:fe56:8005"]},{"InstanceID":"Microsoft:GuestNetwork\\C15141DA-4141-4CF5-8BC3-523F31257E53\\01AA1BD9-E080-4875-9620-45F40CD927A8","IPAddresses":null}]
troian commented 5 years ago

Found this issue. https://github.com/go-ole/go-ole/issues/172 So it's not a WMI

troian commented 5 years ago

Fix merged into go-ole https://github.com/go-ole/go-ole/pull/180