我将一些代码从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 :(