C/C++ 有什么办法吗?检测代码是否在静态初始化期间运行?
我正在编写一个以 DLL 形式提供的跟踪库。它基本上被我系统中的每个组件所消耗。一个棘手的要求是跟踪函数需要在进程生命周期的早期调用,甚至在 main() 运行之前。
该库的使用者包括可执行文件、静态链接的 DLL、延迟加载的 DLL 和动态加载的 DLL。所有的变化。
一些跟踪功能不能很好地与静态初始化配合使用,但其他功能则很好。理想情况下,我希望能够在初始化期间为消费者提供最少的安全功能,然后在初始化完成后为消费者提供完整的功能。
要求使用者自己进行明确的“我完成了 init”调用是行不通的,因为某些使用者本身就是 DLL,并且无法控制托管它们的可执行文件。同样的问题只是将链条向上移动了一层。
我希望有某种方法可以让我询问运行时是否正在静态初始化中运行或者该阶段是否已完成。这样的事可能吗?
更复杂的是,我需要在 5 个平台上运行。我不需要一次写入的解决方案,但我确实需要让它在所有平台上以某种方式工作。
I'm writing a tracing library that is available as a DLL. It is consumed by basically every component in my system. One tricky requirement is that the tracing functions need to be invoked very early in the process lifetime, even before main() runs.
Consumers of this library include executables, statically linked DLLs, delay-loaded DLLs and dynamically loaded DLLs. All the variations.
Some tracing features do no play well with static initialization but others are fine. Ideally, I'd like to be able to offer consumers minimal safe functionality during init time and then full functionality after init is complete.
Asking consumers to make an explicit "I'm done init" call themselves doesn't work because of the fact that certain consumers are DLLs themselves and have no control over the executable hosting them. The same problem just moves one level up the chain.
What I'm hoping is that there is some way for me to ask the runtime whether or I'm currently running in static initialization or whether that stage is complete. Is such a thing possible?
To complicate matters further, I need to run on 5 platforms. I don't need a write-once solution but I do need to get it working somehow on all platforms.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
全局变量?比如:
在你的 DLL 中,然后
在你的可执行文件中。
Global variable? Something like:
in your DLL and then
in your executable.
你这样写
然而,大多数时候问题不在于可执行文件(进程)的静态初始化阶段,而在于DLL的静态初始化阶段。
您必须知道,每个 DLL 都有其自己的静态 C++ 对象的静态初始化阶段。具体来说,您的跟踪 DLL 也有,并且可能使用您的 DLL 的任何其他 DLL 也有。
总结一下:您可能不关心可执行文件的静态初始化阶段是否已完成,但您确实关心 a) 您自己的 DLL 是否已完成初始化以及 b) 在调用 DLL 时是否已完成加载程序当前已持有锁。
至于 a) 如果您的 DLL 已完成初始化,这只是代码内部的问题,因为在初始化之前没有人可以调用您的 DLL。
至于 b),似乎没有(可移植的、有记录的)方法可以从代码中确定当前是否持有加载器锁。除了清楚地记录在持有加载程序锁时不得调用哪些函数之外,我不知道还有什么其他方法。
You write that
However, most of the time the problem lies not in the static initialization phase of the executable (the process), but in the static initialization phase of the/a DLL.
You must be aware that every DLL has it's own static initialization phase for it's static C++ object. Specifically your tracing DLL has too, and so has any other DLL that might use your DLL.
To sum up: Probably you do not care if the static initialization phase of the executable has finished but you do care if a) your own DLL has finished initializing and b) if while calling into your DLL the Loader Lock is currently held.
As to a) If your DLL is finished initializing is only a problem inside your code as noone can call into your DLL before it's initialized.
As to b) It does seem that there is no (portable, documented) way to determine from code if the loader lock is currently being held. I do not know any other way than to clearly document which functions must not be called while the Loader Lock is being held.
您可能必须重写(好吧,修改),然后链接到您重写的 crt0.o。显然,每个平台的情况都不同。
You may have to rewrite (well, modify) and then link with your rewritten crt0.o. That's obviously going to have to be different for each platform.