コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2023年11月29日 >>> 2023年11月16日
link もっと後

2023年11月29日

newlib-4.3.0 for RISC-V 32bitのバグ

目次: RISC-V
目次: C言語とlibc

RISC-V用のツールチェーンを更新しているときに気づいたバグです。

現在の時刻を取得するgettimeofday()というAPIがあります。newlib-4.1.0ではSYS_gettimeofdayを使っていましたが、newlib-4.3.0ではSYS_clock_gettime64を使うように変更されました。が、これがバグっていました。

newlib-4.3.0のgettimeofday()の実装

// newlib-cygwin/libgloss/riscv/sys_gettimeofday.c

/* Get the current time.  Only relatively correct.  */
int
_gettimeofday(struct timeval *tp, void *tzp)
{
#if __riscv_xlen == 32
  struct __timespec64
  {
    int64_t tv_sec;         /* Seconds */
# if BYTE_ORDER == BIG_ENDIAN
    int32_t __padding;      /* Padding */
    int32_t tv_nsec;        /* Nanoseconds */
# else
    int32_t tv_nsec;        /* Nanoseconds */
    int32_t __padding;      /* Padding */
# endif
  };
  struct __timespec64 ts64;
  int rv;
  rv = syscall_errno (SYS_clock_gettime64, 2, 0, (long)&ts64, 0, 0, 0, 0);
  tp->tv_sec = ts64.tv_sec;
  tp->tv_usec = ts64.tv_nsec * 1000;    //★★計算式を間違えている、* 1000ではなく / 1000が正しい★★
  return rv;
#else
  return syscall_errno (SYS_gettimeofday, 1, tp, 0, 0, 0, 0, 0);
#endif
}

見ての通り、gettimeofdayは結果を秒(tv_sec)とマイクロ秒(tv_usec)のペアで返します。clock_gettime64は秒とナノ秒で結果を返してきますので、ナノ秒→マイクロ秒へ変換する必要があります。しかし悲しいことにナノ秒→マイクロ秒の変換コードがバグっており、マイクロ秒の値がかなり大きな値(本来1usなのに1msになってしまう(訂正: 1nsなのに1msになってしまう))になってしまいます。

長らく放置され、今日直っていた

実装変更がnewlibに入ったのは約2年前(2021年4月13日、commit id: 20d008199)でした。結構時間が経っていますね。先ほど紹介したgettimeofdayの実装はRISC-V 32bit向けの時しか使わないので、他のアーキを使っている開発者の皆様がバグに気づかなかったのだろうと思われます。

バグったコミット
commit 20d00819984058e439cfe40818f81d7315c89201
Author: Kito Cheng <kito.cheng@sifive.com>
Date:   Tue Apr 13 17:33:03 2021 +0800

    RISC-V: Using SYS_clock_gettime64 for rv32 libgloss.

     - RISC-V 32 bits linux/glibc didn't provide gettimeofday anymore
       after upstream, because RV32 didn't have backward compatible issue,
       so RV32 only support 64 bits time related system call.

     - So using clock_gettime64 call instead for rv32 libgloss.

このバグは既に下記のコミットで修正されています。

バグが修正されたコミット
commit 5f15d7c5817b07a6b18cbab17342c95cb7b42be4
Author: Kuan-Wei Chiu <visitorckw@gmail.com>
Date:   Wed Nov 29 11:57:14 2023 +0800

    RISC-V: Fix timeval conversion in _gettimeofday()

    Replace multiplication with division for microseconds calculation from
    nanoseconds in _gettimeofday function.

    Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>

コミットの日付を見てびっくりしたのですが、なんと今日のコミットです。きっと世界のどこかで私と同じようなことを調べ、なんじゃこりゃー?!とバグを見つけて直した人が居たんでしょう。やー、奇遇ですね……。

編集者:すずき(2023/12/04 00:39)

コメント一覧

  • 大山恵弘さん(2023/12/02 18:53)
    すずきさんのX(旧Twitter)へのポストを見て気づいた可能性もあるかもしれないと思っています.
    私はOSの時間管理に興味があるので時々gettimeofdayでエゴサーチをかけますが,そのエゴサーチで私はすずきさんのこのポストに気づきました.
    そして,これはすごいバグがみつかったと思っていたところでした.

    今回のfixを施したのは日本語を理解しない人かもしれませんが,当該ポストの画像を見れば何がまずいかはどの国の人にも一目瞭然だと思います.
  • すずきさん(2023/12/03 00:35)
    大山先生、お久しぶりです。コメントありがとうございます。

    gettimeofdayでエゴサーチ……!!さすがです、私はやったことがありませんでした。
    私がバグに気づいてnewlibのリポジトリをチェックしたとき、既に修正されていたので、本当にほぼ同時に気づいた(向こうの方が修正&ML投稿の時間分だけ早いですが)のだろうと思います。偶然ってすごいです。
  • hdkさん(2023/12/03 18:49)
    >(本来1usなのに1msになってしまう)

    1 nsが1 msになる、ですかね。本来の値の範囲を大幅に超えて桁溢れもおこしてしまいそうなバグですね...
  • すずきさん(2023/12/04 00:38)
    あ、そうか。1nsですね。ありがとうございます。
