在任何全局对象之前初始化
Initialize before any global objects
我正在写一个c++内存分析器。
众所周知,一个可执行程序可能包含许多全局对象,和它的DLL模块可以包含全局对象好。这些全局对象将用CRT初始化初始化——在入口点之后,在WinMain之前;dll,入口点是_DllMainCRTStartup,在进入DllMain之前,DLL的所有全局对象都被初始化。
全局对象可以分配内存。一个内存分析器必须在任何全局对象初始化之前初始化。后在做了大量的研究之后,我发现这不是一件容易的工作。
一个想法是使用CREATE_SUSPENDED标志的CreateProcess - try为了获得第一次机会。之后,使用CreateRemoteThread来调用LoadLibrary在目标进程中加载注入DLL,以及初始化DLL。但它不起作用,因为它会加载首先是可执行程序的所有隐式链接dll。也许CreateRemoteThread触发了这个行为?
那么,我们如何获得第一个机会呢?
可能有一种方法可以使用非常特定于平台的方法来做到这一点,但是解决这个问题的一种方法是将延迟初始化与dylib加载结合起来。
例如,假设您的内存分配器函数像这样导出:
API void* exported_alloc();
API void exported_free(void* mem);
…在一个名为mem.dll
的dylib中。
在这种情况下,为了确保所有其他dylib在加载时都可以访问它,我们可以创建一个中央静态链接的库(例如:sdk.lib),所有dylib都可以链接到这个库,并使用如下标题:
#ifndef MEMORY_H
#define MEMORY_H
// Memory.h
void* my_alloc();
void my_free(void* mem);
#endif
…我们可以这样实现:
static void* (exported_alloc)() = 0;
static void (exported_free)(void* mem) = 0;
static void initialize()
{
if (!exported_alloc)
{
// Load 'mem.dll' (ex: 'LoadLibrary') and look up
// symbols for `exported_alloc` and `exported_free`
// (ex: GetProcAddress).
}
}
void* my_alloc()
{
initialize();
return exported_alloc();
}
void my_free(void* mem)
{
initialize();
exported_free(mem);
}
. .然后在完成DLL后的适当时间调用FreeLibrary
。这会产生一些运行时开销(类似于访问单例的开销),但这是一个跨平台的解决方案(如果您有在运行时加载/卸载dylibs/shared libs的跨平台方法)。
使用这个解决方案,所有在全局范围内分配内存的dll将在以惰性初始化的方式执行任何内存分配之前加载mem.dll
,确保它们都可以在适当的时间访问您的内存函数。
- C++使用整数的压缩数组初始化对象
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 在 c++ 中初始化对象
- C++ 手动分配和初始化对象
- 使用运算符"="在C++中用值初始化对象
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- 如何初始化对象数组?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 是否可以在编译时初始化对象的 C 样式函数指针,以便它调用对象的成员函数?
- 如何在线程中初始化对象,然后在其他地方使用它?
- 在没有默认构造函数时使用垃圾数据初始化对象
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 在 c++ 中复制对未初始化对象的引用
- 在成员变量在另一个文件中发生更改后,调用与初始化对象分开的函数
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 当您通过分配初始化C 对象时会发生什么
- 获取未初始化对象成员的地址是否定义良好?