C strchr работает со значением NULL на HPUX, но с ошибками на RHEL - PullRequest
0 голосов
/ 06 ноября 2019

Я перемещаю некоторый код из 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 вызывает segfault, когда ее просят найти символ в нулевом указателе(это было увеличено), но на HPUX это не так. Поэтому он либо возвращает пустую строку, которая затем передается strchr в следующем цикле, либо strchr обрабатывает параметр нулевого указателя по-другому, не используя segfaulting. Или я неправильно понимаю, что происходит.

1 Ответ

1 голос
/ 06 ноября 2019

Создайте два файла, rc, main.c как таковые: rc:

int *r = 0;

main.c:

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

затем cc main.c rc;./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: (

...