open/close この記事にコメントする



2023年11月28日

glibcのclone_threadが使うシステムコール

目次: C言語とlibc

RISC-V向けglibcの実装を眺めていたところ、2.37と2.38でスレッドを作成する関数(__clone_internal関数)が使っているシステムコールが変わっていることに気づきました。

スレッドを作成するcloneシステムコールにはいくつか亜種がありますが、大抵のアーキテクチャではcloneとclone3が実装されています。cloneは引数を値で渡します。clone3は構造体へのポインタと構造体のサイズを渡します。cloneの引数は非常に多く、しかも昔より増えているような気がします……。今後の拡張も考えれば引数の個数に制限がある値渡しよりも、構造体のポインタを渡したほうが合理的ですね。

実装は全アーキテクチャ共通で、下記のような感じです。struct clone_argsがclone3に渡す構造体です。__clone3_internal()はcl_argsを直接clone3システムコールに渡します。__clone_internal_fallback()はcl_argsの各フィールドをバラバラにしてcloneシステムコールに渡します。

glibc-2.38のcloneの実装

// glibc/sysdeps/unix/sysv/linux/clone-internal.c

int
__clone_internal (struct clone_args *cl_args,
		  int (*func) (void *arg), void *arg)
{
#ifdef HAVE_CLONE3_WRAPPER
  int saved_errno = errno;
  int ret = __clone3_internal (cl_args, func, arg);    //★★SYS_clone3を呼ぶ
  if (ret != -1 || errno != ENOSYS)
    return ret;

  /* NB: Restore errno since errno may be checked against non-zero
     return value.  */
  __set_errno (saved_errno);
#endif

  return __clone_internal_fallback (cl_args, func, arg);    //★★SYS_cloneを呼ぶ
}

これまで(2.37まで)のglibcのRISC-V向け実装でclone3システムコールが使われていなかった理由は、有効/無効のスイッチが無効側に設定されていたからです。スイッチとなるマクロ定義はsysdep.hというヘッダにあります。

clone3を使うか使わないかのスイッチ(RISC-V向け)

// glibc/sysdeps/unix/sysv/linux/riscv/sysdep.h

# define HAVE_CLONE3_WRAPPER		1

2.37まではHAVE_CLONE3_WRAPPERが未定義で、2.38ではHAVE_CLONE3_WRAPPERの定義が追加されました。以上が__clone_internal()が使っているシステムコールが変わる仕組みでした。良くできてます。

編集者:すずき(2023/11/30 22:46)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2023年11月25日

JTSA Limited大会参加2023

目次: 射的

JTSA Limitedの大会に参加しました。いつも使っているエアガンであるベレッタ92(東京マルイ、US M9)が大会の朝に壊れてしまい、急遽グロック17(東京マルイ、GLOCK 17 Gen.4)で参加するというトラブル付きです。にも関わらず、記録は絶好調で76.68秒の自己ベストが出ました。えー。


JTSA Limited練習会の記録

ダブルアクションのベレッタ92とシングルアクションのグロック17を比べれば、後者が有利なのはわかりますが、練習会で一度も出たことがない好タイムが大会本番の一発勝負で出るのはどういうことなんだ。うーん、普段の練習の意味とは一体……良い記録が出ただけに複雑な気分です……。

編集者:すずき(2024/06/22 17:31)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2023年11月24日

Linux JMプロジェクトとOSDNの崩壊

目次: Linux

OSDNがOSCHINAに売却された(「OSDN」が中国企業に買収〜日本のオープンソースプロジェクトホスティングサービス - 窓の杜)影響か、最近OSDNのWWWサーバーが応答しなくなりました。人によっては「ふーん、そうなん」で終わりですが、私は非常に困ることが1点あります。Linux JMが見えなくなったことです。

Linux JMとはLinuxのman(マニュアル、英語)を日本語訳して公開してくれている超ありがたいプロジェクトです。man形式だけでなくHTML形式も作成していて、同プロジェクトのサイトにて公開されています……いました。Linux JMおよび同サイトがOSDNでホスティングされているため、今回の騒動で見えなくなってしまいました。

私はmanpage + API名という雑な検索をしても、ほぼ一番最初に出てくるLinux JMを大変重宝しておりました。これが使えなくなるのは辛いよー……。

ソースコードリポジトリは公開されていますので、泣き言を言う暇があったら自分でHTMLに変換すれば良かろうって?全く持っておっしゃるとおりですね。やりましょう。

