什么是“*((char *) - 1)='x';”代码意味着?

时间:2013-12-30 18:00:05

标签: c redis undefined-behavior

我在阅读redis源代码时遇到问题,有人能告诉我 debug.c _redisAssert函数中最后一个语句的用法是什么:

*((char*)-1) = 'x';

2 个答案:

答案 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'分配给此地址的内容,该内容绝对给出 分段错误。