【发布时间】:2021-04-02 02:20:21
【问题描述】:
当我的应用程序在 arm 设备上的 alpine docker 容器中运行时,它无法处理像 time(2) 这样的时间操作。
我有什么: 我正在构建一个本地 c 应用程序,它使用来自 musl.cc (arm-linux-musleabihf-gcc) 的工具链静态链接到 musl。我正在使用最新的 alpine 容器(没有图像标签)。
它的行为方式:
- 直接在 arm 设备上运行二进制文件可以正常工作
- 在 x64 设备上的 alpine 容器中运行按预期工作
- 在 arm 设备上的 alpine 容器中运行不工作
出了什么问题:
-
time(NULL);返回 ((time_t) -1) and error=1: "Operation not allowed" - 日志输出中的时间戳具有曲柄时间戳
- SSH 握手失败,因为远程证书的有效期在未来。
但是,如果我在容器的灰烬中执行date,则输出是有效的。因此,似乎存在仅在 ARM 架构上的 alpine 容器中出现的问题。有趣的是,我正在从 Ubuntu 切换到 Alpine,因为我们在那里有 similar problems。
有人知道我做错了什么吗?
更新#1: 在 ubuntu 上也有同样的问题。所以问题似乎出在任何基于 docker 的图像上,但仅限于 arm 设备上。
更新 #2:这是一个最小的示例 TimeTest.c
#include <stdio.h>
#include <string.h>
#include "time.h"
#include "errno.h"
int main()
{
printf("hallo\n");
time_t myTime;
time_t result = time(&myTime);
printf("result: %lld\n", result);
if ((long)result < 0)
{
printf("time() error=%d: %s\n", errno, strerror(errno));
}
else
{
struct tm* tm_info = localtime(&myTime);
printf("Current local time and date: %s\n", asctime(tm_info));
}
return 0;
}
CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
project ("TimeTest")
if(BUILD_TARGET STREQUAL "ARM_MUSL")
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER /usr/bin/arm-linux-musleabi-gcc)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-stack-protector -mfloat-abi=softfp -static --static")
set(CMAKE_LINK_SEARCH_END_STATIC TRUE)
endif()
add_executable (TimeTest "TimeTest.c")
手臂设备上的输出
pi@raspberrypi:/tmp $ docker run --rm -it -v /tmp/TimeTest:/TimeTest alpine ash
/ # /TimeTest
hallo
result: -4696377169665647048
time() error=1: Operation not permitted
【问题讨论】:
-
暗中猜测:可能与vDSO有关。
-
如果使用
time_t对象的地址调用time()会发生什么? -
@AndrewHenle:两者,返回值和指向 time() 的 time_t 具有相同的值:((time_t) -1)
-
你能发布示例程序吗?
which is statically linked呃,正常链接也会发生同样的情况吗?你能发布你正在使用的编译命令吗? IE。一些minimal reproducible example。 -
@KamilCuk:我添加了一个示例。希望例子没问题