Разное поведение при запуске программы, скомпилированной с G ++ в Docker - PullRequest
2 голосов
/ 09 апреля 2019

Поведение исполняемого файла отличается, если он запускается внутри докера или на хосте. Но это происходит только тогда, когда мы меняем уровень оптимизации G ++.

Компилятор: g ++ (Ubuntu 7.3.0-27ubuntu1 ~ 18.04) 7.3.0

Я пытаюсь выполнить следующий код:

#include <cstdio>
#include <cstring>
int main()
 {
    int nOrd =3395;
    char cOrd[] = "003395";
    char cAux2[256];    
    strcpy(cAux2, cOrd);
    int nRest = nOrd % 26;
    printf("BEFORE SPRINTF %s\n\n\n", cAux2);
    sprintf(cAux2, "%s%c", cAux2, (nRest+65));
    printf("AFTER SPRINTF %s\n\n\n", cAux2);
    return 0;
 }

Если я скомпилирую с:

g++ -o FastCompile FastCompile.c -DNDEBUG -Os

И я бегу в хозяине. Выходные данные, как и ожидалось:

BEFORE SPRINTF 003395


AFTER SPRINTF 003395P

Если я создаю образ с помощью этого исполняемого файла и запускаю в докере, у меня есть:

Docker версия 18.09.4, сборка d14af54266

Dockerfile:

FROM debian
RUN apt-get update && apt-get install -y \
   libssl-dev
COPY fast/ /usr/local/
ENTRYPOINT ["usr/local/FastCompile"]

$ docker build -t fastcompile.

$ docker run fastcompile

BEFORE SPRINTF 003395


AFTER SPRINTF P

Если я уберу -Os и перекомпилирую с:

g++ -o FastCompile FastCompile.c -DNDEBUG 

В докере поведение правильное.

Так, Это проблема с докером? Или это ожидаемое поведение?

1 Ответ

5 голосов
/ 09 апреля 2019

Ваш код имеет неопределенное поведение.

sprintf(cAux2, "%s%c", cAux2, (nRest+65));

читает и пишет в один и тот же объект. Чтобы исправить это, вы можете использовать cOrd в вызове, чтобы вы не читали из буфера. Это будет выглядеть как

sprintf(cAux2, "%s%c", cOrd, (nRest+65));

Также обратите внимание, что (nRest+65) дает вам int, а не char, как вы указали в спецификаторе формата. Это также неопределенное поведение. Вам нужно привести его к персонажу, чтобы исправить это как

sprintf(cAux2, "%s%c", cOrd, char(nRest+65));
...