Jeff.Lu Jeff.Lu -4 years ago 68
C Question

why gcc generates "mov 0x8,%edx" casuing crash

I have a function which is declared like this:

tesysLog(W16 uid, char *file, int line, int level,
W16 state, W16 event, int error, char *format, ...)

There is another func which will call tesysLog above, for example,:

tesysLog(253, __FILE__, __LINE__, 3, 0, 0, result,
"error(code = %d) is %d instead of %d\n",
avp->header.code, decoded, size);

The related assemly codes for the calling above are like:

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 $0x3,%ecx
0x00000000009027f7 <+135>: mov $0x995600,%esi
0x00000000009027fc <+140>: mov $0xfd,%edi
0x0000000000902801 <+145>: mov %ebp,0x20(%rsp)
0x0000000000902805 <+149>: mov %eax,0x18(%rsp)
0x0000000000902809 <+153>: xor %eax,%eax
0x000000000090280b <+155>: movq $0x995770,0x8(%rsp)
0x0000000000902814 <+164>: mov %edx,0x10(%rsp)
0x0000000000902818 <+168>: mov $0x8a,%edx
0x000000000090281d <+173>: movl $0xc8e4,(%rsp)
0x0000000000902824 <+180>: callq 0x9136e0 <tesysLog>

I got a signal 11, Segmentation fault, at the second line of the assembly codes, mov 0x8,%edx. Looks like this line is to prepare for the arg3 (int line) for tesysLog calling. But here, because the "absolute address" is being used, and 0x8 is in the reserved segment of the address space of the process, Segmentation fault is signaled in turn.

These codes are running on SLES, and compiled by gcc.

I am wondering why "absolute address" is being used. Is it a gcc bug, or is there compiling options affecting this?

Answer Source
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);

parameters will be in registers:

  • rdi : W16 uid
  • rsi : char *file
  • rcx : int line
  • rdx : int level
  • r8 : W16 state
  • r9 : W16 event
  • stack: char *format, ...)

you're right, edx is the 3rd parameter, but:

you have to check what is edx right before the call, it's not 0x08 ... it's $0x8a (line 138), so "_ _LINE__" is not the one causing troubles, it's the value that's stored in (%rsp+10), which is "header.code"

Edit: nonsense. mode = 138, not line!!

0x00000000009027e8 <+120>: mov 0x8,%edx         ; here EDX is just a tmp variable
0x0000000000902814 <+164>: mov %edx,0x10(%rsp)  ; for THIS value!
0x0000000000902818 <+168>: mov $0x8a,%edx       ; <-- THIS is edx on call

if you'd reveal the code, we could find the problem ... i'm like 99,9% sure that you're using "header.code" wrong ;-)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download