我将一些代码从HPUX 11.11移到RHEL 7.5,它包括一个使用strchr的函数。在HPUX上运行良好,在RHEL上存在分段错误。我隔离了代码,并创建了以下简单测试以及后续结果。找不到字符时,HPUX strchr似乎返回空字符串而不是NULL。这不是手册页所说的。我发现它可能不是strchr函数,而是HPUX处理NULL值的方式的差异,或者从cc到gcc的编译器的差异。有人真的知道这里发生了什么吗?为什么在HPUX上代码未分段?

C代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int i = 0;
    char* phrase = "Here is my phrase.";
    while (i < 5){
        phrase = strchr(phrase, ' ');
        ++phrase;

        ++i;
    }
    return 0;
}


HPUX Makefile:

BIN=/path/to/bin/
CFLAGS=-c

#----------Targets----------#
default: $(BIN)strchrtest

#----------Objects----------#
OBJS = strchrtest.o

#----------------BUILD----------------#
$(BIN)strchrtest: $(OBJS)
    cc -o $@ $(OBJS)

strchrtest.o: strchrtest.c
    cc $(CFLAGS) strchrtest.c


RHEL Makefile:

CC=gcc
BIN=/path/to/bin/
CFLAGS=-c -g -Wall

#----------Targets----------#
default: $(BIN)strchrtest

#----------Objects----------#
OBJS = strchrtest.o

#----------------BUILD----------------#
$(BIN)strchrtest: $(OBJS)
    $(CC) -o $@ $(OBJS)

strchrtest.o: strchrtest.c
    $(CC) $(CFLAGS) strchrtest.c


HPUX只是一个成功的结果。无分段错误。

RHEL结果:

(gdb) run
Starting program: ../strchrtest

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b4c5f4 in __strchr_sse42 () from /lib64/libc.so.6


从下面的评论中复制了:关键是,当要求strchr函数本身在空指针中找到一个字符(已递增)时,它会导致段错误,但在HPUX上则不会。因此,它要么返回一个空字符串,然后在下一个循环将其传递给strchr,要么strchr通过不进行段错误处理以不同方式处理null指针参数。否则我会误会正在发生的事情。

最佳答案

这样制作两个文件r.c,main.c
r.c:

int *r = 0;


main.c:

extern int *r;
int main(void) {
     return *r;
}


然后是cc main.c r.c; ./a.out
如果不是sigsegv,则您的运行时正在为您映射一个null页。
您可以自己做-main.c:

#include <sys/mman.h>
int main(void) {
    p = mmap(0, 1, PROT_READ, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
    if (p == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
     ....
}


但至少在ubuntu上,您需要是root :(

10-07 15:05