folks! I am writing software that must install and run on as many flavors of Linux as possible, but I must be able to compile it on a single Jenkins slave.
Right now this mostly works. But I have run into a case whereby a special combination of things will produce a segfault on Debian 10, but not on any of my numerous other supported flavors of Linux. I have been able to reproduce this in 3 different apps (some of which have been working for years), including the simplified prototype I have listed below.
// 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;
}
What I have found by running each of my 3 apps on Debian 10 with gdb is that it will segfault under these conditions.
They must be compiled with the -static flag. If I don't use -static, it works fine, regardless on which flavor it is compiled.
They must call the time() function. It doesn't really matter how I call it, but it must be called. I tried the usual suspects like passing a NULL pointer and passing a real pointer. It always segfaults when the app is compiled statically.
They must be compiled on Centos 6 and run on Debian 10. If I compile statically on Debian 10, the prototype works fine.
So here are my constraints that I am working under.
I have to compile on one Linux slave, because I am distributing just one binary. Keeping track of multiple binaries and which one goes on what Linux flavor is not really an option.
I have to compile statically or it creates incompatibilities on other supported flavors of Linux.
I have to use an older Linux flavor, also for the sake of compatibility. It doesn't have to be Centos, but it has to produce binaries that will run on Centos, as well as numerous other flavors.
I have to use g++ 4.7 also for code compatibility.
In your answers, I am hoping for some kind of code trick. Maybe a good, reliable replacement for the time() function. Or a suggestion for another flavor of Linux that is compatible with Debian 10.
Bonus points would go to whoever is able to explain the black magic of why a basic, ubiquitous function like time() would be completely compatible on Debian 9, but segfaults on Debian 10 ONLY when it is compiled statically on Centos 6...
EDIT:
strace on the Centos 6 server:
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 on the Debian 10 server:
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
The executable is trying to use the vsyscall interface to implement the syscall used for the time function.
This interface has been deprecated in favor of the vdso for a long time. It was dropped completely a while back, but can still be emulated.
Debian 10 seems to have disabled the vsyscall emulation, which is done for security reasons because it may make attacks easier. You should be able to re-enable the emulation by passing the kernel command line option vsyscall=emulate at startup, of course with the mentioned security repercussions, if that is an option.
The glibc version on CentOS 6 seems to be 2.12, which is too old to make use of the vdso. So to compile a compatible binary for newer kernel configuations, you need at least glibc 2.14 instead. I don't know whether this can be easily installed on CentOS or whether it will work correctly with the kernel shipped with it.
You should also consider whether you really need a fully static binary. You could link everything statically except libc.
I have SAS 9.4 installed on my windows 7. How do I tell if it is 32 bit or 64 bit? On the net, I can see this question answered for SAS 9.2, not 9.4
You can examine the automatic macro variables such as SYSADDRBITS or SYSHOSTINFOLONG.
I presume a 32-bit SAS installation on 64-bit host would show SYSADDRBITS 32
Log all my automatic variables
%put _AUTOMATIC_;
Log
…
AUTOMATIC SYSADDRBITS 64 <--------------------
…
AUTOMATIC SYSHOSTINFOLONG X64_10PRO WIN 10.0.17134 Workstation <-----------------
…
AUTOMATIC SYSSCP WIN
AUTOMATIC SYSSCPL X64_10PRO <-----------------------
…
AUTOMATIC SYSSIZEOFLONG 4
AUTOMATIC SYSSIZEOFPTR 8 <-----------------------
AUTOMATIC SYSSIZEOFUNICODE 2
…
You can use: proc setinit; run;
Under Operating system it should show something like the below for 64bit linux:
Operating System: LIN X64 .
Or for 64bit windows workstation:
Operating System: WX64_WKS.
I do not understand what I'm doing wrong here. It appears that my Qt Application will not retrieve the value from the HKEY_LOCAL_MACHINE
QSettings sys_app_settings(QSettings::NativeFormat, QSettings::SystemScope, "JokerMartini", "Hyv");
qDebug() << "SYS" << sys_app_settings.value("config", "").toString();
You can even see in the image below that i have the information available but it will not retrieve it for whatever reason. It just returns the default value of "" Any suggestions?
Build Information:
Windows 64bit
Desktop Qt 5.10.1 MinGW 32Bit
Running application on windows 10 64 bit
I have a code wherein I check whether the OS is Windows 2008R2 or not and do stuff accordingly. The following link states that for Windows2008R2, the dwMajorVersion should be 6 and dwMinorVersion would be 1. In my code I check for these 2 values but I have found by logging those values on Windows 2008R2 SP1 OS that the dwMinorVersion is 0, not 1 like the link states.
Does the fact that it is 2008R2 SP1 change the minor version? Also if indeed this is supposed to be 0, then how would I differentiate between 2008R2 and 2008?
EDIT: Added the code snippet
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((LPOSVERSIONINFO )&osvi);
if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
// do something since this is Windows Server 2008R2 OS.
This question already has answers here:
Identifier for win64 configuration in Qmake
(5 answers)
Closed 7 years ago.
I'm trying to build a MultiArch Application for Ubuntu. I have to compile it separately on different Architectures. However I have to do a lot of manual changes Each time the Architecture changes. For Instance-
#linux-g++:LIBS += $$DESTDIR/lib32/libusb-1.0.so #arch-specific changes
linux-g++:LIBS += $$DESTDIR/lib64/libusb-1.0.so
Here I have to comment and uncomment a line every time I'm compiling for a different Architecture. I have to do this on a number of places.
However if there is a way to specify the Linux Architecture in the .pro file itself then my task will become much easier. I know that we can use win32 and macx scope variables and linux-g++ for Ubuntu. But I want to distinguish between ubuntu 32 bit and 64 bit Architectures. Is there any way this might be achieved a little more elegently?
I have already seen
qmake platform scopes
and I just want to specify that I'm looking to distinguish between linux32bit and linux64bit .
SOLVED IT:
linux-g++{
!contains(QT_ARCH, x86_64){
LIB=lib32
message("Compiling for 32bit system")
} else {
LIB=lib64
message("Compiling for 64bit system")
}
}