mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-09-05 16:47:31 -04:00
Make ETW no-op on ARM
Proper support for ETW on ARM will require additional changes in Go to support more than 16 bytes of arguments to a syscall callback. Until this work is done, the ETW package is being changed to no-op on ARM.
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
// +build amd64 arm64
|
||||||
|
|
||||||
|
package etw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewProviderWithID creates and registers a new ETW provider, allowing the
|
||||||
|
// provider ID to be manually specified. This is most useful when there is an
|
||||||
|
// existing provider ID that must be used to conform to existing diagnostic
|
||||||
|
// infrastructure.
|
||||||
|
func NewProviderWithID(name string, id *guid.GUID, callback EnableCallback) (provider *Provider, err error) {
|
||||||
|
providerCallbackOnce.Do(func() {
|
||||||
|
globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
|
||||||
|
})
|
||||||
|
|
||||||
|
provider = providers.newProvider()
|
||||||
|
defer func(provider *Provider) {
|
||||||
|
if err != nil {
|
||||||
|
providers.removeProvider(provider)
|
||||||
|
}
|
||||||
|
}(provider)
|
||||||
|
provider.ID = id
|
||||||
|
provider.callback = callback
|
||||||
|
|
||||||
|
if err := eventRegister((*windows.GUID)(provider.ID), globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata := &bytes.Buffer{}
|
||||||
|
binary.Write(metadata, binary.LittleEndian, uint16(0)) // Write empty size for buffer (to update later)
|
||||||
|
metadata.WriteString(name)
|
||||||
|
metadata.WriteByte(0) // Null terminator for name
|
||||||
|
binary.LittleEndian.PutUint16(metadata.Bytes(), uint16(metadata.Len())) // Update the size at the beginning of the buffer
|
||||||
|
provider.metadata = metadata.Bytes()
|
||||||
|
|
||||||
|
if err := eventSetInformation(
|
||||||
|
provider.handle,
|
||||||
|
eventInfoClassProviderSetTraits,
|
||||||
|
uintptr(unsafe.Pointer(&provider.metadata[0])),
|
||||||
|
uint32(len(provider.metadata))); err != nil {
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// +build arm 386
|
||||||
|
|
||||||
|
package etw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewProviderWithID returns a nil provider on unsupported platforms.
|
||||||
|
func NewProviderWithID(name string, id *guid.GUID, callback EnableCallback) (provider *Provider, err error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
+16
-43
@@ -1,12 +1,10 @@
|
|||||||
package etw
|
package etw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/Microsoft/go-winio/pkg/guid"
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
@@ -29,6 +27,10 @@ type Provider struct {
|
|||||||
|
|
||||||
// String returns the `provider`.ID as a string
|
// String returns the `provider`.ID as a string
|
||||||
func (provider *Provider) String() string {
|
func (provider *Provider) String() string {
|
||||||
|
if provider == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
|
||||||
return provider.ID.String()
|
return provider.ID.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,49 +122,12 @@ func NewProvider(name string, callback EnableCallback) (provider *Provider, err
|
|||||||
return NewProviderWithID(name, providerIDFromName(name), callback)
|
return NewProviderWithID(name, providerIDFromName(name), callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProviderWithID creates and registers a new ETW provider, allowing the
|
|
||||||
// provider ID to be manually specified. This is most useful when there is an
|
|
||||||
// existing provider ID that must be used to conform to existing diagnostic
|
|
||||||
// infrastructure.
|
|
||||||
func NewProviderWithID(name string, id *guid.GUID, callback EnableCallback) (provider *Provider, err error) {
|
|
||||||
providerCallbackOnce.Do(func() {
|
|
||||||
globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
|
|
||||||
})
|
|
||||||
|
|
||||||
provider = providers.newProvider()
|
|
||||||
defer func(provider *Provider) {
|
|
||||||
if err != nil {
|
|
||||||
providers.removeProvider(provider)
|
|
||||||
}
|
|
||||||
}(provider)
|
|
||||||
provider.ID = id
|
|
||||||
provider.callback = callback
|
|
||||||
|
|
||||||
if err := eventRegister((*windows.GUID)(provider.ID), globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata := &bytes.Buffer{}
|
|
||||||
binary.Write(metadata, binary.LittleEndian, uint16(0)) // Write empty size for buffer (to update later)
|
|
||||||
metadata.WriteString(name)
|
|
||||||
metadata.WriteByte(0) // Null terminator for name
|
|
||||||
binary.LittleEndian.PutUint16(metadata.Bytes(), uint16(metadata.Len())) // Update the size at the beginning of the buffer
|
|
||||||
provider.metadata = metadata.Bytes()
|
|
||||||
|
|
||||||
if err := eventSetInformation(
|
|
||||||
provider.handle,
|
|
||||||
eventInfoClassProviderSetTraits,
|
|
||||||
uintptr(unsafe.Pointer(&provider.metadata[0])),
|
|
||||||
uint32(len(provider.metadata))); err != nil {
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close unregisters the provider.
|
// Close unregisters the provider.
|
||||||
func (provider *Provider) Close() error {
|
func (provider *Provider) Close() error {
|
||||||
|
if provider == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
providers.removeProvider(provider)
|
providers.removeProvider(provider)
|
||||||
return eventUnregister(provider.handle)
|
return eventUnregister(provider.handle)
|
||||||
}
|
}
|
||||||
@@ -185,6 +150,10 @@ func (provider *Provider) IsEnabledForLevel(level Level) bool {
|
|||||||
// infrastructure, it can be useful to check if an event will actually be
|
// infrastructure, it can be useful to check if an event will actually be
|
||||||
// consumed before doing expensive work to build the event data.
|
// consumed before doing expensive work to build the event data.
|
||||||
func (provider *Provider) IsEnabledForLevelAndKeywords(level Level, keywords uint64) bool {
|
func (provider *Provider) IsEnabledForLevelAndKeywords(level Level, keywords uint64) bool {
|
||||||
|
if provider == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if !provider.enabled {
|
if !provider.enabled {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -206,6 +175,10 @@ func (provider *Provider) IsEnabledForLevelAndKeywords(level Level, keywords uin
|
|||||||
// constructed based on the EventOpt and FieldOpt values that are passed as
|
// constructed based on the EventOpt and FieldOpt values that are passed as
|
||||||
// opts.
|
// opts.
|
||||||
func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpts []FieldOpt) error {
|
func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpts []FieldOpt) error {
|
||||||
|
if provider == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
options := eventOptions{descriptor: newEventDescriptor()}
|
options := eventOptions{descriptor: newEventDescriptor()}
|
||||||
em := &eventMetadata{}
|
em := &eventMetadata{}
|
||||||
ed := &eventData{}
|
ed := &eventData{}
|
||||||
|
|||||||
Reference in New Issue
Block a user