我有一个C程序,它运行在两个配置了相同时区的不同RHEL6服务器上。 C程序使用time.h
中的时间函数。在其中一台服务器上正确确定本地时间,另一台服务器显示的UTC(默认)时间与配置的时区无关。
我已经尝试查看/etc/localtime
的链接是否已损坏,但它是/usr/share/zoneinfo/<timezone>
(在本例中为欧洲/柏林)的正确软链接。
我已使用zdump
检查了时区文件,并且文件内容正确无误。使用date
也可以正确显示系统的时区和时间。我的bash或其他任何地方都没有$TZ
变量的定义!
作为一项额外测试,我使用和不使用$TZ
变量运行以下代码:
::time_t aclock;
::tm tm_tmp;
::tm *newtime;
setenv("TZ", "Europe/Berlin", 1);
tzset();
::time( &aclock );
newtime = ::localtime_r( &aclock, &tm_tmp );
printf("\nDEBUG TIME: %d ", aclock);
printf("\nDEBUG TIMEZONE: %s \n", newtime->tm_zone);
printf("DEBUG HOUR: %d \n", newtime->tm_hour);
使用上面的代码并以不同方式设置TZ参数我在故障服务器上获得以下输出,假设此时服务器时间为Europe/Berlin, CEST
:
without setenv:
DEBUG TIME: 1524241319
DEBUG TIMEZONE: UTC
DEBUG HOUR: 16
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: Europe
DEBUG HOUR: 16
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
所以它看起来像&#34;欧洲/柏林&#34;时间无法找到,因为显示UTC时间和时区&#34;欧洲&#34;无效。
正如我所说,其他机器上的输出/行为是预期的:
without setenv:
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
P.S。两台机器都使用相同的 gcc版本4.4.7 。
我的时区数据库是否可能在故障服务器上损坏?有人遇到类似问题并解决了吗?
答案 0 :(得分:0)
我终于想通了,问题是libc.so
库,它为其中一台机器编译不同,只用于Linux本身以外的一些C应用程序。这解释了为什么date
提供了wright输出但是C程序没有。
使用ldd libc.so
我发现链接器也设置为默认路径/home/mqm/lib
,这不适合我的服务器/home/mqm/lib/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
。要恢复,这是完整的解决方案:
问题:您的Linux系统正在使用date
或某些应用程序提供怀特日期和时间,但使用C程序输出错误。
解决方案:确保代码中没有编程错误后,请检查
strace -e trace=open,close,read,write,connect,accept yourCProgram
哪条路径用于获取时间/时区。您还可以检查ldd libc.so
以查看链接器的默认路径。
如果路径与您的Linux系统配置不对应,请考虑重新编译C库以适合您的系统配置,或将$TZ='fullpathtotimezone'
设置为修补程序/解决方法。