【发布时间】:2018-08-07 20:54:50
【问题描述】:
我有一个生成的 c 源代码,看起来像这样:
void LCERCA_OGGETTO_AUTO();
void LCERCA_OGGETTO_AUTO()
{
MyApi();
}
然后我在 /Oy- 关闭帧指针优化的情况下编译代码。所有标志都是:
/c /Os /Oi /Gs /O2 /MT /Gy /Gd /Oy-
于是我开始寻找“标准”函数序言:
push ebp
mov ebp, esp
但什么都没有!
我需要这个序言在运行时重建堆栈,检查调用MyApi 的代码是否在 LCERCA_OGGETTO_AUTO 或其他函数中。
我错过了一些编译器标志?
我编辑了问题以澄清上下文。 我们使用了专有语言,并将我们的源代码翻译成 c。 为了在源代码级别创建调试器,我们使用调用检测生成的 c 代码,每行源代码一次:
static void LLEGGI_OGGETTO()
{
TraceDebug2("LEGGI_OGGETTO", 0, FALSE );
BCTracePrint5(220, "DFX_AREA,COD_AREA");
strncpy (PD->DFX_AREA_BC, FNTR(PS->COD_AREA_BC), 10);
BCTracePrint5(221, "DFX_PRODOT,COD_PRODOT");
strncpy (PD->DFX_PRODOT_BC, FNTR(PS->COD_PRODOT_BC), 10);
BCTracePrint5(222, "DFX_PROGET,COD_PROGET");
strncpy (PD->DFX_PROGET_BC, FNTR(PS->COD_PROGET_BC), 10);
BCTracePrint5(224, "OGG_TIPO");
if ((*(PS->OGG_TIPO_BC))==0)
{
BCTracePrint4(225);
LCERCA_OGGETTO_AUTO();
BCTracePrint4(226);
}
else {
BCTracePrint4(227);
LCERCA_OGGETTO_PRECISO();
BCTracePrint4(228);
}
BCTracePrint4(230);
TraceDebug2("LEGGI_OGGETTO", 1, FALSE );
}
代码“填充”了对调试引擎所在的 BCTracePrintXX 函数的调用。 BCTracePrintXX 函数使用 __fastcall 约定来最小化对性能的影响。 为了提供“step over / step in”,我们需要在 BCTracePrintXX 函数内部知道调用者是否在先前调用的同一堆栈帧中。这个想法是在 BCTracePrintXX 中收集 ebp 值。我们可以这样做,因为我们使用 __fastcall 约定,所以我们可以完全控制注册表的使用。 为此,我们必须禁用帧指针优化。
【问题讨论】:
-
很难看出“什么都没有”的样子。有点猜测,如果你坚持这个函数的堆栈帧,那么你必须禁用函数内联优化。像这样的单线总是消失。 /Ob0 是大锤,
__declspec(noinline)是适用于个别功能的微调仪器。 -
@Hans Passant 感谢您的回答,明天我会尝试您的建议。可能我必须更好地解释我想做什么以及我的方面。
标签: c++ visual-studio optimization