我在阅读redis源代码时遇到问题,有人能告诉我 debug.c 中_redisAssert
函数中最后一个语句的用法是什么:
*((char*)-1) = 'x';
答案 0 :(得分:7)
更新
我在OP中提到了debug.c中的行,我们可以从此代码上方的两行看到:
redisLog(REDIS_WARNING,"(forcing SIGSEGV to print the bug report.)");
并且_redisPanic
中也可以找到相同的代码,因此当断言失败或出现恐慌时,它似乎是强制SIGSEGV
的方式。
原始
这看起来像一个调试工具,我们可以从这个文档中看到Redis debugging guide,相关部分说:
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';
^^^^^^^^^^^^^^^^^^^
它正在做的是将-1
转换为* char **,然后对其执行间接操作并将'x'
分配给该内存位置。作为alk链接Is ((void *) -1) a valid address?在大多数系统上说的线程,访问它是无效的,更不用说分配值了。这将在大多数现代操作系统上生成segmentation fault。
这是undefined behavior并且在线程What is the simplest standard conform way to produce a Segfault in C?中已经过去了,因此无法依赖它。编译器越来越聪明,有一些着名的例子,其中compiler is smart about exploiting undefined behavior出现了意想不到的错误。
答案 1 :(得分:0)
在您的表达式中*((char*)-1) = 'x';
:
您正在将值-1
投射到char *
,这会向您提供指向否定地址的指针,然后您尝试将值'x'
分配给此地址的内容,该内容绝对给出
分段错误。