目次: C言語とlibc
たまに最適化を無効にするとビルドできなくなるソフトウェアがあります。大抵はバグです。しかし何か目的があって、あえてやっている場合もあります。C言語標準ライブラリの実装で有名なglibcもその一つです。
最適化をわざと無効にしてglibcをビルドするとエラーが発生します。コードはglibc-2.35を使いました。
$ cd glibc $ mkdir _build $ cd _build $ ../configure CPPFLAGS="-O2 -g" --disable-sanity-checks $ make (成功する、ログは省略) $ cd ../ $ rm -rf _build $ mkdir _build $ cd _build $ ../configure CPPFLAGS="-O0 -g" --disable-sanity-checks $ make In file included from <command-line>: ./../include/libc-symbols.h:75:3: error: #error "glibc cannot be compiled without optimization" 75 | # error "glibc cannot be compiled without optimization" | ^~~~~
最適化を無効にするなと怒られました。コードを見ると__OPTIMIZE__ マクロの定義/未定義を見て検出していました。へえー。
// glibc/include/libc-symbols.h
/* Some files must be compiled with optimization on. */
#if !defined __ASSEMBLER__ && !defined __OPTIMIZE__
# error "glibc cannot be compiled without optimization"
#endif
このチェックをごまかして、最適化を有効にしつつも特定の最適化だけ無効にするとどうなるでしょう?
$ cd glibc $ mkdir __build $ cd __build $ ../configure CPPFLAGS="-O2 -g -fno-inline" --disable-sanity-checks --disable-werror $ make (...略...) gcc -nostdlib -nostartfiles -r -o glibc/__build/elf/librtld.os '-Wl,-(' glibc/__build/elf/dl-allobjs.os glibc/__build/elf/rtld-libc.a -lgcc '-Wl,-)' \ -Wl,-Map,glibc/__build/elf/librtld.os.map gcc -nostdlib -nostartfiles -shared -o glibc/__build/elf/ld.so.new \ -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -Wl,-z,defs \ glibc/__build/elf/librtld.os -Wl,--version-script=glibc/__build/ld.map \ -Wl,-soname=ld-linux-x86-64.so.2 \ -Wl,-defsym=_begin=0 /usr/bin/ld: glibc/__build/elf/librtld.os: in function `_dl_close_worker': glibc/elf/dl-close.c:383: undefined reference to `malloc' /usr/bin/ld: glibc/elf/dl-close.c:689: undefined reference to `free' /usr/bin/ld: glibc/elf/dl-close.c:691: undefined reference to `free' /usr/bin/ld: glibc/elf/dl-close.c:693: undefined reference to `free' /usr/bin/ld: glibc/elf/dl-close.c:701: undefined reference to `free' /usr/bin/ld: glibc/elf/dl-close.c:710: undefined reference to `free' /usr/bin/ld: glibc/__build/elf/librtld.os:glibc/elf/dl-close.c:715: more undefined references to `free' follow /usr/bin/ld: glibc/__build/elf/librtld.os: in function `_dl_map_object_deps': glibc/elf/dl-deps.c:438: undefined reference to `malloc' /usr/bin/ld: glibc/elf/dl-deps.c:479: undefined reference to `malloc' /usr/bin/ld: glibc/elf/dl-deps.c:571: undefined reference to `malloc' /usr/bin/ld: glibc/elf/dl-deps.c:543: undefined reference to `malloc' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `_dl_error_free': glibc/elf/dl-exception.c:41: undefined reference to `free' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `__GI__dl_exception_create': glibc/elf/dl-exception.c:89: undefined reference to `malloc' (...略...) /usr/bin/ld: glibc/elf/../sysdeps/posix/getcwd.c:249: undefined reference to `malloc' /usr/bin/ld: glibc/elf/../sysdeps/posix/getcwd.c:493: undefined reference to `free' /usr/bin/ld: glibc/elf/../sysdeps/posix/getcwd.c:469: undefined reference to `realloc' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `__alloc_dir': glibc/elf/../sysdeps/unix/sysv/linux/opendir.c:115: undefined reference to `malloc' /usr/bin/ld: glibc/elf/../sysdeps/unix/sysv/linux/opendir.c:115: undefined reference to `malloc' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `__closedir': glibc/dirent/../sysdeps/unix/sysv/linux/closedir.c:50: undefined reference to `free' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `scratch_buffer_free': glibc/malloc/../include/scratch_buffer.h:86: undefined reference to `free' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `__libc_scratch_buffer_set_array_size': glibc/malloc/scratch_buffer_set_array_size.c:51: undefined reference to `malloc' /usr/bin/ld: glibc/__build/elf/librtld.os: in function `__strdup': glibc/string/strdup.c:42: undefined reference to `malloc' collect2: error: ld returned 1 exit status make[2]: *** [Makefile:1234: glibc/__build/elf/ld.so] エラー1 make[2]: ディレクトリ 'glibc/elf' から出ます make[1]: *** [Makefile:483: elf/subdir_lib] エラー2 make[1]: ディレクトリ 'glibc' から出ます make: *** [Makefile:9: all] エラー2
リンク時に激しく怒られてしまいダメでした。小細工は効きませんね。
デバッグ時に見やすくするためにOgやO1といった最適化レベルを使うことは珍しくないと思いますが、glibcはOgやO1だとおかしなビルドエラーが発生します。
$ ../configure CPPFLAGS="-Og -g" --disable-sanity-checks (...略...) canonicalize.c: In function ‘realpath_stk’: canonicalize.c:424:50: error: ‘dest’ may be used uninitialized in this function [-Werror=maybe-uninitialized] 424 | return scratch_buffer_dupfree (rname_buf, dest - rname); | ~~~~~^~~~~~~ cc1: all warnings being treated as errors
警告がエラー扱いされただけなので、configureに --disable-werrorを渡して警告をエラーと見なさないようにするとビルドは成功します(実は前節でもしれっと使っていました)。
しかし良く考えるとO2では無警告なのにOgでは警告が出るとは?なかなか興味深い現象です。警告が出ているrealpath_stk() のコードを見ます。
// glibc/stdlib/canonicalize.c
static char *
realpath_stk (const char *name, char *resolved,
struct scratch_buffer *rname_buf)
{
char *dest;
char const *start;
char const *end;
int num_links = 0;
//...
struct scratch_buffer extra_buffer, link_buffer;
scratch_buffer_init (&extra_buffer);
scratch_buffer_init (&link_buffer);
scratch_buffer_init (rname_buf);
char *rname_on_stack = rname_buf->data;
char *rname = rname_on_stack;
bool end_in_extra_buffer = false;
bool failed = true;
/* This is always zero for Posix hosts, but can be 2 for MS-Windows
and MS-DOS X:/foo/bar file names. */
idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
if (!IS_ABSOLUTE_FILE_NAME (name)) //★★この条件が成立、かつ★★
{
while (!__getcwd (rname, rname_buf->length)) //★★この条件が成立、かつ★★
{
if (errno != ERANGE) //★★この条件が不成立、かつ★★
{
dest = rname;
goto error;
}
if (!scratch_buffer_grow (rname_buf)) //★★この条件が成立した場合を考えると★★
goto error_nomem; //★★destが未定義のまま、このgotoに到達する★★
rname = rname_buf->data;
}
dest = __rawmemchr (rname, '\0');
start = name;
prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
}
//...
error_nomem:
scratch_buffer_free (&extra_buffer);
scratch_buffer_free (&link_buffer);
if (failed || rname == resolved) //★★しかし、前半のfailed = trueの条件が必ず成立していて、未定義変数の使用は発生しない★★
{
scratch_buffer_free (rname_buf);
return failed ? NULL : resolved;
}
return scratch_buffer_dupfree (rname_buf, dest - rname); //★★ここで未定義変数の使用の警告が出る★★
}
コード上はdestが未定義のまま使われる可能性があるように見えますし、Ogの警告はもっともに思えます。しかしコードを良く見るとdestが未定義のままerror_nomemに来る場合、failed = trueが必ず成立して警告が出る行には到達しません。他にもgoto error_nomemする箇所はありますが、同様に必ずfailed = trueが成立します。
O2だとif文は必ず成立する場合(異常パス)と、しない場合(正常パス)でコードが複製されるようです。if文が成立する側のコードでは、if文の後は不要 = 未使用コードを消去 = dest - rnameというコードそのものがなかったことになる、というメカニズムが働いて警告が出ないのでしょう。たぶん。
GCCの警告は大体合っていますが、これはコンパイラが誤警告を出してしまうちょっと珍しい例でした。個人的には紛らわしいコードを書くんじゃねえ!と思いますが、歴史あるコードですし……何か理由があってこうなっているんでしょう。
遊ばずに放置していたTimberbornをしばらくやっていました。まだ発展途上のEarly Access版でもありますし、私の遊び方が良くないのもありそうですが、ゲームの前半は非常に面白いのですが、後半がダレ気味です。
前半はいかに効率よく水を確保してビーバー達を救うかがキモです。水源開発(ダムなど)を優先しすぎると容易に木材、食料、住宅不足に陥って街の開発が詰んでしまいます。かといって街の開発を優先しすぎると、水が足りなくなってビーバー達が干からびて死んでしまいます。
この辺りのバランスの取り方が難しくも面白いです。干ばつまでの時間と戦いつつ街もダムも拡張させる、ギリギリの街作りを進める楽しさがあります。
しかし一度でも最長期間の干ばつ(Normal難易度なら9日間)に耐えられる街ができると、非常に安定してしまい、人口を極端に変えない限りはやることがなくなります。特にダイナマイト量産に成功した後は「山崩しゲーム」と化します。
これが延々と続きます。広いマップの巨大な山を切り崩すのは辛いんで、とりあえず一番狭いDiorama(50x50)マップを使い、山を2つ(右の山と、左の手前の小さい山)ほど潰して更地にしてみました。こんな小さい山を潰すだけでもかなり時間が掛かります。ひたすらダルいです。
最後の山も残っていますが……もういいや……。
メモ: 技術系?の話はFacebookから転記しておくことにした。加筆。
奥さんと銀座のSUPER HOTELに来ました。現在SUPER HOTELと進撃の巨人がコラボしていて、泊まるとノベルティが1人1つ貰えるそうです。ノベルティは全部で2種類あり、両方欲しいので2人で泊まりたかったんですって。へー。
部屋にはタブレットとテレビがありました。タブレットはONKYO TA2C-74Z8Aという古い業務用のタブレットでした。Atom機でx86 Androidです。バージョンはAndroid 5.1とかなり古いですね。
戻るボタン、ホームボタンは画面に出せますが、ホームアプリが差し替えられているため基本的には他のアプリは起動しません。
さらにPerfect AppLockなるロックアプリが入っています。通知バーから設定アプリを起動しようとするなど、ホテル業務と関係ないアプリを起動しようとすると妨害されるようです。デフォルトのホームアプリ(Launcher3)はなぜか起動妨害対象に入っておらず、ロックアプリのアイコンが拝めます。
これ以上は何も弄れませんでしたと言いたいところですが、このロックアプリはバグってるみたいで、画面遷移の瞬間に連打するとロックの設定を削除できてしまいました。名前に反して全然パーフェクトじゃないんだが……??設定アプリも拝めましたし、開発者モードもONにできました。ここまで到達できるならadbを繋ぎたかったですね。パソコンを持ってこなかったのが惜しまれます。
タブレットはこれくらいにして、テレビを見ると普通のブラビア(SONY KJ-49X8000E)でした。
サイドの木箱にSTBが隠してありました、業務用のSTB + 普通のテレビというホテルではありがちな構成ですね。残念なことにリモコンはSTB用のリモコンしかなく、ブラビアのリモコンは見あたりませんでした。
おかげでブラビアのメニュー画面が出せなくて特に何も弄れませんでした。つまんないですね……。
メモ: 技術系の話はFacebookから転記しておくことにした。加筆、写真追加。
目次: 射的
秋葉原のトリガーハッピーでシューティングレンジに3回目のチャレンジ。7mくらい先の的9個を撃つゲームです。
前回はアベレージ15秒、ベスト12秒くらい、今回はアベレージ13〜14秒、ベスト10秒くらいでした。一度だけマグレで8秒台が出ましたが、その後は二度と10秒を切ることはありませんでした。
前回はダブルアクションで1発目がブレがちなベレッタ92だったので、今回はグロック19で挑みました。グロック系はセーフティー操作が不要(トリガーセーフティーのみ)で扱いが楽ですね。
構え方の問題なのか、狙いを上下に移動させたときに外しやすいようです。サイトは同じように狙っているつもりなんですが、ズレてる?難しいなー。
スチールチャレンジやアンリミテッドシューティングチャレンジであれば、下記のようなルールのためセーフティー操作とタイムはダイレクトに影響するはずです。
シューティングバーでやるような射的はノールールです。ホルスターなんて持って行きませんし、セーフティー解除してから撃ち始めますからセーフティー操作とタイムもほとんど関係ありません。超適当です。当たる、楽しい!で良いのだ!
エアガンを使った趣味として代表的なモノはサバゲー(サバイバルゲーム)です。サバゲーはやったことありませんが、みなさんでワイワイやるのは楽しそうです。難点は何だろうな?フィールドで移動する最低限の体力が必要ですね。あとは相手に撃たれたら痛いくらい……?
シューティングはほぼ動きませんし撃たれません。シューティング大会に出るなどのガチ系の人は別として、他人の動向を気にする必要はなくて気楽です。難点は何だろうな。
ランニングコストに関してはバカスカ撃たなければ常識の範囲内だと思いますし、もし多人数で交流したいなら練習会に行くのも良いでしょう。
私にとっては一生モノの気楽に遊べる趣味にできそうです。
目次: Kindle
Kindleの純正ケースは、画面のカバー+スタンド機能を備えたナイスなタブレットケースです。カバーを半分に曲げることで足の代わりにし、タブレットを支えることができます。
Kindle Fire HD 10(第七世代)の純正ケース&スタンド
スタンド機能は愛用していたのですが、ついに経年劣化で壊れてきたようで勝手に倒れてしまうことが増えました。5年も頑張ってくれましたし良く保った方だと言えるでしょう。
代わりとしてタブレットスタンドを買いました。サンワサプライPDA-STN11BK(メーカーのサイト)です。Amazonで2,000円くらい?だったと思います。スタンドとして安定しているのはもちろんのこと、角度が調整できる点が非常に便利です。Kindle純正ケースのスタンド機能も良いものでしたが、やはり専門のスタンドには敵いませんね。
残念なことに他社タブレットはカバー+スタンド機能付きタブレットケースが用意されていないことが多く、Kindleから買い換える際に困っていたのです。が、今回の一件でカバーはカバー、スタンドはスタンドで別にしても全く問題ないことがわかりました。これで買い換えの敷居がかなり下がりましたね……。うーむ?買い換えるか??
< | 2022 | > | ||||
<< | < | 04 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
合計:
本日: