люди! Я пишу программное обеспечение, которое должно устанавливать и запускать как можно больше версий Linux, но я должен быть в состоянии скомпилировать его на одном подчиненном устройстве Jenkins.
Сейчас это в основном работает. Но я столкнулся со случаем, когда специальная комбинация вещей приведет к ошибке в Debian 10, но не в любом из моих многочисленных поддерживаемых вариантов Linux. Мне удалось воспроизвести это в 3 разных приложениях (некоторые из которых работали в течение многих лет), включая упрощенный прототип, который я перечислил ниже.
// g++ -g -o ttt -static tt.cpp
// The above compile of this code on Centos 6 will produce a segfault
// when run on Debian 10, but not on any other tested flavor of Linux.
// Dozens of them. The version of g++ is 4.7.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int _argc, char* _argv[])
{
srand(time(0));
printf("success\n");
return 0;
}
Что я нашел, запустив каждое из моих 3 Приложения на Debian 10 с gdb состоят в том, что при этих условиях он будет зависать.
- Они должны быть скомпилированы с флагом -stati c. Если я не использую -stati c, он будет работать нормально, независимо от того, из какого типа он скомпилирован.
- Они должны вызывать функцию time (). Неважно, как я это называю, но это нужно называть. Я попробовал обычные подозреваемые, такие как передача нулевого указателя и передача реального указателя. При статической компиляции приложения всегда происходит сбой.
- Они должны быть скомпилированы в Centos 6 и запущены в Debian 10. Если я статически компилирую в Debian 10, прототип работает нормально.
Итак, вот мои ограничения, над которыми я работаю.
- Я должен скомпилировать на одном Linux ведомом, потому что я распространяю только один двоичный файл. Отслеживание нескольких двоичных файлов и того, какие из них используются, какой вариант Linux на самом деле не подходит.
- Мне приходится компилировать статически, или это создает несовместимости с другими поддерживаемыми вариантами Linux.
- Я должен использовать g ++ 4.7 также для совместимости кода.
В ваших ответах я надеюсь на какую-то хитрость кода. Может быть, хорошая, надежная замена функции time (). Или предложение другого варианта Linux, совместимого с Debian 10.
Бонусные баллы go дадут тому, кто сможет объяснить черным волхвам c, почему основа c вездесуща Функция, подобная time (), будет полностью совместима с Debian 9, но сбои в Debian 10 ТОЛЬКО при статической компиляции в Centos 6 ...
EDIT:
strace на сервере Centos 6:
execve("./ttt", ["./ttt"], [/* 37 vars */]) = 0
uname({sys="Linux", node="testcent6", ...}) = 0
brk(0) = 0x238c000
brk(0x238d180) = 0x238d180
arch_prctl(ARCH_SET_FS, 0x238c860) = 0
brk(0x23ae180) = 0x23ae180
brk(0x23af000) = 0x23af000
gettimeofday({1585687633, 358976}, NULL) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f682c82f000
write(1, "success\n", 8success
) = 8
exit_group(0) = ?
+++ exited with 0 +++
strace на сервере Debian 10:
execve("./ttt", ["./ttt"], 0x7fff0430dfd0 /* 18 vars */) = 0
uname({sysname="Linux", nodename="deletemedebian10", ...}) = 0
brk(NULL) = 0x1f6f000
brk(0x1f70180) = 0x1f70180
arch_prctl(ARCH_SET_FS, 0x1f6f860) = 0
brk(0x1f91180) = 0x1f91180
brk(0x1f92000) = 0x1f92000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xffffffffff600400} ---
+++ killed by SIGSEGV +++
Segmentation fault