为什么 GCC 会生成导致崩溃的 "mov 0x8,%edx" 指令?
Why does GCC generate a "mov 0x8,%edx" instruction that causes a crash?
我有一个声明如下的函数:
void
tesysLog(W16 uid, char *file, int line, int level,
W16 state, W16 event, int error, char *format, ...)
上面还有一个func会调用tesysLog,例如:
tesysLog(253, __FILE__, __LINE__, 3, 0, 0, result,
"error(code = %d) is %d instead of %d\n",
avp->header.code, decoded, size);
上述调用的相关汇编代码如下:
0x00000000009027e5 <+117>: xor %r9d,%r9d <---- clear r9d, means argv6 event = 0
0x00000000009027e8 <+120>: mov 0x8,%edx <---- absolute address, but 0x8 is in reserved segment, crash here
0x00000000009027ef <+127>: xor %r8d,%r8d
0x00000000009027f2 <+130>: mov [=13=]x3,%ecx
0x00000000009027f7 <+135>: mov [=13=]x995600,%esi
0x00000000009027fc <+140>: mov [=13=]xfd,%edi
0x0000000000902801 <+145>: mov %ebp,0x20(%rsp)
0x0000000000902805 <+149>: mov %eax,0x18(%rsp)
0x0000000000902809 <+153>: xor %eax,%eax
0x000000000090280b <+155>: movq [=13=]x995770,0x8(%rsp)
0x0000000000902814 <+164>: mov %edx,0x10(%rsp)
0x0000000000902818 <+168>: mov [=13=]x8a,%edx
0x000000000090281d <+173>: movl [=13=]xc8e4,(%rsp)
0x0000000000902824 <+180>: callq 0x9136e0 <tesysLog>
我在汇编代码的第二行 mov 0x8,%edx 处收到信号 11,分段错误。看起来这一行是为调用 tesysLog 的 arg3(int 行)做准备。但是这里因为使用了"absolute address",而0x8在进程的地址space的保留段中,依次发出Segmentation fault.
这些代码是 运行 在 SLES 上,由 gcc 编译的。
我想知道为什么要使用 "absolute address"。是 gcc 错误,还是有影响此的编译选项?
void
tesysLog(W16 uid, char *file, int line, int level,
W16 state, W16 event, int error, char *format, ...)
tesysLog(253, _ _FILE__, _ _LINE__, 3,
0, 0, result, "error(code = %d) is %d instead of %d\n",
header.code, decoded, size);
参数将在寄存器中:
- rdi : W16 uid
- rsi : 字符 *文件
- rcx : 整行
- rdx : 整数级别
- r8 : W16 状态
- r9 : W16 事件
- 堆栈:字符 *格式,...)
你是对的,edx 是第三个参数,但是:
你必须在调用之前检查 edx 是什么,它不是 0x08 ...它是 $0x8a(第 138 行),所以“_ _LINE__”不是引起麻烦的那个,它是值存储在 (%rsp+10) 中,即 "header.code"
编辑:废话。 mode = 138, 不在线!!
0x00000000009027e8 <+120>: mov 0x8,%edx ; here EDX is just a tmp variable
...
0x0000000000902814 <+164>: mov %edx,0x10(%rsp) ; for THIS value!
0x0000000000902818 <+168>: mov [=11=]x8a,%edx ; <-- THIS is edx on call
如果您公开代码,我们就能找到问题所在...我 99.9% 确定您使用的 "header.code" 是错误的 ;-)
我有一个声明如下的函数:
void
tesysLog(W16 uid, char *file, int line, int level,
W16 state, W16 event, int error, char *format, ...)
上面还有一个func会调用tesysLog,例如:
tesysLog(253, __FILE__, __LINE__, 3, 0, 0, result,
"error(code = %d) is %d instead of %d\n",
avp->header.code, decoded, size);
上述调用的相关汇编代码如下:
0x00000000009027e5 <+117>: xor %r9d,%r9d <---- clear r9d, means argv6 event = 0
0x00000000009027e8 <+120>: mov 0x8,%edx <---- absolute address, but 0x8 is in reserved segment, crash here
0x00000000009027ef <+127>: xor %r8d,%r8d
0x00000000009027f2 <+130>: mov [=13=]x3,%ecx
0x00000000009027f7 <+135>: mov [=13=]x995600,%esi
0x00000000009027fc <+140>: mov [=13=]xfd,%edi
0x0000000000902801 <+145>: mov %ebp,0x20(%rsp)
0x0000000000902805 <+149>: mov %eax,0x18(%rsp)
0x0000000000902809 <+153>: xor %eax,%eax
0x000000000090280b <+155>: movq [=13=]x995770,0x8(%rsp)
0x0000000000902814 <+164>: mov %edx,0x10(%rsp)
0x0000000000902818 <+168>: mov [=13=]x8a,%edx
0x000000000090281d <+173>: movl [=13=]xc8e4,(%rsp)
0x0000000000902824 <+180>: callq 0x9136e0 <tesysLog>
我在汇编代码的第二行 mov 0x8,%edx 处收到信号 11,分段错误。看起来这一行是为调用 tesysLog 的 arg3(int 行)做准备。但是这里因为使用了"absolute address",而0x8在进程的地址space的保留段中,依次发出Segmentation fault.
这些代码是 运行 在 SLES 上,由 gcc 编译的。
我想知道为什么要使用 "absolute address"。是 gcc 错误,还是有影响此的编译选项?
void
tesysLog(W16 uid, char *file, int line, int level,
W16 state, W16 event, int error, char *format, ...)
tesysLog(253, _ _FILE__, _ _LINE__, 3,
0, 0, result, "error(code = %d) is %d instead of %d\n",
header.code, decoded, size);
参数将在寄存器中:
- rdi : W16 uid
- rsi : 字符 *文件
- rcx : 整行
- rdx : 整数级别
- r8 : W16 状态
- r9 : W16 事件
- 堆栈:字符 *格式,...)
你是对的,edx 是第三个参数,但是:
你必须在调用之前检查 edx 是什么,它不是 0x08 ...它是 $0x8a(第 138 行),所以“_ _LINE__”不是引起麻烦的那个,它是值存储在 (%rsp+10) 中,即 "header.code"
编辑:废话。 mode = 138, 不在线!!
0x00000000009027e8 <+120>: mov 0x8,%edx ; here EDX is just a tmp variable
...
0x0000000000902814 <+164>: mov %edx,0x10(%rsp) ; for THIS value!
0x0000000000902818 <+168>: mov [=11=]x8a,%edx ; <-- THIS is edx on call
如果您公开代码,我们就能找到问题所在...我 99.9% 确定您使用的 "header.code" 是错误的 ;-)