- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
问题/症状:
在函数返回的末尾,编译器添加了反汇编中看到的 sxtw 指令,导致返回地址只有 32 位而不是 64 位,从而导致内核崩溃:
Unable to handle kernel paging request at virtual address xxxx
构建环境:
平台:ARMV7LE
gcc, linux-4.4.60
架构:arm64
gdb : aarch64-5.3-glibc-2.22/usr/bin/aarch64-linux-gdb
详细信息:
这是简化的项目结构。它已在相应的 makefile 中得到正确处理。另请注意,file1.c 和 file2.c 是同一模块的一部分。
../src/file1.c/* 它定义并调用了 func1() /
../src/file2.c
../inc/files.h/ 头文件中没有声明 func1() */
问题原因:
从 file2.c 添加了对 func1() 的调用,而 files.h 或 file2.c 中没有 func1 声明。 (基本上在 files.h 中不小心漏掉了 func1。)
编译的代码没有错误,但出现了预期的警告 -- Implicit declaration of function func1
。
但是在运行时,从 file2 中的 func1 返回后,系统立即崩溃,因为它试图取消引用 func1 返回的地址。
进一步分析表明,在函数返回的末尾,编译器添加了反汇编中看到的 sxtw 指令,导致返回地址只有 32 位而不是 64 位,从而导致内核崩溃。
Unable to handle kernel paging request at virtual address xxxx
sxtw x19, w0/* 这是编译器添加的额外指令 /ldp x1, x0, [x19,#304]/ 系统在这里崩溃 */
注册:
[ 91.388130] pc : [<ffffff80016c9074>] lr : [<ffffff80016c906c>] pstate: 80000145
[ 91.462090] sp : ffffff80094333b0
[ 91.552708] x29: ffffff80094333d0 x28: ffffffc06995408a
[ 91.652701] x27: ffffffc06c400a00 x26: 0000000000000000
[ 91.716243] x25: 0000000000000000 x24: ffffffc069958000
[ 91.779784] x23: ffffffc076e00000 x22: ffffffc06c400a00
[ 91.843326] x21: 0000000000000031 x20: ffffffc073060000
[ 91.906867] x19: 0000000066bfc780 x18: ffffff8009436888
[ 91.970409] x17: 0000000000000000 x16: ffffff8008193074
[ 92.033952] x15: 00000000000a8c06 x14: 2c30323030387830
[ 92.097492] x13: 3d7367616c66202c x12: 3038653030303030
[ 92.161034] x11: 3038666666666666 x10: 78303d646e65202c
[ 92.224576] x9 : 3063303030303030 x8 : 3030303030303030
[ 92.288117] x7 : 0000000000000880 x6 : 0000000000000000
[ 92.351659] x5 : ffffffc07fd10ad8 x4 : 0000000000000001
[ 92.415202] x3 : 0000000000000007 x2 : cb88537fdc8ba63c
[ 92.478743] x1 : 0000000000000000 x0 : ffffffc066bfc780
在 files.h 中添加 func1 的声明后,未看到额外的指令和因此发生的崩溃。
有人可以解释为什么编译器在这种情况下添加了 sxtw 吗?
最佳答案
您应该至少收到两条警告,一条是关于缺少函数声明,另一条是关于从 int
到指针类型的隐式转换。
原因是隐式声明的函数的返回类型为int
。将此 int
值转换为 64 位指针会丢弃结果的 32 位。这是预期的 GNU C 行为,基于早期 64 位目标的 C 编译器所做的。 sxtw
指令是实现此行为所必需的。 (当前的 C 标准不再有隐式函数声明,但 GCC 仍然必须支持它们以向后兼容现有的 autoconf 测试。)
请注意,您的平台显然是 Aarch64(具有 64 位寄存器),而不是 32 位 ARMv7。
关于linux - 为什么编译器要添加额外的 'sxtw' 指令(进一步导致内核 panic )?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55351940/
我有这个: const {ops} = getOplogStreamInterpreter(strm); ops.del.subscribe(v => { console.log('delete
我四处搜索,据我所知,POST 表单请求已被限制为 10MB (http://golang.org/src/net/http/request.go#L721)。 如果我要在我的 ServeHTTP 方
我是一名优秀的程序员,十分优秀!