以下の内容はhttps://tech.guitarrapc.com/entry/2026/02/09/160000より取得しました。


straceでC#のシステムコールを覗いてみる

ClassMethodsさんの記事で、C,Go,Rust,Python,Node.jsのHello Worldプログラムをstraceで覗いていたのですが、C#も気になりませんか?私は気になるので見てみましょう。

C#のビルド成果物にはJITとAOTの2種類があり、これらの言語がVMを用いないことを考えると比較するならAOTでのstraceが適切です。ただ、せっかくなので両方を見てみましょう。

結論

記事が長いので、結論を書いておきます。

システムコール数の比較は次の通りです。

実装 システムコール数
C# (JIT) 1159
C# (JIT + ICU無効) 940
C# (JIT + ICU指定) 985
C# (AOT) 470
C# (AOT + ICU無効) 228
C# (AOT + ICU指定) 290
Go 185
Go (共有ライブラリ版) 24884
Rust 63
C 34

C#の起動時のシステムコールを減らすには、ICUの使用有無を指定するのが効果的です。

  • InvariantCultureで問題ない: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
  • 多言語対応が必要: DOTNET_ICU_VERSION_OVERRIDE=<バージョン>で探索を削減

環境

今回の検証はguitarrapc/linux-straceリポジトリで公開しています。元の記事のリポジトリを参考にしつつ、C#のJIT/AOT両方や結果を記載し、再現が取れるようにコンテナで動かしています。気になる方は参照してください。

項目 バージョン
OS Ubuntu 24.04 (コンテナ)
C (gcc) 13.3.0
Rust 1.93.0
Go 1.24.1
.NET SDK 10.0.102
strace 6.8

検証

各言語でHello, Worldを書いていきます。C、Rust、Goは元記事と同じコードです。

C#

Console.WriteLine("Hello, World");

C

#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}

Rust

fn main() {
    println!("Hello World");
}

Go

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello World")
}

成果物の生成

成果物を生成する流れは本題ではないので、再現したい人向けに簡単に説明します。

C#は、JITとAOTはPublishAotの有無だけで切り替わります。publish時のパラメーターで指定してもいいのですが、わかりやすくするため、フォルダを分けて2つ用意しましょう。それぞれhello_csharp (JIT)とhello_csharp_aot (AOT)を使います。

C# (JIT)

JIT設定のhello_csharp.csprojです。ランタイムを自己完結型にして、単一ファイルにまとめる設定です。

mkdir hello_csharp
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishTrimmed>true</PublishTrimmed>
    <SelfContained>true</SelfContained>
  </PropertyGroup>

</Project>

成果物をリリースビルドで作成します。

dotnet publish -c Release -r linux-x64 -o ./bin hello_csharp/hello_csharp.csproj

C# (AOT)

AOT設定のhello_csharp_aot.csprojです。JITとの違いは、<PublishAot>true</PublishAot>の追加だけです。

mkdir hello_csharp_aot
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishSingleFile>true</PublishSingleFile>
    <SelfContained>true</SelfContained>
    <PublishTrimmed>true</PublishTrimmed>
    <PublishAot>true</PublishAot>
  </PropertyGroup>

</Project>
dotnet publish -c Release -r linux-x64 -o ./bin hello_csharp_aot/hello_csharp_aot.csproj

C

gcc hello_c/main.c -o ./bin/hello_c

Rust

rustc hello_rust/main.rs -o ./bin/hello_rust

Go

静的リンク版(通常)と共有ライブラリ版1の2種類を作成します。

cd hello_go && go build -o ../bin/hello_go && cd ..
cd hello_go && go build -linkshared -o ../bin/hello_go_linkshared && cd ..

システムコールの統計を比較

元記事同様に、strace -cオプションでシステムコール数の統計を出します。

strace -c `./バイナリ`

使うバイナリはこちらです。各言語を見ていきましょう。

$ ls -l ./bin/hello*
-rwxrwxrwx 1 ubuntu ubuntu    15960 Feb 10 13:21 ./bin/hello_c
-rwxrwxrwx 1 ubuntu ubuntu 14853880 Feb 10 13:35 ./bin/hello_csharp
-rwxrwxrwx 1 ubuntu ubuntu  1270792 Feb 10 13:21 ./bin/hello_csharp_aot
-rwxrwxrwx 1 ubuntu ubuntu  2204715 Feb 10 13:21 ./bin/hello_go
-rwxrwxrwx 1 ubuntu ubuntu    24048 Feb 10 13:21 ./bin/hello_go_linkshared
-rwxrwxrwx 1 ubuntu ubuntu  3893728 Feb 10 13:21 ./bin/hello_rust

C

$ strace -c ./bin/hello_c
Hello World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 32.15    0.000109          13         8           mmap
 10.62    0.000036          12         3           mprotect
  8.55    0.000029          29         1           write
  6.49    0.000022           7         3           brk
  5.31    0.000018           9         2           close
  5.31    0.000018           6         3           fstat
  5.31    0.000018           9         2           pread64
  4.42    0.000015          15         1           munmap
  4.13    0.000014           7         2           openat
  2.95    0.000010          10         1           read
  2.65    0.000009           9         1           prlimit64
  2.65    0.000009           9         1           getrandom
  2.36    0.000008           8         1           arch_prctl
  2.36    0.000008           8         1           set_tid_address
  2.36    0.000008           8         1           set_robust_list
  2.36    0.000008           8         1           rseq
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ----------------
100.00    0.000339           9        34         1 total

Rust

$ strace -c ./bin/hello_rust
Hello World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 18.45    0.000119           9        13           mmap
  9.46    0.000061          12         5           mprotect
  8.84    0.000057          11         5           read
  7.91    0.000051          12         4           close
  7.13    0.000046           9         5           rt_sigaction
  7.13    0.000046          11         4           openat
  6.67    0.000043          21         2           munmap
  4.03    0.000026           8         3           brk
  4.03    0.000026           8         3           sigaltstack
  3.72    0.000024           6         4           fstat
  3.26    0.000021          21         1           write
  3.26    0.000021          10         2           pread64
  3.26    0.000021          21         1           getrandom
  2.79    0.000018           9         2           prlimit64
  1.86    0.000012          12         1           poll
  1.55    0.000010          10         1           sched_getaffinity
  1.40    0.000009           9         1           arch_prctl
  1.40    0.000009           9         1           gettid
  1.40    0.000009           9         1           set_tid_address
  1.24    0.000008           8         1           set_robust_list
  1.24    0.000008           8         1           rseq
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ------------------
100.00    0.000645          10        63         1 total

Go

$ strace -c ./bin/hello_go
Hello World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 54.59    0.001041           9       114           rt_sigaction
 14.53    0.000277          15        18           rt_sigreturn
 10.44    0.000199          39         5         1 futex
  7.03    0.000134          67         2           clone
  4.09    0.000078          13         6           fcntl
  3.15    0.000060          10         6           rt_sigprocmask
  1.73    0.000033           1        20           mmap
  1.68    0.000032          16         2           prlimit64
  1.31    0.000025          25         1           write
  1.05    0.000020          10         2           sigaltstack
  0.42    0.000008           8         1           gettid
  0.00    0.000000           0         1           read
  0.00    0.000000           0         1           close
  0.00    0.000000           0         2           madvise
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           sched_getaffinity
  0.00    0.000000           0         1           openat
------ ----------- ----------- --------- --------- ------------------
100.00    0.001907          10       185         1 total

Go (共有ライブラリ版)

$ strace -c ./bin/hello_go_linkshared
Hello World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 99.30    0.363647          14     24613           rt_sigreturn
  0.18    0.000676          21        31         3 futex
  0.14    0.000511          73         7           mprotect
  0.14    0.000503           4       114           rt_sigaction
  0.08    0.000307          20        15           rt_sigprocmask
  0.06    0.000234          78         3           clone
  0.05    0.000174           4        40           mmap
  0.01    0.000029           4         6           fcntl
  0.01    0.000027           4         6           read
  0.01    0.000023           2         9         4 openat
  0.00    0.000011           2         5           close
  0.00    0.000010           3         3           brk
  0.00    0.000010           5         2           sigaltstack
  0.00    0.000008           4         2           sched_getaffinity
  0.00    0.000007           7         1           munmap
  0.00    0.000007           3         2           madvise
  0.00    0.000006           2         3           prlimit64
  0.00    0.000006           6         1         1 clone3
  0.00    0.000004           1         4           fstat
  0.00    0.000004           4         1           gettid
  0.00    0.000004           4         1           getrandom
  0.00    0.000000           0         1           write
  0.00    0.000000           0         2           pread64
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         3           sched_yield
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         3         3 newfstatat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           rseq
------ ----------- ----------- --------- --------- ------------------
100.00    0.366208          14     24884        12 total

C# (AOT)

$ strace -c ./bin/hello_csharp_aot
Hello, World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 33.24    0.001192           9       129        83 openat
 14.89    0.000534           8        61           mmap
 12.97    0.000465          17        27           mprotect
  7.45    0.000267          12        22           munmap
  6.53    0.000234           5        44           fstat
  5.94    0.000213           4        45           close
  4.35    0.000156           9        16        12 newfstatat
  3.12    0.000112           2        38           read
  2.51    0.000090           5        18           rt_sigaction
  2.29    0.000082          13         6           rt_sigprocmask
  1.06    0.000038           9         4           ioctl
  0.98    0.000035          17         2           write
  0.98    0.000035          17         2           clone3
  0.70    0.000025           8         3           futex
  0.56    0.000020           1        17           madvise
  0.47    0.000017          17         1           pipe2
  0.31    0.000011          11         1           lseek
  0.28    0.000010           3         3           pread64
  0.25    0.000009           2         4           brk
  0.25    0.000009           3         3           sched_getaffinity
  0.22    0.000008           2         3           getpid
  0.22    0.000008           8         1           fcntl
  0.22    0.000008           8         1           gettid
  0.22    0.000008           2         4           prlimit64
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           sysinfo
  0.00    0.000000           0         2           statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         2           getdents64
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           get_mempolicy
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           getrandom
  0.00    0.000000           0         2           membarrier
  0.00    0.000000           0         1           rseq
