0

I'm debugging this code :

len = NGX_SYS_NERR * sizeof(ngx_str_t);

ngx_sys_errlist = malloc(len);
if (ngx_sys_errlist == NULL) {
    goto failed;
}

for (err = 0; err < NGX_SYS_NERR; err++) {

But in gdb if (ngx_sys_errlist == NULL) { is skipped directly:

(gdb) 
59      ngx_sys_errlist = malloc(len);
(gdb) n
64      for (err = 0; err < NGX_SYS_NERR; err++) {

I also have experienced this before,but never knows the reason,anyone knows?

Is it a bug?

UPDATE

0x000000000041be9d <ngx_strerror_init+0>:   mov    %rbx,-0x30(%rsp)
0x000000000041bea2 <ngx_strerror_init+5>:   mov    %rbp,-0x28(%rsp)
0x000000000041bea7 <ngx_strerror_init+10>:  mov    %r12,-0x20(%rsp)
0x000000000041beac <ngx_strerror_init+15>:  mov    %r13,-0x18(%rsp)
0x000000000041beb1 <ngx_strerror_init+20>:  mov    %r14,-0x10(%rsp)
0x000000000041beb6 <ngx_strerror_init+25>:  mov    %r15,-0x8(%rsp)
0x000000000041bebb <ngx_strerror_init+30>:  sub    $0x38,%rsp
0x000000000041bebf <ngx_strerror_init+34>:  mov    $0x840,%edi
0x000000000041bec4 <ngx_strerror_init+39>:  callq  0x402388 <malloc@plt>
0x000000000041bec9 <ngx_strerror_init+44>:  mov    %rax,0x26e718(%rip)        # 0x68a5e8 <ngx_sys_errlist>
0x000000000041bed0 <ngx_strerror_init+51>:  mov    $0x840,%r12d
0x000000000041bed6 <ngx_strerror_init+57>:  test   %rax,%rax
0x000000000041bed9 <ngx_strerror_init+60>:  je     0x41bf56 <ngx_strerror_init+185>
0x000000000041bedb <ngx_strerror_init+62>:  mov    $0x0,%r13d
0x000000000041bee1 <ngx_strerror_init+68>:  mov    $0x0,%r14d
0x000000000041bee7 <ngx_strerror_init+74>:  mov    $0x0,%r15d
0x000000000041beed <ngx_strerror_init+80>:  mov    %r13d,%edi
0x000000000041bef0 <ngx_strerror_init+83>:  callq  0x402578 <strerror@plt>

UPDATE

Nobody else ever met the same thing in using gdb? It happens to me frequently when debugging.

compile-fan
  • 16,885
  • 22
  • 59
  • 73
  • 1
    Don't use goto. for everyone's sake. – Daniel Jun 04 '11 at 03:21
  • 1
    You have a debugger, look at the generated assembly code. – Greg Hewgill Jun 04 '11 at 03:23
  • 1
    @Dani: Sorry but that looks like a perfectly valid use of `goto`. I'd guess that the `failed` label is at the bottom of the function (after the normal `return`) and precedes some cleanup code. If I'm right, then this is a perfect job for `goto` and anything else would probably a bunch of pointless busy work. – mu is too short Jun 04 '11 at 03:32
  • @mu is too short: there is no valid use for goto. It's just a remanent from whatever language c++ is built upon that didn't have function calls. – Daniel Jun 04 '11 at 03:38
  • @Greg Hewgill ,it's in the assembly,but I don't know why gdb doesn't ever stop there. – compile-fan Jun 04 '11 at 03:40
  • @Dani: Nonsense. Error handling is a perfectly valid use of `goto` in **C** (which this code clearly is). Dogma has little use in the real world. But, this isn't the best place for religious war. – mu is too short Jun 04 '11 at 03:42
  • @Dani: your alternatives are to repeat your error recovery anywhere or use something that is even more dubious such as wrapping the whole thing in a dummy loop. Functions have nothing to do with it, you can't force a non-local return so you still have to break out of the current scope somehow. This kind of error handling code is indeed one of the few cases when `goto` is sensible. – geekosaur Jun 04 '11 at 03:48
  • Let's just ban jump instructions, all of them. That way nobody would ever use `goto`. Right? – Nikolai Fetissov Jun 04 '11 at 04:08
  • @geekosaur: My way is to wrap everything in try/catch and throw exception when one happens or even better in The function with the error. That's what it's meant for, right? – Daniel Jun 04 '11 at 05:03
  • 1
    @Dani: that works when you can use `try`/`catch`, which excludes C (the C equivalent is `goto`, or for nested functions `setjmp()`/`longjmp()` which make `goto` look clean...) and some embedded or restricted contexts (for example, getting it right in an interrupt lower half would be difficult to impossible). As this is C code (`malloc()` instead of `new[]`), you're left with `goto` or even uglier and logically confusing mechanisms like dummy loops. – geekosaur Jun 04 '11 at 05:07

2 Answers2

1

Most likely the two statements were optimized into a single set-and-test expression, which then can't be decomposed into the original two lines. The generated pseudocode is likely to be something like

call _malloc
jz _failed
mov acc, _ngx_sys_errlist

where the test now happens before the assignment; do you let the source level trace go backwards to reflect this?

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • @geekosaur,see my update,I think it's still there:`je 0x41bf56 ` – compile-fan Jun 04 '11 at 03:34
  • @compile-fan: IIRC the usual way to test for zero on x86 is something like `or`ing `%eax` with itself and then doing `je` or `jne` as appropriate, so you may well be seeing exactly what I suggested. – geekosaur Jun 04 '11 at 03:39
  • As we can see in the assembly,it's not optimized out. – compile-fan Jun 04 '11 at 03:42
  • @geekosaur,I just googled `test %rax %rax` and seems it's also a valid use to check if `%rax` is `0`. And you can check this answer: http://stackoverflow.com/questions/147173/x86-assembly-testl-eax-against-eax – compile-fan Jun 04 '11 at 03:46
  • Aside from the fact that `%rax` is x86-64, not x86, `test` is morally the same as the `or`. I think which one is faster depends on processor generation (it may well always be faster with anything produced in the past several years; I haven't needed to care this century :) . – geekosaur Jun 04 '11 at 03:51
  • BTW, pedantically, `test` is `sub`, not `or`; the result is thrown away but the flags are kept, so for this use it's indeed the same thing. – geekosaur Jun 04 '11 at 03:58
  • @geekosaur,don't you ever met the same thing in using gdb? It happens to me frequently when debugging. – compile-fan Jun 04 '11 at 04:00
  • Most of my compilation these days involves Haskell (otherwise I'm in Perl/Python/Ruby/etc.); `gdb` is less than useful. – geekosaur Jun 04 '11 at 04:01
0

please check,
a) if you are debugging release build (if there exists one)
b) if your source file is modified

if you still have the issue, please provide the details (Complier with version, degugger version , platform and code ...)

Tatvamasi
  • 2,537
  • 19
  • 14