Sin(int) is broken in Xcode debugger (lldb)

前端 未结 1 545
遇见更好的自我
遇见更好的自我 2021-01-20 00:20

I have an universal iOS app targeting iOS SDK 6.1, and the compiler is set to Apple LLVM compiler 4.2. When I place a breakpoint in my code and run the foll

1条回答
  •  梦毁少年i
    2021-01-20 00:43

    You're walking into the wonderful world of default argument promotions in C. Remember, lldb doesn't know what the argument types or return type of sin() is. The correct prototype is double sin (double). When you write

    (lldb) p (float) sin(70)
    

    there are two problems with this. First, you're providing an integer argument and the C default promotion rules are going to pass this as an int, a 4-byte value on the architectures in question. double, besides being 8-bytes, is an entirely different encoding. So sin is getting garbage input. Second, sin() returns a double, or 8-byte on these architectures, value but you're telling lldb to grab 4 bytes of it and do something meaningful. If you'd called p (float)sin((double)70) (so only the return type was incorrect) lldb would print a nonsensical value like 9.40965e+21 instead of 0.773891.

    When you wrote

    (lldb) p (double) sin(70.0)
    

    you fixed these mistakes. The default C promotion for a floating point type is to pass it as a double. If you were calling sinf(), you'd have problems because the function expected only a float.

    If you want to provide lldb with a proper prototype for sin() and not worry about these issues, it is easy. Add this to your ~/.lldbinit file,

    settings set target.expr-prefix ~/lldb/prefix.h
    

    (I have a ~/lldb directory where I store useful python files and things like this) and ~/lldb/prefix.h will read

    extern "C" {
    int strcmp (const char *, const char *);
    void printf (const char *, ...);
    double sin(double);
    }
    

    (you can see that I also have prototypes for strcmp() and printf() in my prefix file so I don't need to cast these.) You don't want to put too many things in here - this file is prepended to every expression you evaluate in lldb and it will slow your expression evaluations down if you put all the prototypes in /usr/include in there.

    With that prototype added to my target.expr-prefix setting:

    (lldb) p sin(70)
    (double) $0 = 0.773890681557889
    

    0 讨论(0)
提交回复
热议问题