------ ----------- ----------- --------- --------- ------------------
100.00    0.003586           7       470        96 total

C# (JIT)

$ strace -c ./bin/hello_csharp
Hello, World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 46.49    0.002176           6       343           mprotect
 18.44    0.000863           5       161           mmap
  9.25    0.000433           2       163        92 openat
  4.10    0.000192           5        37           munmap
  3.18    0.000149           3        38        34 readlink
  2.88    0.000135           6        21           pread64
  2.67    0.000125           1        67           fstat
  2.63    0.000123           5        22           fcntl
  2.22    0.000104           6        15           rt_sigprocmask
  1.60    0.000075           8         9           stat
  1.30    0.000061           1        61           close
  1.22    0.000057           8         7           clone3
  1.03    0.000048           2        24           rt_sigaction
  0.58    0.000027           0        58           read
  0.43    0.000020           3         6         6 access
  0.41    0.000019           1        11           brk
  0.34    0.000016           8         2           pipe2
  0.28    0.000013           1         9           futex
  0.26    0.000012           3         4           ioctl
  0.21    0.000010           2         5           getpid
  0.19    0.000009           1         8           write
  0.19    0.000009           0        23           madvise
  0.11    0.000005           5         1           lseek
  0.00    0.000000           0         1           socket
  0.00    0.000000           0         1           bind
  0.00    0.000000           0         1           listen
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           ftruncate
  0.00    0.000000           0         5         2 unlink
  0.00    0.000000           0         1           fchmod
  0.00    0.000000           0         2           sysinfo
  0.00    0.000000           0         1           getsid
  0.00    0.000000           0         2           sigaltstack
  0.00    0.000000           0         2           statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           gettid
  0.00    0.000000           0         4           sched_getaffinity
  0.00    0.000000           0         2           getdents64
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           get_mempolicy
  0.00    0.000000           0         2           mknodat
  0.00    0.000000           0        16        12 newfstatat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0        10           prlimit64
  0.00    0.000000           0         1           getrandom
  0.00    0.000000           0         1           memfd_create
  0.00    0.000000           0         4           membarrier
  0.00    0.000000           0         1           rseq
------ ----------- ----------- --------- --------- ------------------
100.00    0.004681           4      1159       146 total

元記事に比べてGoのシステムコール数が減っています。(911 -> 185前後) straceは決定論的に結果が出るわけではないので、実行ごとに多少のばらつきがありますが、明らかに違いがあります。Goのバージョンは元記事が1.24.0、今回が1.24.1なので、このような差が生まれる要因とは考えにくく、実際記事のリポジトリにあるコンテナを用いても本記事と同様の190前後でした。おや? 今回、Goの共有ライブラリ版も追加しましたが、こちらは24884回と非常に多くなっています。共有ライブラリ版は動的リンクを行うため、起動時に多くのシステムコールが発生するようです。とはいえ、さすがに多すぎる気もします。

本記事で追加したC# (JIT)とC# (AOT)ですが、JITは1159回、AOTは470回と大きな差があります。AOTはネイティブコードに変換されているので、JITのように実行時にコードを生成する必要がなく、その分システムコール数が減っています。これは、あとから見るwriteの数の違いでも分かります。

C#のopenatシステムコールとICU

C#はJITもシステムコールが多いですが、AOTにしてもまだシステムコールが多く特にopenatの数が目立ちます。openat/readlink/accessはerrorsがあるのも気になります。 straceでopenatを調べてみると、openat(…libicu*.so…)ログから、プログラムロード前にICU(国際化対応ライブラリ)のデータファイルを探しに行っていることが分かります。glibc-hwcapsバージョンごとにICUバージョンを90 > 89 > 88 ... 74と探索するため、openatが大きく増え、ICUファイルが見つからなければENOENTが出てerrorがカウントされます。最後にlibicuuc.so.74が見つかった瞬間から、libicudata.so.74libicui18n.so.74のロードに進んでいます。

結果、(候補バージョン数) × (探索ディレクトリ数) × (hwcaps分岐)でopenatもエラーが増えているわけです。

C# (AOT)のstraceログ全文(クリックで展開)

$ strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_csharp_aot 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
openat(AT_FDCWD, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 3
strace: Process 160 attached
[pid   159] openat(AT_FDCWD, "/sys/fs/cgroup//memory.max", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/proc/meminfo", O_RDONLY) = 3
[pid   159] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
strace: Process 161 attached
[pid   159] openat(AT_FDCWD, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
[pid   159] openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
[pid   159] openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/", 0x7ffc1064fc30, 0) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] newfstatat(AT_FDCWD, "/usr/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/usr/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.74", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicudata.so.74", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   159] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicui18n.so.74", O_RDONLY|O_CLOEXEC) = 6
Hello, World
[pid   161] +++ exited with 0 +++
[pid   160] +++ exited with 0 +++
+++ exited with 0 +++

C# (JIT)のstraceログ全文(クリックで展開)

$ strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_csharp 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/", 0x7ffea13b05b0, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
access("", F_OK)                        = -1 ENOENT (No such file or directory)
access("opt/coreservicing", F_OK)       = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
access("", F_OK)                        = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
strace: Process 55 attached
[pid    54] openat(AT_FDCWD, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 8
[pid    54] openat(AT_FDCWD, "/dev/urandom", O_RDONLY|O_CLOEXEC) = 9
[pid    54] openat(AT_FDCWD, "/proc/54/stat", O_RDONLY) = 10
strace: Process 56 attached
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 11
[pid    54] openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 11
[pid    54] openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 11
[pid    54] openat(AT_FDCWD, "/proc/54/stat", O_RDONLY) = 11
[pid    54] openat(AT_FDCWD, "/proc/54/stat", O_RDONLY) = 11
strace: Process 57 attached
strace: Process 58 attached
[pid    57] openat(AT_FDCWD, "/tmp/clr-debug-pipe-54-2245245-in", O_RDONLY <unfinished ...>
[pid    54] openat(AT_FDCWD, "/proc/54/stat", O_RDONLY) = 14
[pid    54] openat(AT_FDCWD, "/dev/shm/sem.clrst00000036000000000022427d", O_RDWR|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/sys/fs/cgroup//memory.max", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/proc/meminfo", O_RDONLY) = 12
[pid    54] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12
[pid    54] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12
strace: Process 59 attached
[pid    54] openat(AT_FDCWD, "/proc/self/task/59/comm", O_RDWR) = 14
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 12
strace: Process 60 attached
[pid    54] openat(AT_FDCWD, "/proc/self/task/60/comm", O_RDWR) = 16
[pid    54] access("", F_OK)            = -1 ENOENT (No such file or directory)
[pid    54] access("opt/corebreadcrumbs", F_OK) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 14
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 16
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 18
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 20
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 22
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 25
strace: Process 61 attached
[pid    54] openat(AT_FDCWD, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 30
[pid    54] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 32
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/usr/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.74", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicudata.so.74", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    54] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicui18n.so.74", O_RDONLY|O_CLOEXEC) = 29
Hello, World
[pid    57] <... openat resumed>)       = ?
[pid    60] +++ exited with 0 +++
[pid    61] +++ exited with 0 +++
[pid    59] +++ exited with 0 +++
[pid    58] +++ exited with 0 +++
[pid    57] +++ exited with 0 +++
[pid    56] +++ exited with 0 +++
[pid    55] +++ exited with 0 +++
+++ exited with 0 +++

ICUの読み込みを無効化する

DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1を指定するとICUの読み込みを無効化できます。この状態でstraceを取ると、C# AOT、JIT共にopenatが減っています。

  • C# AOT: 全体の数が470から228へ、openatの数が129 (83)から28 (7)へ減少
  • C# JIT: 全体の数が1159から940へ、openatの数が163 (92)から77 (28)へ減少

C# (AOT)

$ DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 strace -c ./bin/hello_csharp_aot
Hello, World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 18.23    0.000144           5        28         7 openat
 14.18    0.000112           6        18           rt_sigaction
 14.05    0.000111          55         2           clone
  8.48    0.000067           2        30           read
  6.84    0.000054          13         4           ioctl
  6.46    0.000051           2        22           mprotect
  4.81    0.000038           6         6           rt_sigprocmask
  4.68    0.000037          18         2           write
  3.16    0.000025           1        20           mmap
  2.78    0.000022           1        21           close
  2.78    0.000022           1        17           madvise
  2.53    0.000020           1        20           fstat
  2.28    0.000018          18         1           pipe2
  1.65    0.000013           4         3           pread64
  1.39    0.000011           3         3           sched_getaffinity
  1.27    0.000010          10         1           fcntl
  1.14    0.000009           9         1           lseek
  1.14    0.000009           3         3           getpid
  1.14    0.000009           2         4           prlimit64
  1.01    0.000008           8         1           gettid
  0.00    0.000000           0         4           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           sysinfo
  0.00    0.000000           0         2           statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1         1 get_mempolicy
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           getrandom
  0.00    0.000000           0         2           membarrier
  0.00    0.000000           0         1           rseq
  0.00    0.000000           0         1         1 clone3
------ ----------- ----------- --------- --------- ------------------
100.00    0.000790           3       228        10 total

C# (JIT)

$ DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 strace -c ./bin/hello_csharp
Hello, World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 22.62    0.002220           7       314           mprotect
 14.36    0.001410          11       128           mmap
 12.74    0.001251          16        77        28 openat
  7.71    0.000757          14        52           read
  4.49    0.000441           9        45           fstat
  3.95    0.000388          55         7           clone
  3.80    0.000373           9        38        34 readlink
  3.50    0.000344          18        19           munmap
  3.48    0.000342           8        39           close
  3.28    0.000322          21        15           rt_sigprocmask
  2.56    0.000251          11        21           pread64
  2.07    0.000203           8        23           madvise
  1.79    0.000176          11        16        12 newfstatat
  1.78    0.000175           7        24           rt_sigaction
  1.34    0.000132           6        22           fcntl
  1.07    0.000105          11         9           stat
  1.03    0.000101          10        10           prlimit64
  0.99    0.000097          97         1           bind
  0.69    0.000068           6        10           brk
  0.68    0.000067          11         6         6 access
  0.57    0.000056          28         2           mknodat
  0.52    0.000051           6         8           write
  0.37    0.000036           7         5         2 unlink
  0.35    0.000034           4         8           futex
  0.34    0.000033          16         2           pipe2
  0.34    0.000033           8         4           membarrier
  0.33    0.000032          32         1           socket
  0.32    0.000031           7         4           sched_getaffinity
  0.31    0.000030           6         5           getpid
  0.31    0.000030          15         2           sysinfo
  0.31    0.000030          15         2           statfs
  0.22    0.000022          22         1           gettid
  0.21    0.000021           5         4           ioctl
  0.20    0.000020          10         2           sigaltstack
  0.18    0.000018          18         1           memfd_create
  0.12    0.000012          12         1           ftruncate
  0.12    0.000012          12         1           fchmod
  0.12    0.000012          12         1         1 clone3
  0.11    0.000011          11         1           listen
  0.10    0.000010          10         1           set_tid_address
  0.09    0.000009           9         1           getsid
  0.09    0.000009           9         1         1 get_mempolicy
  0.09    0.000009           9         1           set_robust_list
  0.09    0.000009           9         1           getrandom
  0.08    0.000008           8         1           arch_prctl
  0.08    0.000008           8         1           rseq
  0.07    0.000007           7         1           lseek
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ------------------
100.00    0.009816          10       940        84 total

openatの呼び出しログからもICU探索ブロックが丸ごと消えています。

C# (AOT)

$ DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_csharp_aot 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
openat(AT_FDCWD, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 3
strace: Process 187 attached
[pid   186] openat(AT_FDCWD, "/sys/fs/cgroup//memory.max", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/proc/meminfo", O_RDONLY) = 3
[pid   186] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
strace: Process 188 attached
[pid   186] openat(AT_FDCWD, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   186] openat(AT_FDCWD, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 6
Hello, World
[pid   188] +++ exited with 0 +++
[pid   187] +++ exited with 0 +++
+++ exited with 0 +++

C# (JIT)のstraceログ全文(クリックで展開)

$ DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_csharp 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/", 0x7fff38292300, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
access("", F_OK)                        = -1 ENOENT (No such file or directory)
access("opt/coreservicing", F_OK)       = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
access("", F_OK)                        = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
strace: Process 128 attached
[pid   127] openat(AT_FDCWD, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 8
[pid   127] openat(AT_FDCWD, "/dev/urandom", O_RDONLY|O_CLOEXEC) = 9
[pid   127] openat(AT_FDCWD, "/proc/127/stat", O_RDONLY) = 10
strace: Process 129 attached
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 11
[pid   127] openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 11
[pid   127] openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 11
[pid   127] openat(AT_FDCWD, "/proc/127/stat", O_RDONLY) = 11
[pid   127] openat(AT_FDCWD, "/proc/127/stat", O_RDONLY) = 11
strace: Process 130 attached
[pid   130] openat(AT_FDCWD, "/tmp/clr-debug-pipe-127-2260796-in", O_RDONLYstrace: Process 131 attached
 <unfinished ...>
[pid   127] openat(AT_FDCWD, "/proc/127/stat", O_RDONLY) = 14
[pid   127] openat(AT_FDCWD, "/dev/shm/sem.clrst0000007f0000000000227f3c", O_RDWR|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/sys/fs/cgroup//memory.max", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/proc/meminfo", O_RDONLY) = 12
[pid   127] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12
[pid   127] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12
strace: Process 132 attached
[pid   127] openat(AT_FDCWD, "/proc/self/task/132/comm", O_RDWR) = 14
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 12
strace: Process 133 attached
[pid   127] openat(AT_FDCWD, "/proc/self/task/133/comm", O_RDWR) = 16
[pid   127] access("", F_OK)            = -1 ENOENT (No such file or directory)
[pid   127] access("opt/corebreadcrumbs", F_OK) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 14
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 16
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 18
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 20
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 22
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 25
strace: Process 134 attached
[pid   127] openat(AT_FDCWD, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   127] openat(AT_FDCWD, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 29
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 30
[pid   127] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 32
Hello, World
[pid   130] <... openat resumed>)       = ?
[pid   133] +++ exited with 0 +++
[pid   132] +++ exited with 0 +++
[pid   131] +++ exited with 0 +++
[pid   130] +++ exited with 0 +++
[pid   129] +++ exited with 0 +++
[pid   128] +++ exited with 0 +++
[pid   134] +++ exited with 0 +++
+++ exited with 0 +++

ICUバージョンを指定する

ICU探索が重いからと言って、グローバリゼーションを無効にしてもいいアプリケーションばかりではありません。当然多言語対応が必要な場合もあります。この場合、ICUライブラリバージョンを指定するか、アプリに同梱する手があります。DOTNET_ICU_VERSION_OVERRIDE=74でICUバージョンを指定でき、該当バージョンのICUライブラリだけを探索するようになります。この状態でstraceを取ると、C# AOT、JIT共にopenatが減っています。

  • C# (AOT): 全体の数が470から290 (無効だと228)へ、openatの数が129 (83)から35(7)(無効だと28 (7))へ減少
  • C# (JIT): 全体の数が1159から985 (無効だと940)へ、openatの数が163 (92)から82(28)(無効だと77 (28))へ減少

C# (AOT)

$ DOTNET_ICU_VERSION_OVERRIDE=74 strace -c ./bin/hello_csharp_aot
Hello, World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 22.68    0.000414           9        45           mmap
 13.86    0.000253           7        35         7 openat
 11.45    0.000209           7        27           mprotect
  7.07    0.000129           3        35           read
  5.37    0.000098           3        28           close
  5.37    0.000098           5        17           madvise
  5.26    0.000096           5        18           rt_sigaction
  5.15    0.000094           3        27           fstat
  4.66    0.000085          14         6           rt_sigprocmask
  3.67    0.000067          33         2           clone
  3.34    0.000061          10         6           munmap
  2.74    0.000050          12         4           ioctl
  2.03    0.000037          18         2           write
  1.48    0.000027           9         3           futex
  1.04    0.000019          19         1           pipe2
  0.77    0.000014           4         3           sched_getaffinity
  0.77    0.000014           3         4           prlimit64
  0.66    0.000012           4         3           pread64
  0.60    0.000011           2         4           brk
  0.55    0.000010          10         1           fcntl
  0.49    0.000009           9         1           lseek
  0.49    0.000009           3         3           getpid
  0.49    0.000009           9         1           gettid
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           sysinfo
  0.00    0.000000           0         2           statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1         1 get_mempolicy
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           getrandom
  0.00    0.000000           0         2           membarrier
  0.00    0.000000           0         1           rseq
  0.00    0.000000           0         1         1 clone3
------ ----------- ----------- --------- --------- ------------------
100.00    0.001825           6       290        10 total

C# (JIT)

$ DOTNET_ICU_VERSION_OVERRIDE=74 strace -c ./bin/hello_csharp
Hello, World
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 38.07    0.003370          10       322           mprotect
 16.23    0.001437           9       144           mmap
  9.27    0.000821          10        82        28 openat
  4.80    0.000425           7        55           read
  4.06    0.000359          51         7           clone
  3.66    0.000324           6        50           fstat
  3.28    0.000290          13        21           pread64
  2.64    0.000234           5        44           close
  2.04    0.000181           7        23           madvise
  2.01    0.000178           4        38        34 readlink
  1.86    0.000165          18         9           stat
  1.82    0.000161           7        21           munmap
  1.69    0.000150          18         8           write
  1.66    0.000147           6        22           fcntl
  1.60    0.000142           9        15           rt_sigprocmask
  1.17    0.000104           4        24           rt_sigaction
  1.01    0.000089           9         9           futex
  0.66    0.000058           5        10           brk
  0.59    0.000052          13         4           ioctl
  0.51    0.000045           9         5         2 unlink
  0.40    0.000035           3        10           prlimit64
  0.28    0.000025           5         5           getpid
  0.23    0.000020           5         4           sched_getaffinity
  0.21    0.000019           3         6         6 access
  0.14    0.000012           6         2           pipe2
  0.11    0.000010          10         1           lseek
  0.00    0.000000           0         1           socket
  0.00    0.000000           0         1           bind
  0.00    0.000000           0         1           listen
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           ftruncate
  0.00    0.000000           0         1           fchmod
  0.00    0.000000           0         2           sysinfo
  0.00    0.000000           0         1           getsid
  0.00    0.000000           0         2           sigaltstack
  0.00    0.000000           0         2           statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           gettid
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1         1 get_mempolicy
  0.00    0.000000           0         2           mknodat
  0.00    0.000000           0        16        12 newfstatat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           getrandom
  0.00    0.000000           0         1           memfd_create
  0.00    0.000000           0         4           membarrier
  0.00    0.000000           0         1           rseq
  0.00    0.000000           0         1         1 clone3
------ ----------- ----------- --------- --------- ------------------
100.00    0.008853           8       985        84 total

straceでopenatの呼び出しログを見ると、ICU探索ブロックが期待通り1つだけ存在し、ENOENTも発生していません。

$ DOTNET_ICU_VERSION_OVERRIDE=74 strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_csharp_aot
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
openat(AT_FDCWD, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 3
strace: Process 175 attached
[pid   174] openat(AT_FDCWD, "/sys/fs/cgroup//memory.max", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/proc/meminfo", O_RDONLY) = 3
[pid   174] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
strace: Process 176 attached
[pid   174] openat(AT_FDCWD, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   174] openat(AT_FDCWD, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.74", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicudata.so.74", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid   174] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicui18n.so.74", O_RDONLY|O_CLOEXEC) = 6
Hello, World
[pid   176] +++ exited with 0 +++
[pid   175] +++ exited with 0 +++
+++ exited with 0 +++

C# (JIT)のstraceログ全文(クリックで展開)

$ DOTNET_ICU_VERSION_OVERRIDE=74 strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_csharp 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/", {st_mode=S_IFDIR|0755, st_size=16384, ...}, 0) = 0
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v4/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v3/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/glibc-hwcaps/x86-64-v2/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v4/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v3/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/glibc-hwcaps/x86-64-v2/", 0x7fffa888a720, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
access("", F_OK)                        = -1 ENOENT (No such file or directory)
access("opt/coreservicing", F_OK)       = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 3
access("", F_OK)                        = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 3
openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 3
strace: Process 92 attached
[pid    91] openat(AT_FDCWD, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 8
[pid    91] openat(AT_FDCWD, "/dev/urandom", O_RDONLY|O_CLOEXEC) = 9
[pid    91] openat(AT_FDCWD, "/proc/91/stat", O_RDONLY) = 10
strace: Process 93 attached
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 11
[pid    91] openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY) = 11
[pid    91] openat(AT_FDCWD, "/proc/self/cgroup", O_RDONLY) = 11
[pid    91] openat(AT_FDCWD, "/proc/91/stat", O_RDONLY) = 11
[pid    91] openat(AT_FDCWD, "/proc/91/stat", O_RDONLY) = 11
strace: Process 94 attached
[pid    94] openat(AT_FDCWD, "/tmp/clr-debug-pipe-91-2255926-in", O_RDONLYstrace: Process 95 attached
 <unfinished ...>
[pid    91] openat(AT_FDCWD, "/proc/91/stat", O_RDONLY) = 14
[pid    91] openat(AT_FDCWD, "/dev/shm/sem.clrst0000005b0000000000226c36", O_RDWR|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/sys/fs/cgroup//memory.max", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/proc/meminfo", O_RDONLY) = 12
[pid    91] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12
[pid    91] openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12
strace: Process 96 attached
[pid    91] openat(AT_FDCWD, "/proc/self/task/96/comm", O_RDWR) = 14
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 12
strace: Process 97 attached
[pid    91] openat(AT_FDCWD, "/proc/self/task/97/comm", O_RDWR) = 16
[pid    91] access("", F_OK)            = -1 ENOENT (No such file or directory)
[pid    91] access("opt/corebreadcrumbs", F_OK) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 14
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 16
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 18
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 20
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 22
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 25
strace: Process 98 attached
[pid    91] openat(AT_FDCWD, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid    91] openat(AT_FDCWD, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 29
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 30
[pid    91] openat(AT_FDCWD, "/workspace/bin/hello_csharp", O_RDONLY) = 32
[pid    91] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    91] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicuuc.so.74", O_RDONLY|O_CLOEXEC) = 29
[pid    91] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicudata.so.74", O_RDONLY|O_CLOEXEC) = 29
[pid    91] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29
[pid    91] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libicui18n.so.74", O_RDONLY|O_CLOEXEC) = 29
Hello, World
[pid    94] <... openat resumed>)       = ?
[pid    97] +++ exited with 0 +++
[pid    96] +++ exited with 0 +++
[pid    95] +++ exited with 0 +++
[pid    94] +++ exited with 0 +++
[pid    93] +++ exited with 0 +++
[pid    92] +++ exited with 0 +++
[pid    98] +++ exited with 0 +++
+++ exited with 0 +++

ICUを指定するためには、対象環境に入っているICUライブラリのバージョンを知る必要があります。これはldconfig -pで確認できます。

$ ldconfig -p | grep -E 'libicu(uc|i18n)\.so' | head -n 50
        libicuuc.so.74 (libc6,x86-64) => /lib/x86_64-linux-gnu/libicuuc.so.74
        libicui18n.so.74 (libc6,x86-64) => /lib/x86_64-linux-gnu/libicui18n.so.74

あるいはアプリケーションでICUバージョンを指定できるので、いずれかを使うと良いでしょう。

InvariantCultureを使えればいいのですが、そうでない場合はICUバージョン指定で起動時間を改善できるのはなるほどです。

C# AOTのopenatシステムコール

他のopenat呼び出しも見てみましょう。straceログから、ICUを除いたopenatの呼び出しは以下だけに限定されています。2

  • /sys/devices/system/cpu/...
  • /proc/self/mountinfo, /proc/self/cgroup
  • /sys/fs/cgroup/.../cpu.max, memory.max
  • /proc/meminfo, /proc/self/maps
  • /dev/urandom
  • terminfo探索

他言語を見てみると、CとRustはlibcを通じて同様の情報を取得しているようです。Goはランタイムが独自に実装しているため、プロセスを複数生成して情報を集めています。こうやって見ると、C#の追加分は、いくつかシステムファイルを読んだり、icu、terminfoを読んだりしているためとわかります。

C

$ strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_c 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
Hello World
+++ exited with 0 +++

Rust

$ strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_rust 2>&1
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
Hello World
+++ exited with 0 +++

Go

$ strace -f -e trace=openat,newfstatat,access -s 200 ./bin/hello_go 2>&1
openat(AT_FDCWD, "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY) = 3
strace: Process 239 attached
strace: Process 240 attached
[pid   238] --- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=238, si_uid=0} ---
strace: Process 241 attached
strace: Process 242 attached
strace: Process 243 attached
Hello World
[pid   243] +++ exited with 0 +++
[pid   242] +++ exited with 0 +++
[pid   241] +++ exited with 0 +++
[pid   240] +++ exited with 0 +++
[pid   239] +++ exited with 0 +++
+++ exited with 0 +++

C#ランタイムが読むシステムファイルの意味

C#が/sys,/procを色々読んでいるのは、dotnetランタイムがコンテナ/CPU/メモリのチューニングに必要なためです。index4ENOENTなのは単にそのCPUにindex4が無いので、最後まで試しているだけです。環境検出(CPU/NUMA/キャッシュ)、制限検出(cgroup)、メモリ検出、乱数、Console(terminfo)の5系統しかなく、パスが固定なので、起動時決め打ちの必要な情報を取っているように見えます。

他言語より多いものの、むしろC/Rustは最低限の情報しか取っていないとも言えます。

コンテナリソース制限(cgroup)検出

これらはdotnetランタイムがコンテナ内のCPU quotaやメモリ上限を読むためのものです。実際、dotnetランタイムのGCはコンテナリソース制限を考慮して動作するため必要な情報です。

  • /proc/self/mountinfo
  • /proc/self/cgroup:
  • /sys/fs/cgroup/.../cpu.max
  • /sys/fs/cgroup/.../memory.max

CPU情報

CPUトポロジ/キャッシュ階層を取得しています。dotnetランタイムが、GCのセグメント/ヒープ構成やスレッドプールや初期パラメーターに必要な情報です。

  • /sys/devices/system/cpu/online
  • cpu0/cache/index*/{size,level}

メモリ情報・自己マップ

物理メモリ等、自プロセスのマップ(保護設定、診断、アンワインド/例外、スタック関連など)でランタイム起動時に必要な情報です。

  • /proc/meminfo
  • /proc/self/maps:

乱数

ハッシュのランダム化やセキュリティ機能のために乱数を取得します。

  • /dev/urandom

terminfo

TERM=dumbにしても1しか減らないことから、Console周りがterminfoをスキップしない、あるいはTERM=dumbでも最低限の確認をしているようです。terminfoで6回ENOENTが出ているのは嫌ですが、まぁ仕方ないでしょう。

  • ~/.terminfo/
  • /etc/terminfo/
  • /lib/terminfo/
  • /usr/share/terminfo

C#のwriteシステムコール

ここまでopenatを見てきましたが、writeシステムコールが他言語は標準出力の1回だけなのに対して、C# AOTは2回、JITは8回呼ばれています。これは割と特徴的なのでwriteシステムコールを深堀りしてみましょう。strace -e writeを実行した結果が以下です。

C

$ strace -e write ./bin/hello_c > /dev/null
write(1, "Hello World\n", 12)           = 12
+++ exited with 0 +++

Rust

$ strace -e write ./bin/hello_rust > /dev/null
write(1, "Hello World\n", 12)           = 12
+++ exited with 0 +++

Go

$ strace -e write ./bin/hello_go > /dev/null
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=5462, si_uid=0} ---
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=5462, si_uid=0} ---
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=5462, si_uid=0} ---
write(1, "Hello World\n", 12)           = 12
+++ exited with 0 +++

C# AOT

$ strace -e write ./bin/hello_csharp_aot > /dev/null
write(0, "\33[?1h\33=", 7)              = 7
write(3, "Hello, World\n", 13)          = 13
+++ exited with 0 +++

C# JIT

$ strace -e write ./bin/hello_csharp > /dev/null
write(13, "*", 1)                       = 1
write(14, ".NET Finalizer", 14)         = 14
write(13, "*", 1)                       = 1
write(16, ".NET Tiered Com", 15)        = 15
write(15, "*", 1)                       = 1
write(0, "\33[?1h\33=", 7)              = 7
write(24, "Hello, World\n", 13)         = 13
write(4, "\1", 1)                       = 1
+++ exited with 0 +++

C、Rust、Goは標準出力への1回のwriteだけですが、C# AOTでは端末制御シーケンスを書き込んでから標準出力へ書き込んでいます。JITではさらにソケット作成のため書き込みしています。C# AOTとJITを詳しく見てみましょう。

C# AOTのwriteシステムコール

straceのオプションを追加して、タイムスタンプ、File descriptor(FD)のパス、バッファ内容を表示します。

$ strace -f -ttt -e trace=write,writev -s 200 -yy -xx ./bin/hello_csharp_aot
strace: Process 13 attached
strace: Process 14 attached
[pid    12] 1770645277.828800 write(1<\x2f\x64\x65\x76\x2f\x70\x74\x73\x2f\x30<char 136:0>>, "\x1b\x5b\x3f\x31\x68\x1b\x3d", 7) = 7
[pid    12] 1770645277.830239 write(3<\x2f\x64\x65\x76\x2f\x70\x74\x73\x2f\x30<char 136:0>>, "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x0a", 13Hello, World
) = 13
[pid    14] 1770645277.830626 +++ exited with 0 +++
[pid    13] 1770645277.830656 +++ exited with 0 +++
1770645277.831918 +++ exited with 0 +++

$ strace -f -ttt -e trace=write,writev -s 200 -yy ./bin/hello_csharp_aot
strace: Process 31 attached
strace: Process 32 attached
[pid    30] 1770646142.571391 write(1</dev/pts/0<char 136:0>>, "\33[?1h\33=", 7) = 7
[pid    30] 1770646142.572052 write(3</dev/pts/0<char 136:0>>, "Hello, World\n", 13Hello, World
) = 13
[pid    32] 1770646142.573542 +++ exited with 0 +++
[pid    31] 1770646142.573563 +++ exited with 0 +++
1770646142.574448 +++ exited with 0 +++

1回目のwriteで端末のモード切り替え(ANSIエスケープ)を流し、それからFD 3へ"Hello, World\n"を書き込んでいます。FD 3はstraceの-yyオプションでパスを表示させたところ、/dev/pts/0となっており、標準出力が端末に接続されている場合に割り当てられる擬似端末デバイスです。つまり、C# AOTでは標準出力に直接書き込むのではなく、擬似端末デバイスに書き込んでから端末に出力していることになります。

1回目のwrite

端末のモード切り替えは以下の処理で、DECCKM: cursor keys modeDECKPAM(Keypad Application Modeを設定しています。

  • \x1b = ESC
  • \x1b\x5b\x3f\x31\x68 = ESC [ ? 1 h = DEC Private Mode Set 1 (DECCKM: cursor keys mode)
  • \x1b\x3d = ESC = DECKPAM(Keypad Application Mode)
write(1<\x2f\x64\x65\x76\x2f\x70\x74\x73\x2f\x30<char 136:0>>, "\x1b\x5b\x3f\x31\x68\x1b\x3d", 7) = 7

あるいは、エスケープシーケンスを可読化すると以下のようになります。

write(1</dev/pts/0<char 136:0>>, "\33[?1h\33=", 7) = 7

dotnet/runtimeのどこで処理されているかというと、src/libraries/System.Console/src/System/ConsolePal.Unix.csのEnsureConsoleInitialized関数にて、Interop.Sys.SetKeypadXmit(s_terminalHandle, keypadXmit);で端末のモード切替をしています。

private static unsafe void EnsureInitializedCore()
{
    lock (Console.Out) // ensure that writing the ANSI string and setting initialized to true are done atomically
    {
        if (!s_initialized)
        {
            // Do this even when redirected to make CancelKeyPress works.
            if (!Interop.Sys.InitializeTerminalAndSignalHandling())
            {
                throw new Win32Exception();
            }
            // InitializeTerminalAndSignalHandling will reset the terminal on a normal exit.
            // This also resets it for termination due to an unhandled exception.
            AppDomain.CurrentDomain.UnhandledException += (_, _) => { Interop.Sys.UninitializeTerminal(); };

            s_terminalHandle = !Console.IsOutputRedirected ? OpenStandardOutputHandle() :
                                !Console.IsInputRedirected  ? OpenStandardInputHandle() :
                                null;

            // Provide the native lib with the correct code from the terminfo to transition us into
            // "application mode".  This will both transition it immediately, as well as allow
            // the native lib later to handle signals that require re-entering the mode.
            if (s_terminalHandle != null &&
                TerminalFormatStringsInstance.KeypadXmit is string keypadXmit)
            {
                Interop.Sys.SetKeypadXmit(s_terminalHandle, keypadXmit);
            }

2回目のwriteはなぜFD3なのか

Hello, World\nを出力していますが、FD 3へ書き込んでいます。

write(3<\x2f\x64\x65\x76\x2f\x70\x74\x73\x2f\x30<char 136:0>>, "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x0a", 13Hello, World

エスケープシーケンスを可読化すると以下のようになります。

write(3</dev/pts/0<char 136:0>>, "Hello, World\n", 13Hello, World

CやRust、Goは標準出力FD 1へ直接書き込んでいるのに対して、C# AOTは擬似端末デバイスFD 3へ書き込んでいる点は不思議ですね。

# C
$ strace -f -ttt -e trace=write,writev -s 200 -yy ./bin/hello_c
write(1</dev/pts/0<char 136:0>>, "Hello World\n", 12Hello World

# Rust
$ strace -f -ttt -e trace=write,writev -s 200 -yy ./bin/hello_rust
write(1</dev/pts/0<char 136:0>>, "Hello World\n", 12Hello World

# Go
$ strace -f -ttt -e trace=write,writev -s 200 -yy ./bin/hello_go
write(1</dev/pts/0<char 136:0>>, "Hello World\n", 12Hello World

書き込みを追ってみましょう。

C# AOTのwriteシステムコール追跡 (クリックで展開)

$ strace -f -ttt -e trace=dup,dup2,dup3,fcntl,openat,close,write -s 200 -yy ./bin/hello_csharp_aot
1770646837.538617 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
1770646837.538979 close(3</etc/ld.so.cache>) = 0
1770646837.539104 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libm.so.6>
1770646837.539803 close(3</usr/lib/x86_64-linux-gnu/libm.so.6>) = 0
1770646837.539917 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libc.so.6>
1770646837.540707 close(3</usr/lib/x86_64-linux-gnu/libc.so.6>) = 0
1770646837.543771 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3</sys/devices/system/cpu/online>
1770646837.544000 close(3</sys/devices/system/cpu/online>) = 0
1770646837.544644 openat(AT_FDCWD</workspace>, "/proc/self/mountinfo", O_RDONLY) = 3</proc/137/mountinfo>
1770646837.545334 close(3</proc/137/mountinfo>) = 0
1770646837.545512 openat(AT_FDCWD</workspace>, "/proc/self/cgroup", O_RDONLY) = 3</proc/137/cgroup>
1770646837.545820 close(3</proc/137/cgroup>) = 0
1770646837.546360 openat(AT_FDCWD</workspace>, "/proc/self/mountinfo", O_RDONLY) = 3</proc/137/mountinfo>
1770646837.546940 close(3</proc/137/mountinfo>) = 0
1770646837.547053 openat(AT_FDCWD</workspace>, "/proc/self/cgroup", O_RDONLY) = 3</proc/137/cgroup>
1770646837.547324 close(3</proc/137/cgroup>) = 0
1770646837.547582 openat(AT_FDCWD</workspace>, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 3</sys/fs/cgroup/cpu.max>
1770646837.547895 close(3</sys/fs/cgroup/cpu.max>) = 0
strace: Process 138 attached
[pid   137] 1770646837.549562 openat(AT_FDCWD</workspace>, "/sys/fs/cgroup//memory.max", O_RDONLY) = 3</sys/fs/cgroup/memory.max>
[pid   137] 1770646837.549880 close(3</sys/fs/cgroup/memory.max>) = 0
[pid   137] 1770646837.550374 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index0/size>
[pid   137] 1770646837.550791 close(3</sys/devices/system/cpu/cpu0/cache/index0/size>) = 0
[pid   137] 1770646837.550911 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index0/level>
[pid   137] 1770646837.551252 close(3</sys/devices/system/cpu/cpu0/cache/index0/level>) = 0
[pid   137] 1770646837.551367 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index1/size>
[pid   137] 1770646837.551765 close(3</sys/devices/system/cpu/cpu0/cache/index1/size>) = 0
[pid   137] 1770646837.551889 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index1/level>
[pid   137] 1770646837.552238 close(3</sys/devices/system/cpu/cpu0/cache/index1/level>) = 0
[pid   137] 1770646837.552360 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index2/size>
[pid   137] 1770646837.552654 close(3</sys/devices/system/cpu/cpu0/cache/index2/size>) = 0
[pid   137] 1770646837.552790 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index2/level>
[pid   137] 1770646837.553103 close(3</sys/devices/system/cpu/cpu0/cache/index2/level>) = 0
[pid   137] 1770646837.553222 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index3/size>
[pid   137] 1770646837.553513 close(3</sys/devices/system/cpu/cpu0/cache/index3/size>) = 0
[pid   137] 1770646837.553629 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 3</sys/devices/system/cpu/cpu0/cache/index3/level>
[pid   137] 1770646837.553912 close(3</sys/devices/system/cpu/cpu0/cache/index3/level>) = 0
[pid   137] 1770646837.554043 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.555098 openat(AT_FDCWD</workspace>, "/proc/meminfo", O_RDONLY) = 3</proc/meminfo>
[pid   137] 1770646837.555372 close(3</proc/meminfo>) = 0
[pid   137] 1770646837.557397 openat(AT_FDCWD</workspace>, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3</proc/137/maps>
[pid   137] 1770646837.558138 close(3</proc/137/maps>) = 0
[pid   137] 1770646837.561204 fcntl(1</dev/pts/0<char 136:0>>, F_DUPFD_CLOEXEC, 0) = 3</dev/pts/0<char 136:0>>
strace: Process 139 attached
[pid   137] 1770646837.562720 openat(AT_FDCWD</workspace>, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.562981 openat(AT_FDCWD</workspace>, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.563093 openat(AT_FDCWD</workspace>, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.563212 openat(AT_FDCWD</workspace>, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.563341 openat(AT_FDCWD</workspace>, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.563475 openat(AT_FDCWD</workspace>, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.563648 openat(AT_FDCWD</workspace>, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 6</usr/share/terminfo/x/xterm>
[pid   137] 1770646837.564125 close(6</usr/share/terminfo/x/xterm>) = 0
[pid   137] 1770646837.564249 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.564534 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.564700 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.564886 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.565197 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.565444 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.565722 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.565980 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.566227 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.566497 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.566767 openat(AT_FDCWD</workspace>, "/lib/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.567001 openat(AT_FDCWD</workspace>, "/lib/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.567277 openat(AT_FDCWD</workspace>, "/lib/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.567554 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.567779 openat(AT_FDCWD</workspace>, "/usr/lib/glibc-hwcaps/x86-64-v4/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.567974 openat(AT_FDCWD</workspace>, "/usr/lib/glibc-hwcaps/x86-64-v3/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.568192 openat(AT_FDCWD</workspace>, "/usr/lib/glibc-hwcaps/x86-64-v2/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.568404 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.568702 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.569027 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.569146 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.569274 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.569402 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.569532 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.569740 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.570007 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.570137 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.570305 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.570443 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.570583 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.570792 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.571078 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.571184 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.571303 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.571408 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.571549 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.571828 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.572099 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.572216 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.572358 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.572511 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.572662 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.572861 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.573188 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.573420 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.573612 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.573790 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.574000 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.574299 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.574644 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.574781 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.574940 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.575085 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.575207 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.575539 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.575823 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.575963 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.576089 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.576212 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.576351 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.576564 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.576850 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.576976 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.577100 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.577265 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.577408 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.577682 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.578019 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.578130 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.578248 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.578374 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.578507 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.578751 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.579075 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.579186 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.579302 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.579457 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.579541 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.579801 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.580128 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.580244 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.580403 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.580520 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.580683 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.580877 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.581203 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.581383 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.581544 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.581703 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.581872 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.582150 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.582529 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.582696 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.582857 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.583033 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.583186 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.583474 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.583801 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.583913 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.584040 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.584172 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.584351 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.584607 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.584878 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.584988 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.585114 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.585244 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.585410 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   137] 1770646837.585664 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.585977 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.586087 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.74", O_RDONLY|O_CLOEXEC) = 6</usr/lib/x86_64-linux-gnu/libicuuc.so.74.2>
[pid   137] 1770646837.586809 close(6</usr/lib/x86_64-linux-gnu/libicuuc.so.74.2>) = 0
[pid   137] 1770646837.586925 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicudata.so.74", O_RDONLY|O_CLOEXEC) = 6</usr/lib/x86_64-linux-gnu/libicudata.so.74.2>
[pid   137] 1770646837.587485 close(6</usr/lib/x86_64-linux-gnu/libicudata.so.74.2>) = 0
[pid   137] 1770646837.587587 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 6</usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33>
[pid   137] 1770646837.588280 close(6</usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33>) = 0
[pid   137] 1770646837.588404 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 6</usr/lib/x86_64-linux-gnu/libgcc_s.so.1>
[pid   137] 1770646837.588959 close(6</usr/lib/x86_64-linux-gnu/libgcc_s.so.1>) = 0
[pid   137] 1770646837.590298 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6</etc/ld.so.cache>
[pid   137] 1770646837.590678 close(6</etc/ld.so.cache>) = 0
[pid   137] 1770646837.590820 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicui18n.so.74", O_RDONLY|O_CLOEXEC) = 6</usr/lib/x86_64-linux-gnu/libicui18n.so.74.2>
[pid   137] 1770646837.591551 close(6</usr/lib/x86_64-linux-gnu/libicui18n.so.74.2>) = 0
[pid   137] 1770646837.592432 write(1</dev/pts/0<char 136:0>>, "\33[?1h\33=", 7) = 7
[pid   137] 1770646837.592944 write(3</dev/pts/0<char 136:0>>, "Hello, World\n", 13Hello, World
) = 13
[pid   139] 1770646837.593311 +++ exited with 0 +++
[pid   138] 1770646837.593343 +++ exited with 0 +++
1770646837.594304 +++ exited with 0 +++

以下のfd=3はstdout(1)の複製(CLOEXEC付き)を示しており、dotnetランタイムは起動時にstdoutFD=1F_DUPFD_CLOEXECFD=3dup(close-on-exec 付き)していることが分かります。

fcntl(1</dev/pts/0<char 136:0>>, F_DUPFD_CLOEXEC, 0) = 3</dev/pts/0<char 136:0>>

dotnet/runtimeを確認すると、src/coreclr/pal/src/file/file.cppのinit_std_handle関数にて、以下のようにF_DUPFD_CLOEXECでdupしていることが分かります。コメントに元のFILE*(= stdoutなど)をfcloseしても、元のfd(1) を閉じないためにdupして別fdを持つと書かれているので、まさにstrace結果と一致します。

static HANDLE init_std_handle(HANDLE * pStd, FILE *stream)
{
    CPalThread *pThread = InternalGetCurrentThread();
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pFileObject = NULL;
    IPalObject *pRegisteredFile = NULL;
    IDataLock *pDataLock = NULL;
    CFileProcessLocalData *pLocalData = NULL;
    CObjectAttributes oa;

    HANDLE hFile = INVALID_HANDLE_VALUE;
    int new_fd = -1;

    /* duplicate the FILE *, so that we can fclose() in FILECloseHandle without
       closing the original */
    new_fd = fcntl(fileno(stream), F_DUPFD_CLOEXEC, 0); // dup, but with CLOEXEC
    if(-1 == new_fd)
    {
        ERROR("dup() failed; errno is %d (%s)\n", errno, strerror(errno));
        goto done;
    }

System.Nativeでも意図的にF_DUPFD_CLOEXECでdupしており、dotnetランタイム全体でこの方法を採用していることが分かります。

intptr_t SystemNative_Dup(intptr_t oldfd)
{
    int result;
#if HAVE_F_DUPFD_CLOEXEC
    while ((result = fcntl(ToFileDescriptor(oldfd), F_DUPFD_CLOEXEC, 0)) < 0 && errno == EINTR);
#elif HAVE_F_DUPFD
    while ((result = fcntl(ToFileDescriptor(oldfd), F_DUPFD, 0)) < 0 && errno == EINTR);
    // do CLOEXEC here too
    fcntl(result, F_SETFD, FD_CLOEXEC);
#else
    // The main use cases for dup are setting up the classic Unix dance of setting up file descriptors in advance of performing a fork. Since WASI has no fork, these don't apply.
    // https://github.com/bytecodealliance/wasmtime/blob/b2fefe77148582a9b8013e34fe5808ada82b6efc/docs/WASI-rationale.md#why-no-dup
    result = oldfd;
#endif
    return result;
}

int32_t SystemNative_Unlink(const char* path)
{
    int32_t result;
    while ((result = unlink(path)) < 0 && errno == EINTR);
    return result;
}

#ifdef __NR_memfd_create
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#endif
#ifndef MFD_ALLOW_SEALING
#define MFD_ALLOW_SEALING 0x0002U
#endif
#ifndef F_ADD_SEALS
#define F_ADD_SEALS (1024 + 9)
#endif
#ifndef F_SEAL_WRITE
#define F_SEAL_WRITE 0x0008
#endif
#endif

C# JITのwriteシステムコール

C# JITコンパイラが動作しているときのwriteシステムコールを見てみます。以下は、dotnet runでJITコンパイルを行いながらHello Worldを出力したときのstrace結果です。制御コードやHello Worldの出力回りはAOTと同様なのでおいておきましょう。

$ strace -e write ./bin/hello_csharp > /dev/null
write(13, "*", 1)                       = 1
write(14, ".NET Finalizer", 14)         = 14
write(13, "*", 1)                       = 1
write(16, ".NET Tiered Com", 15)        = 15
write(15, "*", 1)                       = 1
write(0, "\33[?1h\33=", 7)              = 7
write(24, "Hello, World\n", 13)         = 13
write(4, "\1", 1)                       = 1
+++ exited with 0 +++

気になるのが、.NET Finalizer.NET Tiered Comなどの文字列がwriteシステムコールです。これは.NETがスレッドを作って名前を付けているのがwrite()として見えています。Linuxのスレッド名は15文字まで(終端NULを含めて16バイト制限)なので、次のような名前になります。

  • .NET Finalizer: 14字なのでそのまま
  • .NET Tiered Com: .NET Tiered Compilationですが、先頭15文字だけなので切り詰められる

.NET FinalizerはGCのファイナライザースレッドであり、ランタイムとしていつでもファイナライズできる状態を作るために起動します。.NET Tiered CompilationはJITコンパイラのTiered PGO最適化を担当するスレッドです。なお、NativeAOTではJITがなく、またTiered PGO最適化は行われないため、これらスレッドは起動せずwriteシステムコールも発生しません。

この辺りはstraceでログを見ると、もう少し詳しくわかります。

C# JITのwriteシステムコールのstrace結果(クリックして展開)

$ strace -f -ttt -e trace=openat,close,fcntl,write -yy -s 200 ./bin/hello_csharp
1770651503.638424 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
1770651503.638872 close(3</etc/ld.so.cache>) = 0
1770651503.639013 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libdl.so.2>
1770651503.639668 close(3</usr/lib/x86_64-linux-gnu/libdl.so.2>) = 0
1770651503.639779 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/librt.so.1>
1770651503.640466 close(3</usr/lib/x86_64-linux-gnu/librt.so.1>) = 0
1770651503.640575 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libgcc_s.so.1>
1770651503.641275 close(3</usr/lib/x86_64-linux-gnu/libgcc_s.so.1>) = 0
1770651503.641383 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libpthread.so.0>
1770651503.642019 close(3</usr/lib/x86_64-linux-gnu/libpthread.so.0>) = 0
1770651503.642173 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libm.so.6>
1770651503.642672 close(3</usr/lib/x86_64-linux-gnu/libm.so.6>) = 0
1770651503.642775 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33>
1770651503.643511 close(3</usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33>) = 0
1770651503.643629 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/x86_64-linux-gnu/libc.so.6>
1770651503.644728 close(3</usr/lib/x86_64-linux-gnu/libc.so.6>) = 0
1770651503.659843 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
1770651503.660212 close(3</etc/ld.so.cache>) = 0
1770651503.660343 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.660624 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.660899 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.661116 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.661325 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.661507 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.661742 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.661973 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.662165 openat(AT_FDCWD</workspace>, "/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.662366 openat(AT_FDCWD</workspace>, "/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.662548 openat(AT_FDCWD</workspace>, "/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.662759 openat(AT_FDCWD</workspace>, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.662937 openat(AT_FDCWD</workspace>, "/usr/lib/glibc-hwcaps/x86-64-v4/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.663160 openat(AT_FDCWD</workspace>, "/usr/lib/glibc-hwcaps/x86-64-v3/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.663372 openat(AT_FDCWD</workspace>, "/usr/lib/glibc-hwcaps/x86-64-v2/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.663581 openat(AT_FDCWD</workspace>, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.663842 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
1770651503.664154 close(3</etc/ld.so.cache>) = 0
1770651503.664265 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.664416 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.664611 openat(AT_FDCWD</workspace>, "/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.664714 openat(AT_FDCWD</workspace>, "/usr/lib/liblttng-ust-tracepoint.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
1770651503.666744 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 3</workspace/bin/hello_csharp>
1770651503.667483 close(3</workspace/bin/hello_csharp>) = 0
1770651503.668334 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 3</workspace/bin/hello_csharp>
1770651503.668997 close(3</workspace/bin/hello_csharp>) = 0
1770651503.669736 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 3</workspace/bin/hello_csharp>
1770651503.670377 close(3</workspace/bin/hello_csharp>) = 0
1770651503.671028 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 3</workspace/bin/hello_csharp>
1770651503.671721 close(3</workspace/bin/hello_csharp>) = 0
1770651503.673748 openat(AT_FDCWD</workspace>, "/proc/self/mountinfo", O_RDONLY) = 3</proc/143/mountinfo>
1770651503.674430 close(3</proc/143/mountinfo>) = 0
1770651503.674546 openat(AT_FDCWD</workspace>, "/proc/self/cgroup", O_RDONLY) = 3</proc/143/cgroup>
1770651503.674831 close(3</proc/143/cgroup>) = 0
strace: Process 144 attached
[pid   143] 1770651503.677794 fcntl(0</dev/pts/0<char 136:0>>, F_DUPFD_CLOEXEC, 0) = 5</dev/pts/0<char 136:0>>
[pid   143] 1770651503.677926 fcntl(1</dev/pts/0<char 136:0>>, F_DUPFD_CLOEXEC, 0) = 6</dev/pts/0<char 136:0>>
[pid   143] 1770651503.678068 fcntl(2</dev/pts/0<char 136:0>>, F_DUPFD_CLOEXEC, 0) = 7</dev/pts/0<char 136:0>>
[pid   143] 1770651503.679079 openat(AT_FDCWD</workspace>, "/sys/fs/cgroup//cpu.max", O_RDONLY) = 8</sys/fs/cgroup/cpu.max>
[pid   143] 1770651503.679363 close(8</sys/fs/cgroup/cpu.max>) = 0
[pid   143] 1770651503.683922 openat(AT_FDCWD</workspace>, "/dev/urandom", O_RDONLY|O_CLOEXEC) = 9</dev/urandom<char 1:9>>
[pid   143] 1770651503.684119 openat(AT_FDCWD</workspace>, "/proc/143/stat", O_RDONLY) = 10</proc/143/stat>
[pid   143] 1770651503.684495 close(10</proc/143/stat>) = 0
strace: Process 145 attached
[pid   143] 1770651503.687465 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 11</sys/devices/system/cpu/online>
[pid   143] 1770651503.687648 close(11</sys/devices/system/cpu/online>) = 0
[pid   143] 1770651503.688005 openat(AT_FDCWD</workspace>, "/proc/self/mountinfo", O_RDONLY) = 11</proc/143/mountinfo>
[pid   143] 1770651503.688585 close(11</proc/143/mountinfo>) = 0
[pid   143] 1770651503.688690 openat(AT_FDCWD</workspace>, "/proc/self/cgroup", O_RDONLY) = 11</proc/143/cgroup>
[pid   143] 1770651503.688925 close(11</proc/143/cgroup>) = 0
[pid   143] 1770651503.691797 openat(AT_FDCWD</workspace>, "/proc/143/stat", O_RDONLY) = 11</proc/143/stat>
[pid   143] 1770651503.692066 close(11</proc/143/stat>) = 0
[pid   143] 1770651503.692179 openat(AT_FDCWD</workspace>, "/proc/143/stat", O_RDONLY) = 11</proc/143/stat>
[pid   143] 1770651503.692478 close(11</proc/143/stat>) = 0
strace: Process 146 attached
[pid   146] 1770651503.694266 openat(AT_FDCWD</workspace>, "/tmp/clr-debug-pipe-143-4092879-in", O_RDONLYstrace: Process 147 attached
 <unfinished ...>
[pid   143] 1770651503.695169 write(13<pipe:[654821]>, "*", 1) = 1
[pid   143] 1770651503.695294 openat(AT_FDCWD</workspace>, "/proc/143/stat", O_RDONLY <unfinished ...>
[pid   147] 1770651503.695332 close(12<pipe:[654821]> <unfinished ...>
[pid   143] 1770651503.695361 <... openat resumed>) = 14</proc/143/stat>
[pid   147] 1770651503.695388 <... close resumed>) = 0
[pid   147] 1770651503.695429 close(13<pipe:[654821]>) = 0
[pid   143] 1770651503.695560 close(14</proc/143/stat>) = 0
[pid   143] 1770651503.695670 openat(AT_FDCWD</workspace>, "/dev/shm/sem.clrst0000008f00000000003e73cf", O_RDWR|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.696489 openat(AT_FDCWD</workspace>, "/sys/fs/cgroup//memory.max", O_RDONLY) = 12</sys/fs/cgroup/memory.max>
[pid   143] 1770651503.696794 close(12</sys/fs/cgroup/memory.max>) = 0
[pid   143] 1770651503.697425 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index0/size", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index0/size>
[pid   143] 1770651503.697800 close(12</sys/devices/system/cpu/cpu0/cache/index0/size>) = 0
[pid   143] 1770651503.697912 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index0/level", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index0/level>
[pid   143] 1770651503.698353 close(12</sys/devices/system/cpu/cpu0/cache/index0/level>) = 0
[pid   143] 1770651503.698491 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index1/size", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index1/size>
[pid   143] 1770651503.698789 close(12</sys/devices/system/cpu/cpu0/cache/index1/size>) = 0
[pid   143] 1770651503.698909 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index1/level", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index1/level>
[pid   143] 1770651503.699260 close(12</sys/devices/system/cpu/cpu0/cache/index1/level>) = 0
[pid   143] 1770651503.699371 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index2/size", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index2/size>
[pid   143] 1770651503.699689 close(12</sys/devices/system/cpu/cpu0/cache/index2/size>) = 0
[pid   143] 1770651503.699824 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index2/level", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index2/level>
[pid   143] 1770651503.700127 close(12</sys/devices/system/cpu/cpu0/cache/index2/level>) = 0
[pid   143] 1770651503.700243 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index3/size", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index3/size>
[pid   143] 1770651503.700559 close(12</sys/devices/system/cpu/cpu0/cache/index3/size>) = 0
[pid   143] 1770651503.700679 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index3/level", O_RDONLY) = 12</sys/devices/system/cpu/cpu0/cache/index3/level>
[pid   143] 1770651503.700997 close(12</sys/devices/system/cpu/cpu0/cache/index3/level>) = 0
[pid   143] 1770651503.701105 openat(AT_FDCWD</workspace>, "/sys/devices/system/cpu/cpu0/cache/index4/size", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.702578 openat(AT_FDCWD</workspace>, "/proc/meminfo", O_RDONLY) = 12</proc/meminfo>
[pid   143] 1770651503.702830 close(12</proc/meminfo>) = 0
[pid   143] 1770651503.703978 openat(AT_FDCWD</workspace>, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12</proc/143/maps>
[pid   143] 1770651503.704811 close(12</proc/143/maps>) = 0
[pid   143] 1770651503.704991 openat(AT_FDCWD</workspace>, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 12</proc/143/maps>
[pid   143] 1770651503.706019 close(12</proc/143/maps>) = 0
strace: Process 148 attached
[pid   143] 1770651503.707664 openat(AT_FDCWD</workspace>, "/proc/self/task/148/comm", O_RDWR) = 14</proc/143/task/148/comm>
[pid   143] 1770651503.707795 write(14</proc/143/task/148/comm>, ".NET Finalizer", 14) = 14
[pid   143] 1770651503.707905 close(14</proc/143/task/148/comm>) = 0
[pid   143] 1770651503.708034 write(13<pipe:[656760]>, "*", 1) = 1
[pid   148] 1770651503.708204 close(12<pipe:[656760]>) = 0
[pid   148] 1770651503.708355 close(13<pipe:[656760]>) = 0
[pid   143] 1770651503.708851 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 12</workspace/bin/hello_csharp>
[pid   143] 1770651503.709311 fcntl(12</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.709529 fcntl(12</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 13</workspace/bin/hello_csharp>
strace: Process 149 attached
[pid   143] 1770651503.739900 openat(AT_FDCWD</workspace>, "/proc/self/task/149/comm", O_RDWR) = 16</proc/143/task/149/comm>
[pid   143] 1770651503.740087 write(16</proc/143/task/149/comm>, ".NET Tiered Com", 15) = 15
[pid   143] 1770651503.740251 close(16</proc/143/task/149/comm>) = 0
[pid   143] 1770651503.740380 write(15<pipe:[654827]>, "*", 1) = 1
[pid   149] 1770651503.740714 close(14<pipe:[654827]>) = 0
[pid   149] 1770651503.740860 close(15<pipe:[654827]>) = 0
[pid   143] 1770651503.759910 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 14</workspace/bin/hello_csharp>
[pid   143] 1770651503.760370 fcntl(14</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.760596 fcntl(14</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 15</workspace/bin/hello_csharp>
[pid   143] 1770651503.762460 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 16</workspace/bin/hello_csharp>
[pid   143] 1770651503.762883 fcntl(16</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.763136 fcntl(16</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 17</workspace/bin/hello_csharp>
[pid   143] 1770651503.769514 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 18</workspace/bin/hello_csharp>
[pid   143] 1770651503.770035 fcntl(18</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.770286 fcntl(18</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 19</workspace/bin/hello_csharp>
[pid   143] 1770651503.779217 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 20</workspace/bin/hello_csharp>
[pid   143] 1770651503.779738 fcntl(20</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.780015 fcntl(20</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 21</workspace/bin/hello_csharp>
[pid   143] 1770651503.786433 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 22</workspace/bin/hello_csharp>
[pid   143] 1770651503.786897 fcntl(22</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.787267 fcntl(22</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 23</workspace/bin/hello_csharp>
[pid   143] 1770651503.790962 fcntl(1</dev/pts/0<char 136:0>>, F_DUPFD_CLOEXEC, 0) = 24</dev/pts/0<char 136:0>>
[pid   143] 1770651503.799356 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 25</workspace/bin/hello_csharp>
[pid   143] 1770651503.799878 fcntl(25</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.800107 fcntl(25</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 26</workspace/bin/hello_csharp>
strace: Process 150 attached
[pid   143] 1770651503.804328 openat(AT_FDCWD</workspace>, "/root/.terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.805457 openat(AT_FDCWD</workspace>, "/root/.terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.805598 openat(AT_FDCWD</workspace>, "/etc/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.805738 openat(AT_FDCWD</workspace>, "/etc/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.805889 openat(AT_FDCWD</workspace>, "/lib/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.806050 openat(AT_FDCWD</workspace>, "/lib/terminfo/78/xterm", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.806268 openat(AT_FDCWD</workspace>, "/usr/share/terminfo/x/xterm", O_RDONLY|O_CLOEXEC) = 29</usr/share/terminfo/x/xterm>
[pid   143] 1770651503.807384 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 30</workspace/bin/hello_csharp>
[pid   143] 1770651503.807820 fcntl(30</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.808029 fcntl(30</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 31</workspace/bin/hello_csharp>
[pid   143] 1770651503.811379 openat(AT_FDCWD</workspace>, "/workspace/bin/hello_csharp", O_RDONLY) = 32</workspace/bin/hello_csharp>
[pid   143] 1770651503.811898 fcntl(32</workspace/bin/hello_csharp>, F_SETFD, FD_CLOEXEC) = 0
[pid   143] 1770651503.812202 fcntl(32</workspace/bin/hello_csharp>, F_DUPFD_CLOEXEC, 0) = 33</workspace/bin/hello_csharp>
[pid   143] 1770651503.819234 close(29</usr/share/terminfo/x/xterm>) = 0
[pid   143] 1770651503.821484 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.821744 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.821877 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.822027 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.822180 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.822296 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.90", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.822496 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.822790 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.822908 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.823061 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.823191 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.823323 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.89", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.823533 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.823862 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.823971 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.824115 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.824245 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.824350 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.88", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.824537 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.824873 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.824996 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.825210 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.825320 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.825400 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.87", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.825577 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.825921 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.826037 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.826181 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.826345 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.826517 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.86", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.826743 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.827013 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.827184 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.827308 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.827414 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.827546 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.85", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.827743 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.828080 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.828260 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.828410 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.828527 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.828655 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.84", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.828891 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.829219 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.829330 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.829457 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.829600 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.829721 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.83", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.829992 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.830294 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.830407 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.830538 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.830661 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.830761 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.82", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.830942 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.831250 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.831386 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.831513 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.831643 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.831818 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.81", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.832110 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.832416 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.832537 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.832691 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.832827 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.832943 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.80", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.833210 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.833542 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.833681 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.833836 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.833988 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.834114 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.79", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.834362 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.834618 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.834710 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.834952 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.835083 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.835207 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.78", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.835438 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.835794 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.835904 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.836046 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.836204 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.836366 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.77", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.836645 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.836936 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.837088 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.837257 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.837387 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.837559 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.76", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.837851 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.838170 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.838272 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.838409 openat(AT_FDCWD</workspace>, "/usr/lib/x86_64-linux-gnu/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.838562 openat(AT_FDCWD</workspace>, "/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.838724 openat(AT_FDCWD</workspace>, "/usr/lib/libicuuc.so.75", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid   143] 1770651503.838965 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.839287 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.839394 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicuuc.so.74", O_RDONLY|O_CLOEXEC) = 29</usr/lib/x86_64-linux-gnu/libicuuc.so.74.2>
[pid   143] 1770651503.840074 close(29</usr/lib/x86_64-linux-gnu/libicuuc.so.74.2>) = 0
[pid   143] 1770651503.840189 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicudata.so.74", O_RDONLY|O_CLOEXEC) = 29</usr/lib/x86_64-linux-gnu/libicudata.so.74.2>
[pid   143] 1770651503.840985 close(29</usr/lib/x86_64-linux-gnu/libicudata.so.74.2>) = 0
[pid   143] 1770651503.841575 openat(AT_FDCWD</workspace>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 29</etc/ld.so.cache>
[pid   143] 1770651503.841994 close(29</etc/ld.so.cache>) = 0
[pid   143] 1770651503.842160 openat(AT_FDCWD</workspace>, "/lib/x86_64-linux-gnu/libicui18n.so.74", O_RDONLY|O_CLOEXEC) = 29</usr/lib/x86_64-linux-gnu/libicui18n.so.74.2>
[pid   143] 1770651503.842904 close(29</usr/lib/x86_64-linux-gnu/libicui18n.so.74.2>) = 0
[pid   143] 1770651503.847992 write(1</dev/pts/0<char 136:0>>, "\33[?1h\33=", 7) = 7
[pid   143] 1770651503.848572 write(24</dev/pts/0<char 136:0>>, "Hello, World\n", 13Hello, World
) = 13
[pid   143] 1770651503.850376 write(4<pipe:[653798]>, "\1", 1) = 1
[pid   144] 1770651503.850599 close(4<pipe:[653798]>) = 0
[pid   146] 1770651503.851271 <... openat resumed>) = ?
[pid   150] 1770651503.851382 +++ exited with 0 +++
[pid   149] 1770651503.851403 +++ exited with 0 +++
[pid   148] 1770651503.851425 +++ exited with 0 +++
[pid   147] 1770651503.851445 +++ exited with 0 +++
[pid   146] 1770651503.851456 +++ exited with 0 +++
[pid   145] 1770651503.851479 +++ exited with 0 +++
[pid   144] 1770651503.856690 +++ exited with 0 +++
1770651503.856716 +++ exited with 0 +++

ログを見ているとclr-debug-pipeというパイプで診断情報をやり取りしていますが、これは診断用でDOTNET_EnableDiagnostics=0を指定すれば止められます。診断情報を止めた状態でstraceを取ると、clr-debug-pipeがなくなります。システムコール的には1つ減るだけですが、診断情報は不要なら止める判断もありでしょう。

$ DOTNET_EnableDiagnostics=0 strace -f -ttt -e trace=openat,close,fcntl,write -yy -s 200 ./bin/hello_csharp

まとめ

C#のstraceを追いかけてみましたが、面白かったです。こうやってみていくとstraceのシステムコールが少ないからよい、とは一概には言えないと感じます。

C#のdotnetランタイム(CoreCLR)は、GC最適化やJITコンパイラのために環境情報を収集しており、これにより実行時のパフォーマンスを向上させています。仮にdotnetランタイムが/proc/sysを見に行くシステムコールをしていない場合、それはGC、JITコンパイラのTiered PGO最適化、その他ランタイム最適化のための情報を取得できないことを意味します。CやRustのように、メモリ管理や最適化を手動で行う言語と異なり、C#などのマネージドランタイムは、ランタイムがシステムの状態を把握して最適化を行うことに依存しています。したがって、必要なシステムコールはある程度存在するでしょう。

一方で、C# AOTのシステムコールは起動時のシステムコールを最小限に抑えつつ、必要な最適化情報を取得するよう設計されています。straceで追いかけていて無駄だなーと感じるポイントが少なく、だいぶん頑張っているなーという印象です。このあたりは、AOTとJITの違いがよく出ていますね。

参考

元記事

本記事の再現をGitHub


  1. 共有ライブラリビルドをするには、go install -buildmode=shared stdが必要です。
  2. ちなみにDOTNET_EnableDiagnostics=0で診断系を止めても、strace上は変化がありません。



以上の内容はhttps://tech.guitarrapc.com/entry/2026/02/09/160000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14