Linux JMプロジェクトのリポジトリ

リポジトリのアドレスはgit://git.osdn.net/gitroot/linuxjm/jm.gitです。OSDNのシステムをよく知りませんが、GitHubなどとは異なりHTTPSでcloneできるサーバーはなさそうな気配です。リポジトリは他に3つ存在しますが、いずれも過去の履歴を保持するために残されたリポジトリです。READMEファイル以外は何も入っていません。

  • git://git.osdn.net/gitroot/linuxjm/LDP_man-pages.git
  • git://git.osdn.net/gitroot/linuxjm/coreutils.git
  • git://git.osdn.net/gitroot/linuxjm/iptables.git

今回はこれらは使いませんので、リポジトリのアドレスを紹介するだけに留めます。

Linux JMプロジェクトのビルド

ビルドというほど大げさでもないですけど。apt-getなどでman2htmlをインストールした後に、下記を実行します。

Linux JMのビルド方法(HTMLファイルのみ)
$ git clone git://git.osdn.net/gitroot/linuxjm/jm.git
$ cd jm
$ make JMHOME=`pwd`/result MAN2HTML=/usr/bin/man2html html

成功するとJMHOMEで指定したディレクトリの下(result/htdocs/html)にHTMLファイルの入ったディレクトリが生成されます。この日記のサイトから読めるようにしておきます(一覧へのリンク)。右側のコンテンツメニューからも辿れるようにしました。

HTMLファイルだけでもマニュアルとしては十分ですが、白黒で目が痛いしデザインがそっけないです。デザインを変更するにはhtmlディレクトリと同列にjm.cssというファイルを置くと良いみたいです。リポジトリのwwwディレクトリ以下にある*.cssファイルを使うのが手っ取り早いでしょう。


CSS適用後の表示画面

いつもの見慣れたデザインになりました。黄色いデザインのイメージでしたが、デフォルトは青いみたいです。知りませんでした……。

一覧を見る方法

HTMLファイルが生成されたディレクトリを見ると、ツールの名前がついたディレクトリが延々と並んでいます。JavaDocのようなIndex HTMLを出力する機能はなさそうです。


ApacheのIndex表示でLinux JMの一覧を見る

とはいえさほど複雑な構造でもありませんし、わざわざ作らずともApacheのIndexes機能を開放するだけで十分でしょう。

検索が悩ましい

配置したLinux JMはとりあえず正常に読めるようになりました。Indexesも出せるようにしました。残る問題はGoogleが検索結果に出してくれるかどうかで、使い勝手という意味では割と大きい要素です。最初に紹介したように、私はmanpage + API名で検索してLinux JMが一番上に出る使い方に慣れきった軟弱者なので……他の文字を打たないと出ないなら使いにくいんです。

Googleはそのうちクロールしてくれると思うので、しばらく放置しようと思います。検索できるようになっても検索順位が低すぎるとか、どうにも使いにくかったらまた何か考えます。

編集者:すずき(2024/01/13 13:49)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2023年11月21日

musl libcのアトミックCAS実装

目次: C言語とlibc

OSSのlibc実装の一つであるmusl libcのアトミックCAS(Compare And Swap)の実装を調べたメモです。CASはa_cas(p, t, s)関数に実装されていて、ポインタpの指す先の値がtなら、アトミックにsと入れ替える関数です。調べるのはRISC-V用の実装です。

コンパイラが提供するアトミック関数実装(stdatomic.h)は使わないみたいです。musl libc独自の実装となっています。

musl libcのアトミックCAS実装

// musl/arch/riscv64/atomic_arch.h

#define a_cas a_cas
static inline int a_cas(volatile int *p, int t, int s)
{
	int old, tmp;
	__asm__ __volatile__ (
		"\n1:   lr.w.aqrl %0, (%2)\n"
		"       bne %0, %3, 1f\n"
		"       sc.w.aqrl %1, %4, (%2)\n"
		"       bnez %1, 1b\n"
		"1:"
		: "=&r"(old), "=&r"(tmp)
		: "r"(p), "r"((long)t), "r"((long)s)
		: "memory");
	return old;
}

RISC-V向けの実装はLR/SC(Load and Reserve, Store Conditional)という仕組みを使い実装されています。RISC-V以外のアーキテクチャでも良く見かける機能で、見たことある方も多いと思います。LRはLL(Load Link)という名前のこともあるようです。

コードはたった4行です、1行ずついきましょう。

  • 1行目: pの指す先を予約付きロードします。ロードした値は変数oldに格納されます。
  • 2行目: ロードした値がtでなければ終了します。
  • 3行目: ロードした値がtならばpの指す先にsを条件付きストアします。
  • 4行目: 条件付きストアが成功したら終了、失敗したら1行目に戻ります。

