【问题标题】:visual studio 2013 truncates returned pointer value in x64Visual Studio 2013 截断 x64 中返回的指针值
【发布时间】:2018-09-02 10:57:52
【问题描述】:

我尝试为 x64 编译 wingraphviz(这是一个旧的、无人维护的项目),但遇到了一个非常奇怪的问题:

getDefaultFont() 的调用如下所示:

const char* def = getDefaultFont();
Deffontname = late_nnstring(g->proto->n,N_fontname,def);

(原代码在函数调用中做了调用,但我把它提取出来以便理解)

getDefaultFont 函数非常简单,根据当前字符集返回一个字符串:

const char * getDefaultFont() {
    switch(DOT_CODEPAGE) {

            case CP_KOREAN:
            return CP_949_DEFAULTFONT;
            break;
[...]

            default:
            return DEFAULT_FONTNAME;
            break;
    }
}

在头文件中定义DEFAULT_FONTNAME 和其他人:

#define     DEFAULT_FONTNAME    "Times New Roman"

我把return改成{ const char* r = DEFAULT_FONTNAME; return r; }调试的时候看值:r在return指令是正确的。

但是当调试器返回调用函数时,def 指向无效内存。

我在汇编模式下运行调试器,看到了:

    const char* def = getDefaultFont();
000007FEDA1244FE  call        getDefaultFont (07FEDA1291A0h)  
000007FEDA124503  cdqe  
000007FEDA124505  mov         qword ptr [def],rax  

call 指令之后,RAX 包含正确的值,一个指向 .data 的指针:RAX = 000007FEDA0C9A20 但下一条指令,cqde“将 dword (eax) 转换为 qword (rax)。”销毁高 4 个字节,现在 RAX = FFFFFFFFDA0C9A20。然后第三个将截断的值存储在堆栈中。

之后,late_nnstring() 尝试取消引用损坏的指针并崩溃...

你知道为什么 VS 会插入这个cqde 指令吗? 所有这些函数都在同一个项目下的.c文件中。

我已经实现了一个解决方法,使用 strdup() 返回低内存地址,但这并不安全(也许堆可以在 4G 之后使用内存?)(还有一些我在测试时没有发现的其他情况使用库时会崩溃)

我在这里发布了文件:https://gitlab.com/data-public/wingraphviz

尤其是:

【问题讨论】:

  • gitlab项目配置错误,现已公开

标签: c visual-studio assembly compilation 64-bit


【解决方案1】:

您的链接需要一些我没有的帐户。

您可能没有包含声明该函数的标头,或者弄乱了标头顺序。 Here’s more info 为什么 C 编译器会插入 cdqe

附:为什么你应该阅读和修复编译器警告的好例子。

更新:如果你有循环依赖问题并且不能只包含 utils.h,一个快速的解决方法是在调用该函数之前在 emit.c 中声明 const char * getDefaultFont();

【讨论】:

  • 你是对的。谢谢。错过了“此遗留代码中有太多警告”输出中的警告...:/
猜你喜欢
  • 1970-01-01
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
相关资源
最近更新 更多