c - 修复段错误

标签 c string casting

<分区>

我遇到了段错误,我已将其缩小为回调函数中的 for 循环。很奇怪,因为该程序以前可以运行,现在不行了!

struct debuggerth_command debuggerth_protocol[] = { /*
    * Note: These strings are NOT null-terminated. The
    * strings are 4 bytes long for memory alignment and
    * integer-cast comparisons.
    */

    { "run ", debuggerth_startprocess },
    { "stop", 0 },
    { "inp ", 0 },
    { "sig ", 0 },
    { 0, 0 }
};

这是代码:

int debuggerth_callback (struct libwebsocket_context * context,
                    struct libwebsocket * wsi,
                    enum libwebsocket_callback_reasons reason,
                    void * user,
                    void * in,
                    size_t len){

switch (reason) {

case LWS_CALLBACK_RECEIVE:

    if (len < 4){
        /* send error */
        return -1;
    }

    /* Getting a segmentation fault
     * within this loop.
     */

    // I used this break to determine where the seg fault starts
    // break

    int i = 0;
    for (; debuggerth_protocol[i].cmd; i++)
        if (cmpcmd (debuggerth_protocol[i].cmd, in)) break;


    //break;

    if (!debuggerth_protocol[i].cmd){
        int byteswritten = sprintf
            (debuggerth_message,
             debuggerth_format,
             debuggerth_headers[0],
             debuggerth_errors [0]);

         libwebsocket_write (wsi, debuggerth_message,
                                      byteswritten,
                                      LWS_WRITE_TEXT);
         return -1;
    }

    break;

这是字符串比较宏:

#define cmpcmd(cmd, str) ((*(int*)(cmd)) == (*(int*)(str)))

有人有什么想法吗?

最佳答案

一个想法:依赖于你的字符串恰好是 int 的大小这一事实是相当可怕的。

人们经常尝试做这样聪明的事情,但当基本假设发生变化时,例如移动到 int 类型为八个字节的平台时,只会被严重咬伤。

我会放弃该宏并重写它以使用 strcmpstrncmp (a)


还有一些其他事情要做。

首先,在尝试使用它们之前打印出(或使用调试器检查)所有变量。可能是in为NULL。

或者您可能尝试调用 NULL 命令,如 stopsig,或者即使您得到一个不在您的表中的命令并且您在 i 等于 4。这些特殊的可能性在代码中没有显示,在循环之后,所以它是纯粹的,尽管我想认为是受过教育的,我的猜测。


另一种可能性是您在不允许未对齐访问的架构上运行。某些架构针对特定边界的访问进行了优化(例如从 32 位对齐地址获取 32 位值),如果您违反该对齐,运行速度会变慢。

但是,一些架构根本不允许未对齐的访问,而是在您尝试时给出类似 BUS 错误的信息。

既然您现在在评论中表示您正在使用 ARM,那么几乎可以肯定是这样。参见 here了解更多信息。

如果是这样的话,更有理由摆脱棘手的宏并使用更传统的解决方案。


(a):您可能还想在某个时候调查术语“严格别名”,因为这在技术上可能是未定义的行为。

关于c - 修复段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17057749/

相关文章:

Java : autoboxing of an Object array of integers, 从 LinkedList.toArray() 转换为 int

Mastermind 游戏的字符串比较

java - StringBuffer 已过时?

c - 如何从 char 缓冲区读取到 unsigned long 和 short

string - 如何在 Haskell 中检查字符串的每个字符

java - 允许缺失字符的正则表达式

c++ - 使用 boost_any 时是否可以避免开销?

c++ - 关于模板类的 C++ 动态转换

c - 关于 C 分配的问题

c - 为什么不能在 if 语句中使用空指针?