条件付きストアは、予約付きロードから条件付きストア間にpの指す先を誰も変更していない場合のみストアが成功します。pの指す先の値がsに変化します(tmpには0が返されます)。

もし予約付きロードから条件付きストアの間に誰かがpの指す先を変更していた場合はストアが失敗します。pの指す先の値は変化しません(tmpには0以外の値が返されます)。

編集者:すずき(2023/11/25 03:33)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2023年11月29日 >>> 2023年11月16日
link もっと後

管理用メニュー

link 記事を新規作成

<2023>
<<<11>>>
---1234
567891011
12131415161718
19202122232425
2627282930--

最近のコメント5件

  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」
  • link 24年10月1日
    hdkさん (10/03 08:30)
    「おー、面白いですね。xrdpはすでに立ち...」
  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」

最近の記事20件

  • link 24年10月31日
    すずき (11/04 15:17)
    「[DENSOの最終勤務日] 最終勤務日でした、入門カードや会社のPCを返却してきました。在籍期間はNSITEXE(品川のオフィ...」
  • link 22年7月8日
    すずき (11/02 20:34)
    「[マンガ紹介 - まとめリンク] 目次: マンガ紹介一覧が欲しくなったので作りました。5作品乙女ゲームの破滅フラグしかない悪役...」
  • link 24年10月30日
    すずき (11/02 20:33)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。最近完結した短めの作品を紹介します。マイナススキル持ち四人が...」
  • link 19年3月28日
    すずき (11/02 13:27)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。こわもてかわもて(全2巻、2019年)(アマゾンへのリンク)...」
  • link 21年6月20日
    すずき (11/02 13:22)
    「[読書一生分が93万円?] 目次: マンガ紹介書籍通販のhontoがこんなキャンペーンをやっています。honto読書一生分プレ...」
  • link 17年10月27日
    すずき (11/02 13:11)
    「[異世界&最強系漫画の種類] 目次: マンガ紹介少し前にアニメ化されて盛り上がって(おそらく負の方向に…)いた「...」
  • link 24年10月28日
    すずき (10/30 23:49)
    「[Linuxからリモートデスクトップ] 目次: Linux開発用のLinuxマシンの画面を見るにはいろいろな手段がありますが、...」
  • link 23年4月10日
    すずき (10/30 23:46)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年10月24日
    すずき (10/25 02:35)
    「[ONKYOからM-AUDIOのUSB DACへ] 目次: PCかれこれ10年以上(2013年3月16日の日記参照)活躍してく...」
  • link 24年7月25日
    すずき (10/25 02:24)
    「[OpenSBIを調べる - デバイスツリーの扱い(別方法)] 目次: LinuxOpenSBIのブート部分を調べます。Ope...」
  • link 24年8月7日
    すずき (10/25 02:23)
    「[Debian独自の挙動をするQEMUとbinfmt_misc] 目次: Linux前回はbinfmt_miscの使い方や動作...」
  • link 24年9月9日
    すずき (10/25 02:22)
    「[GDBの便利コマンド] 目次: LinuxGDBは便利ですが、少し使わないでいるとあっという間にコマンドを忘れます。便利&使...」
  • link 24年10月20日
    すずき (10/25 02:22)
    「[ゲームを買ったら遊びましょう2] 目次: ゲーム前回の振り返り(2022年5月13日の日記参照)から2年半経ちました。所持し...」
  • link 24年8月2日
    すずき (10/25 02:21)
    「[Debian on RISC-V] 目次: LinuxOpenSBI + Linuxの環境まで動いたので、次はLinuxのデ...」
  • link 24年8月6日
    すずき (10/25 02:21)
    「[他アーキテクチャ向けバイナリを実行する仕組みbinfmt_misc] 目次: LinuxRISC-V 64bit用の実行ファ...」
  • link 24年8月27日
    すずき (10/25 02:20)
    「[Milk-V Jupiterが届いた] 目次: RISC-VMilk-V Jupiterが届きました。お値段が非常に安かった...」
  • link 24年9月13日
    すずき (10/25 02:20)
    「[OpenSBIを調べる - OpenSBIとRISC-V ISA extensions] 目次: Linux今回はOpenS...」
  • link 24年10月11日
    すずき (10/25 02:19)
    「[企業のドメイン] 今の企業は公式サイトを持っていなほうが珍しいと思いますが、ドメイン名の使い方は各社でバラバラで面白いです。...」
  • link 24年10月21日
    すずき (10/25 02:18)
    「[OpenPilotを調べる - プロセス間通信msgqの仕組み] 目次: OpenPilot最近はOSSの運転支援ソフトウェ...」
  • link 24年10月6日
    すずき (10/25 02:11)
    「[OpenPilotを調べる - ビルドと実行] 目次: OpenPilot最近はOSSの運転支援ソフトウェアOpenPilo...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 11/04 15:17