GNU/Linux >> Linux の 問題 >  >> Linux

Linux の 32 ビット プログラムで 64 ビットの time_t を取得する方法はありますか?

どうやら、それは不可能です。まず、time() は 1 つだけです。 Linux での機能、なし time32() または time64() .

しばらく調べてみると、libc のせいではなく、実はカーネルに問題があることがわかりました。

libc が現在の時刻を取得するには、システム コールを実行する必要があります:

time_t time (t) time_t *t;
{
    // ...
    INTERNAL_SYSCALL_DECL (err);
    time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
    // ...
    return res;
}

システムコールは次のように定義されます:

SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
    time_t i = get_seconds();
    // ...
    return i;
}

関数 get_seconds() unsigned long を返します 、そのように:

unsigned long get_seconds(void)
{
    struct timekeeper *tk = &timekeeper;

    return tk->xtime_sec;
}

そして timekeeper.xtime_sec は実際には 64 ビットです:

struct timekeeper {
    // ...
    /* Current CLOCK_REALTIME time in seconds */
    u64                     xtime_sec;
    // ...
}

C の知識があれば、 unsigned long のサイズが 実際には実装依存です。ここにある私の 64 ビット マシンでは、64 ビットです。しかし、私の 32 ビット マシンでは 32 ビットです。 おそらく 一部の 32 ビット実装では 64 ビットになる可能性がありますが、保証はありません。

一方、u64 は常に 64 ビットであるため、カーネルは基本的に 64 ビット型で時間を追跡します。これを unsigned long として返す理由 、64ビット長であることが保証されていないため、私には理解できません。

最後に、libc が time_t を強制したとしても 64 ビットの値を保持する場合、何も変わりません。

アプリケーションをカーネルに深く結び付けることができますが、それだけの価値はないと思います。


上記の多くの回答は不可能だと言っていますが、それは完全に間違っています . だった 当時は不可能でしたが、人々はそれを修正することについて何年も話し合っていました。最後に、新しい *time64 の追加により、32 ビット プラットフォームでの 64 ビット時間のサポートが Linux 5.1 カーネルに導入されました。 システムコール。この表を見ると、これらの syscall は 32 ビット プラットフォームでのみ使用できることがわかります。 32 ビット システム用のコードを記述している場合は、clock_gettime64 を呼び出すことができます。 直接 (インライン アセンブリまたは syscall() を使用した C から) ) 現在の時刻を取得する

ただし、その後は完全に独りです。フルユーザースペースが必要な場合 Linux 5.6 以降と musl 1.2+ または glibc 2.32+ を使用している必要があります。コードと time_t を再構築するだけです 64ビット長になります

  • すべてのユーザー空間は、64 ビットの time_t でコンパイルする必要があります これは、今後の musl-1.2 および glibc-2.32 リリースで、linux-5.6 以降のインストール済みカーネル ヘッダーと共にサポートされる予定です。

  • システム コール インターフェイスを直接使用するアプリケーションは、time64 を使用するように移植する必要があります。 syscalls は、既存のシステム コールの代わりに linux-5.1 で追加されました。これは futex() のほとんどのユーザーに影響します と seccomp() libc に基づいていない独自のランタイム環境を持つプログラミング言語も同様です。

https://lkml.org/lkml/2020/1/29/355?anz=web

詳細については

  • カーネル 2038 年エンド ゲームに近づく
  • GNU C ライブラリでの 64 ビット時間シンボルの処理
  • glibc Y2038 プルーフネス デザイン
  • time_t と clock_t を 64 ビットに変更

Linux
  1. Dhcpd:Dhcpプールのステータスを確認する方法はありますか?

  2. javaを使用してLinuxマシンでユーザーのUIDを取得する方法はありますか?

  3. 64 ビット Unix タイムスタンプ変換

  1. Linux でエポックからの秒数を取得する

  2. Cargo プロジェクトの名前を変更する方法はありますか?

  3. Linux で LD_PRELOAD と LD_LIBRARY_PATH をブロックする方法はありますか?

  1. Linux - ソフトウェアでメモリの速度を特定する方法はありますか?

  2. Linux 内から BIOS バージョンを取得する方法はありますか?

  3. Linux でブロック デバイスのキャッシュ ヒット/ミス率を取得する方法はありますか?