der*_*eky 4 c undefined-behavior redis
我在阅读redis源代码时遇到问题,有人能告诉我debug.c中_redisAssert函数中最后一个语句的用法是什么:
*((char*)-1) = 'x';
Run Code Online (Sandbox Code Playgroud)
更新
我在OP中提到的debug.c中找到了这行,我们可以从这段代码上面的两行看到:
redisLog(REDIS_WARNING,"(forcing SIGSEGV to print the bug report.)");
Run Code Online (Sandbox Code Playgroud)
并且也可以找到相同的代码_redisPanic,所以看起来他们的方式强制SIGSEGV断言失败或恐慌.
原版的
这看起来像一个调试工具,我们可以从这个文件中看到Redis调试指南和相关部分说:
Redis有一个使用DEBUG SEGFAULT命令模拟分段错误(换句话说是一个糟糕的崩溃)的命令(当然不要将它用于真实的生产实例;).所以我将使用此命令来崩溃我的实例以显示GDB端发生的事情:
并显示此gdb输出:
(gdb) continue
Continuing.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xffffffffffffffff
debugCommand (c=0x7ffc32005000) at debug.c:220
220 *((char*)-1) = 'x';
^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
它正在做的是转换-1为*char**,然后对其执行间接并分配'x'给该内存位置.作为alk链接的线程是((void*)-1)一个有效的地址?在大多数系统上说它无法访问,更不用说分配值了.这将在大多数现代操作系统上生成分段错误.
这是未定义的行为,并且在线程中已经过去了什么是在C中生成Segfault的最简单的标准符合方式?它不能被依赖.编译器变得越来越聪明,并且有一些着名的例子,编译器很聪明地以意外和坏的方式利用未定义的行为.