- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试从 Advapi32.dll 中访问 EnumerateTraceGuids 函数。我还处于非常早期的阶段,仍在尝试破译我必须做什么。我有以下代码不断给我错误:87,意思是 ERROR_INVALID_PARAMETER。
虽然它只是写入而不是读取,但我已将此文件用作起点: https://github.com/moby/moby/blob/master/daemon/logger/etwlogs/etwlogs_windows.go
我要调用的函数的官方文档在这里: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363713(v=vs.85).aspx
它需要 GuidPropertiesArray [in, out] 指向 TRACE_GUID_PROPERTIES 结构的指针数组。此结构如下 ( https://msdn.microsoft.com/en-us/library/windows/desktop/aa364143(v=vs.85).aspx )
typedef struct _TRACE_GUID_PROPERTIES {
GUID Guid;
ULONG GuidType;
ULONG LoggerId;
ULONG EnableLevel;
ULONG EnableFlags;
BOOLEAN IsEnable;
} TRACE_GUID_PROPERTIES, *PTRACE_GUID_PROPERTIES;
我有以下代码来尝试执行此操作:
package main
import (
"errors"
"fmt"
"syscall"
"unsafe"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
)
const (
win32CallSuccess = 0
MaxProv = 50
nbProviders = 50
)
var (
modAdvapi32 = windows.NewLazySystemDLL("Advapi32.dll")
procEnumerateTraceGuids = modAdvapi32.NewProc("EnumerateTraceGuids")
)
type ulong int32
type TRACE_GUID_PROPERTIES struct {
Guid syscall.GUID
GuidType ulong
LoggerId ulong
EnableLevel ulong
EnableFlags ulong
IsEnable bool
}
func callEnumerateTraceGuids() error {
GuidPropertiesArray:= make([]TRACE_GUID_PROPERTIES, 1)
ptr := &GuidPropertiesArray[0]
ret, _, _ := procEnumerateTraceGuids.Call(uintptr(unsafe.Pointer(&ptr)), MaxProv, nbProviders)
if ret != win32CallSuccess {
errorMessage := fmt.Sprintf("Failed to register ETW provider. Error: %d", ret)
logrus.Error(errorMessage)
return errors.New(errorMessage)
}
return nil
}
func main() {
callEnumerateTraceGuids()
}
此时我不确定我必须做什么。我尝试了很多初始化数组的变体,但都没有成功。希望有人能指出我正确的方向。谢谢!
编辑:根据评论更改了代码,但仍然出现相同的错误。
PS:这是我第一次在 stackoverflow 上发帖,我已经被告知我在发布问题后不到 12 小时就懒惰了(耶!)所以不确定我问的是否正确...我我不太熟悉 go 并且之前从未从 go 调用过 Windows DLL,因为我一直在点击那个 ERROR_INVALID_PARAMETER 我想伸出手去尝试通过这第一堵墙以便能够同时掌握一些概念。希望这有助于理解我的请求(即,我平安而来)。
最佳答案
好吧,我有一点空闲时间并且可以使用 Windows XP 盒子,所以我决定重温我的 Windows 编程技能并编写了一个可行的解决方案:
package main
import (
"golang.org/x/sys/windows"
"log"
"syscall"
"unsafe"
)
var (
modAdvapi32 = windows.NewLazySystemDLL("advapi32")
procEnumerateTraceGuids = modAdvapi32.NewProc("EnumerateTraceGuids")
)
type traceGuidProperties struct {
guid syscall.GUID
guidType uint32
loggerId uint32
enableLevel uint32
enableFlags uint32
isEnable uint32
}
func enumerateTraceGuids(ptr **traceGuidProperties, count uint32, out *uint32) error {
rc, _, _ := procEnumerateTraceGuids.Call(uintptr(unsafe.Pointer(ptr)),
uintptr(count), uintptr(unsafe.Pointer(out)))
if rc != 0 {
return syscall.Errno(rc)
}
return nil
}
func enumTraceGuids() ([]*traceGuidProperties, error) {
var errMoreData = syscall.Errno(234)
var (
dummyProps traceGuidProperties
dummyPtr = &dummyProps
count uint32
)
err := enumerateTraceGuids(&dummyPtr, 0, &count)
if err != errMoreData {
return nil, err
}
items := make([]*traceGuidProperties, count)
for i := range items {
items[i] = new(traceGuidProperties)
}
for {
err = enumerateTraceGuids(&items[0], count, &count)
if err == nil {
break
}
if err != errMoreData {
return nil, err
}
for i := 0; i < int(count)-len(items); i++ {
items = append(items, new(traceGuidProperties))
}
}
return items[:count], nil
}
func main() {
log.SetFlags(0)
data, err := enumTraceGuids()
if err != nil {
log.Fatal(err)
}
log.Printf("len(data)=%d\n", len(data))
for i := range data {
log.Println(*(data[i]))
}
}
要点:
我告诉你的时候我错了«你……应该分配一个结构数组(而不是指针)»——事实上EnumerateTraceGuids
确实需要一个指针数组。
如提示here ,EnumerateTraceGuids
的工作方式有两个微妙之处:
PropertyArrayCount
调用参数设置为 0,在这种情况下,它应该返回 ERROR_MORE_DATA
同时将 GuidCount
设置为输入的元素数(下一次)调用成功完成所需的数组。IOW,这样我们就知道系统当前有多少跟踪 GUID“知道”。事实证明,该函数需要一个指向的指针数组TRACE_GUID_PROPERTIES
block 由您分配。
换句话说,如果它说你知道大约 10 个跟踪 GUID,您必须分配 10 个 TRACE_GUID_PROPERTIES
类型的值,然后创建一个包含 10 个指向这些值的指针的数组并传递一个指针将该数组的第一个元素传递给函数。
请注意,发生的变化之间存在固有的竞争在系统中(由于各种原因添加或删除的痕迹)以及对 EnumerateTraceGuids
的调用。
这意味着如果第一次调用这个函数告诉你它“知道”大约 10 个跟踪 GUID,在下一次调用时可能会出现已经有 20 个跟踪 GUID,或 5 个 GUID(或任何其他数量的 FWIW)。
因此我们通过以下方式考虑这两种可能性:
首先,我们使用指向单个(但有效)的指针进行调用TRACE_GUID_PROPERTIES
值,静态分配(因此函数“看到”看起来像单个元素的数组),在告诉函数输入“数组”有零个元素时。
我们预计该函数会失败并返回 ERROR_MORE_DATA
并将它“知道”的跟踪 GUID 的实际数量放入变量中我们已经为它提供了一个指针。
我们分配那么多 TRACE_GUID_PROPERTIES
内存块第一次调用时指示的函数。为此,我们使用 new()
内置函数就像标准 C 库中的 malloc()
——它为指定类型的值并返回指向分配的指针内存块。
我们创建一个指向这些已分配内存块的指针数组并再次调用 EnumerateTraceGuids
。
如果成功,我们会处理返回较少的可能性比我们分配的元素更多,并重新 slice 我们的 slice 。
如果它因 ERROR_MORE_DATA
而失败,我们将扩展我们的 slice 无论需要多少元素(为它们分配内存TRACE_GUID_PROPERTIES
首先阻塞),然后尝试再次调用该函数。
“魔数(Magic Number)”234 是 ERROR_MORE_DATA
值的实际代码。
对于最初的困惑,我们深表歉意。
关于winapi - 使用 go 读取 ETW 提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50124486/
我目前正在使用 Microsoft 网络监视器来解析调试事件跟踪。它不是一个坏工具,但也不是很好。你知道一些更好的解决方案吗? 最佳答案 这些是用于探索自定义 ETW 跟踪的读者: SvcPerf -
我正在使用 Windows API 的事件跟踪,并且不时运行我的应用程序,但它在打开 ETW 跟踪 Controller session 后无法关闭它。 基本上我做::StartTrace([out]
问题:如何查看所有打开的 ETW session ,包括其根路径?我期望一些 PowerShell 命令,如 Get-EtwTraceSession ,但我没有看到任何内容。 背景 我使用 Event
性能计数器是 ETW 的一部分吗?如果不是,两者有什么区别? 最佳答案 性能计数器和 ETW 是不同的技术。性能计数器不通过 ETW 公开。 基本区别:性能计数器提供有关系统行为的高级度量(想想计时器
我正在使用新的 EventSource 类从我的应用程序写入 Windows 事件日志,到目前为止它很棒。但是,我观察到有两件事会导致可能相关的问题:传递给 Event 属性的格式字符串在写入事件日志
我打算使用 ETW,因为它: 强制构建日志记录 低延迟 在另一个进程上消费事件的能力 想法是使用语义日志应用程序 block 等外部进程使用 ETW 事件,并将这些事件转发到中央位置。 我的问题是。如
我有一个使用 native 插件的应用程序。对于这些插件,我有自己的二进制格式。每个插件都在运行时使用类似于将 DLL 映射到进程空间的方法加载。这意味着,每个插件都有自己的 ImageBase,.t
我们使用 AppFabric Monitoring 来检查执行时间并跟踪日志消息。这在一年后运行良好,但一些服务器突然停止监视我们的 WCF 服务。 我在 AppFabric 监控方面有一些经验,并且
我为 CLR 提供程序记录 ETW 事件: xperf -start clr -on e13c0d23-ccbc-4e12-931b-d9cc2eee27e4 -f clr.etl ... xperf
是否有使用 ETW 记录异常的标准方法? 据我所知,这样做的唯一方法是记录消息和可能的内部异常消息,因为异常类型没有强类型参数。 最佳答案 启用时,所有 CLR 异常(第一次机会,以及可能最终导致应用
我正在尝试让我的 Azure 辅助角色的日志出现在 Application Insights 中。当我运行 Get-AzureServiceDiagnosticsExtension 时,我得到以下信息
如何确定 ETW session 是否正在丢弃事件? 如果正在丢弃事件,我如何配置跟踪 session 以便事件不被丢弃? 我编写了一个自定义 ETW 提供程序来帮助进行一些调试工作。我目前正在使用
任务并行库使用 Event Tracing for Windows (ETW)用于记录。显然,在 Windows Phone 或 Windows Store .NET Runtime 下,TPL 或
我想实现一个 ETW C 中的消费者用于来自 Microsoft-Windows-TCPIP 提供程序的事件。但是,我找不到此提供程序生成的事件类型。 我已经做了一些类似的工作来使用来自 Micros
这个问题在这里已经有了答案: How do I log events in Windows IoT? (1 个回答) 关闭 5 年前。 我正在为 Windows 10 IoT 开发基于 UWP 的应
一些人告诉我,ETW 提供了一种机制来捕获用户模式进程进行的系统调用。我已经列举了可用的提供者,并且只提出了两个可能提供此信息的可能性。第一个是 Microsoft-Windows-Kernel-Au
在不使用 list 的情况下卸载/删除以前安装的事件源的最佳方法是什么? 例如。如果我有类似的东西: [EventSource(Name = "Corporation-Module-X")]
我正在尝试使用新的 EventSource(来自 nuget 的 Microsoft.Diagnostics.Tracing.EventSource)及其对 ETW channel 的新支持,以便写入
我们刚刚开始使用 Service Fabric,到目前为止唯一的痛点是使用 WAD 进行 ETW,它似乎总是因丢失数据(消息、事件消息)而注销。 到目前为止,我们的经验是它在 Visual Studi
我们刚刚开始使用 Service Fabric,到目前为止唯一的痛点是使用 WAD 进行 ETW,它似乎总是因丢失数据(消息、事件消息)而注销。 到目前为止,我们的经验是它在 Visual Studi
我是一名优秀的程序员,十分优秀!