在任何全局对象之前初始化 [英] Initialize before any global objects

查看:102
本文介绍了在任何全局对象之前初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



众所周知,可执行程序可能包含许多全局对象,
和它的DLL模块可能包含全局变量对象作为
好​​。这些全局对象将用CRT
初始化 - 在入口点之后和WinMain之前;对于DLL,
的入口点是_DllMainCRTStartup,在你进入DllMain之前,
将初始化DLL的所有全局对象。



对象可以分配内存。所以内存分析器
必须在任何全局对象初始化之前初始化。



一个想法是使用CreateProcess与CREATE_SUSPENDED标志 - try
获得第一次机会。之后,使用CreateRemoteThread在目标进程中调用
LoadLibrary以加载注入DLL,并且
初始化该DLL。但它不工作,因为这将加载
所有隐式链接DLL的可能是CreateRemoteThread触发了这个行为?



那么,我们如何获得第一次机会呢?

解决方案

可能有一种方法,否则使用非常特定平台的方式,但解决问题的一种方法是结合延迟初始化与dylib加载。



例如,假设你的内存分配器函数是这样导出的:

  API void * exported_alloc(); 
API void exported_free(void * mem);

...在dylib中调用 mem.dll



在这种情况下,为了确保所有其他dylib可以在加载时访问它,我们可以创建一个中央

 链接

#ifndef MEMORY_H
#define MEMORY_H

// Memory.h
void * my_alloc();
void my_free(void * mem);

#endif

...我们可以这样实现: / p>

  static void *(exported_alloc)()= 0; 
static void(exported_free)(void * mem)= 0;

static void initialize()
{
if(!exported_alloc)
{
//加载'mem.dll'(例如:'LoadLibrary' ),并为`exported_alloc`和`exported_free`
//(例如:GetProcAddress)查找
//符号。
}
}

void * my_alloc()
{
initialize();
return exported_alloc();
}

void my_free(void * mem)
{
initialize();
exported_free(mem);
}

..然后调用 FreeLibrary 在你完成DLL的适当时间。这会带来一点运行时开销(类似于访问单例的开销),但是是一个跨平台的解决方案(假设你有一个跨平台的方法在运行时加载/卸载dylib /共享库)。



使用此解决方案,所有在全局范围内分配内存的DLL将在执行之前加载 mem.dll 任何内存分配在延迟初始化的方式,确保他们都可以访问您的记忆功能在适当的时间。


I am writing a C++ memory profiler.

As everyone knows, an executable program may contain many global objects, and its DLL modules may contain global objects as well. These global objects will be initialized with CRT initialization - after the entry point and before WinMain; for DLLs, the entry point is _DllMainCRTStartup, before you get into DllMain, all the global objects of the DLL are initialized.

A global object may allocate memory. so a memory profiler must be initialized before any global object initialization. After doing a lot of researching, I found that this is not an easy job.

One idea is using CreateProcess with CREATE_SUSPENDED flag - try to get a first chance. After that, use CreateRemoteThread to call LoadLibrary in the target process to load an injection DLL, and initialize that DLL. But it doesn't work because this will load all the implicit-linking DLLs of the executable program first. Maybe CreateRemoteThread triggers this behavior?

So, how do we get the first chance?

解决方案

There might be a way to do this otherwise using very platform-specific ways, but one way to solve the issue is to combine lazy initialization with dylib loading.

For example, say your memory allocator functions are exported like this:

API void* exported_alloc();
API void exported_free(void* mem);

... inside a dylib called mem.dll.

In this case, to ensure that all of your other dylibs can get to it when they are being loaded, we can create a central statically-linked library (ex: sdk.lib) that all of your dylibs link against with a header like so:

#ifndef MEMORY_H
#define MEMORY_H

// Memory.h
void* my_alloc();
void my_free(void* mem);

#endif

... which we can implement like so:

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);
}

.. Then call FreeLibrary at the appropriate time when you're finished with the DLL. This incurs a bit of run-time overhead (similar to the overhead of accessing a singleton), but is a cross-platform solution (provided that you have a cross-platform means of loading/unloading dylibs/shared libs at runtime).

With this solution, all of your DLLs allocating memory at a global scope would then load mem.dll prior to performing any memory allocations in a lazy-initialized kind of way, ensuring that they all have access to your memory functions at the appropriate time.

这篇关于在任何全局对象之前初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