C strchr 在 HPUX 上使用 NULL 值,但在 RHEL 上使用段错误
C strchr works with NULL value on HPUX but segfaults on RHEL
我正在将一些代码从 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 生成文件:
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 生成文件:
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 通过不进行段错误来以不同方式处理空指针参数。或者我误解了发生的事情。
制作两个文件,r.c,main.c
r.c:
int *r = 0;
main.c:
extern int *r;
int main(void) {
return *r;
}
然后抄送main.cr.c; ./a.out
如果它不是 sigsegv,则您的运行时正在为您映射一页空值。
你可以自己做 - 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 :(
我正在将一些代码从 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 生成文件:
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 生成文件:
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 通过不进行段错误来以不同方式处理空指针参数。或者我误解了发生的事情。
制作两个文件,r.c,main.c r.c:
int *r = 0;
main.c:
extern int *r;
int main(void) {
return *r;
}
然后抄送main.cr.c; ./a.out 如果它不是 sigsegv,则您的运行时正在为您映射一页空值。 你可以自己做 - 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 :(