コグノスケ


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

link もっと前
2025年6月1日 >>> 2025年5月19日
link もっと後

2025年5月25日

JTSA Unlimited大会参加2025

目次: 射的

JTSA Unlimitedの大会に参加しました。

「木」ステージが大失敗、「水」もダメダメで、高速ステージの「土」もいまいち振るわず、結果は75.69秒(前回は76.75秒)でした(総合82位/113人、LM 12位/21人)。70秒台前半くらいを出したかったけど無念ですね。


JTSA Unlimited練習会+大会の記録

練習会の記録を見ると自己ベストは65.81秒ですが、その後はほとんど60秒台が出ないところをみると、75〜70秒くらいが実力と思われます。最近はあまり上達している感じがしません。そろそろ週1練習の限界かもしれませんが、今後もゆるゆると続けていきます。

編集者:すずき(2025/05/25 21:53)

コメント一覧

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



2025年5月24日

メガネが壊れた

金曜日、メガネの鼻当てが曲がってんなー?と思って、元の位置に戻そうと指で押したらパキっと音がして折れました。なにーー!?メガネの固定が甘くなって激しい動き、例えば走ったり階段の上り下りをすると、メガネが上下に揺れて視界がグワングワンします、目が回ります……。


メガネの鼻当てが折れた

直近で一番困ったのは、明日のシューティング大会JTSA Unlimitedです。サブのメガネもないし、メガネ外したら的が見えないですから、壊れたメガネのまま参加するしかありません。不幸中の幸いか、JTSA Unlimitedはアクションなし=その場から動かないで撃つタイプなのでメガネが揺れてどうこうなることはありません。

今日のシューティング練習会で試した限りでも、視界に大きな影響はなかったですし壊れたメガネで参加してきます。

編集者:すずき(2025/05/25 22:25)

コメント一覧

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



2025年5月23日

デバッグ用のlibcを使って実行する方法(ダイナミックリンク編)

目次: C言語とlibc

Cライブラリのデバッグをしたいときはあまりないと思いますが、Cライブラリにデバッグ情報やprintを追加して実行する方法を紹介します。今回使用するのはDebian Testingが採用しているglibc-2.40です。

システムにインストールされているバージョンと同じにしないと動作しないと思います。システムにインストールされているCライブラリの確認方法、ビルド方法は前回の日記(2025年5月22日の日記参照)と同様です。ソースコードは~/work/の下にあるとします。

Cライブラリをビルドしたら、テストプログラムをビルドします。スタティックリンクのときとは異なり-Lオプションは指定しません。ビルドは通常と一緒で、実行時にライブラリを差し替えるからです。-Dオプションには先程改変したpthread_sigmask()を呼ぶためのコンパイルスイッチを指定します。

ダイナミックリンク
$ gcc -g -O2 -Wall -DUSE_PTHREADSIGMASK test.c

実行すると追加したhogeが出力されるはずです。

テストプログラムを実行(ダイナミックリンク版)
$ LD_PRELOAD=~/work/glibc/__build/libc.so ./a.out

Use pthread_sigmask
th  0: sub  (child ) thread start
th  0: pthread_sigmask(block)
th  1: sub  (child ) thread start
th  1: pthread_sigmask(block)
hoge
th  2: sub  (child ) thread start
th  2: pthread_sigmask(block)
hoge
hoge
th  3: sub  (child ) thread start
th  3: pthread_sigmask(block)
th  4: main (parent) thread start
th  4: pthread_sigmask(block)
hoge
hoge
th  3: loop start
th  4: loop start
th  2: loop start
th  0: loop start
th  1: loop start

デバッグしてみましょう。

テストプログラムをデバッグ(ダイナミックリンク版)
$ gdb ./a.out

(gdb) set env LD_PRELOAD ~/work/glibc/__build/libc.so
(gdb) b pthread_sigmask
(gdb) run

Thread 2 "a.out" hit Breakpoint 2, __GI___pthread_sigmask (how=0,
    newmask=0x7ffff7dd2da0, oldmask=0x7ffff7dd2e20) at pthread_sigmask.c:29
29        printf("hoge\n");

(gdb) bt
#0  __GI___pthread_sigmask (how=0, newmask=0x7ffff7dd2da0,
    oldmask=0x7ffff7dd2e20) at pthread_sigmask.c:29
#1  0x00005555555555e3 in thread_main (arg=0x7fffffffc880)
    at signal_thread.cpp:81
#2  0x00007ffff7e63332 in start_thread (arg=<optimized out>)
    at pthread_create.c:447
#3  0x00007ffff7edede8 in __GI___clone3 ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

環境変数を設定して実行すると、ソースコードが表示されること、先程追加したprintf()が見えることも確認できました。ダイナミックリンクもうまくいっていそうです。

編集者:すずき(2025/05/23 22:30)

コメント一覧

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



2025年5月22日

デバッグ用のlibcを使って実行する方法(スタティックリンク編)

目次: C言語とlibc

Cライブラリのデバッグをしたいときはあまりないと思いますが、Cライブラリにデバッグ情報やprintを追加して実行する方法を紹介します。今回使用するのはDebian Testingが採用しているglibc-2.40です。

バージョンはよほど古いバージョンでなければ動くと思いますが、最初はシステムにインストールされているバージョンと同じにしたほうがトラブルが少ないと思います。システムにインストールされているCライブラリの確認方法はディストリビューションによって違いますが、DebianやUbuntuならば下記のように確認できます。

インストールされているCライブラリのバージョン確認
$ dpkg -l libc6:amd64

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name            Version      Architecture Description
+++-===============-============-============-=================================
ii  libc6:amd64    2.40-7       amd64        GNU C Library: Shared libraries

バージョンは2.40でした。次にglibc-2.40のソースコードをもってきてビルドします。ソースコードは~/work/の下にあるとします。

glibcのソースコードを取得&ビルド
$ git clone git://sourceware.org/git/glibc.git
$ cd glibc
$ git checkout glibc-2.40

$ mkdir build
$ cd build
$ ../configure --disable-sanity-checks --enable-debug
$ make -j16

実行したときに自分でビルドしたライブラリかどうか簡単にわかるようにpthread_sigmask()にprintf()を追加してからビルドします。

pthread_sigmaskにprint文を追加

$ git diff

diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c
index a39f3ca335..4c725592b6 100644
--- a/nptl/pthread_sigmask.c
+++ b/nptl/pthread_sigmask.c
@@ -19,12 +19,14 @@
 #include <pthreadP.h>
 #include <sysdep.h>
 #include <shlib-compat.h>
+#include <stdio.h>

 int
 __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
 {
   sigset_t local_newmask;

+  printf("hoge\n");
   /* The only thing we have to make sure here is that SIGCANCEL and
      SIGSETXID is not blocked.  */
   if (newmask != NULL

ビルドしたglibcとテストプログラムをスタティックリンクします。-Lオプションには先程glibcをビルドしたディレクトリを指定し、-Dオプションには先程改変したpthread_sigmask()を呼ぶためのコンパイルスイッチを指定します。テストプログラムは以前紹介したものです(2025年5月12日の日記参照)。

スタティックリンク
$ g++ -g -O2 -Wall -static -L ~/work/glibc/build -DUSE_PTHREADSIGMASK 20250512_signal_thread.cpp

実行すると追加したhogeが出力されるはずです。

テストプログラムを実行
$ ./a.out

Use pthread_sigmask
th  0: sub  (child ) thread start
th  0: pthread_sigmask(block)
hoge
th  1: sub  (child ) thread start
th  1: pthread_sigmask(block)
hoge
th  2: sub  (child ) thread start
th  2: pthread_sigmask(block)
hoge
th  4: main (parent) thread start
th  4: pthread_sigmask(block)
th  3: sub  (child ) thread start
th  3: pthread_sigmask(block)
hoge
hoge
th  4: loop start
th  1: loop start
th  3: loop start
th  2: loop start
th  0: loop start

最後にデバッグしてソースコードが表示されるか試しましょう。

テストプログラムをデバッグ
$ gdb a.out

(gdb) b pthread_sigmask
(gdb) run

Thread 2 "a.out" hit Breakpoint 1, __pthread_sigmask (how=0,
    newmask=0x7ffff7ff7120, oldmask=0x7ffff7ff71a0) at pthread_sigmask.c:29
29        printf("hoge\n");

(gdb) bt
#0  __pthread_sigmask (how=0, newmask=0x7ffff7ff7120, oldmask=0x7ffff7ff71a0)
    at pthread_sigmask.c:29
#1  0x0000000000401c43 in thread_main (arg=0x7fffffffc900)
    at signal_thread.cpp:81
#2  0x00000000004109cf in start_thread (arg=<optimized out>)
    at pthread_create.c:447
#3  0x0000000000422968 in __clone3 ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

ソースコードが表示されること、先程追加したprintf()が見えることも確認できました。良さそうです。

編集者:すずき(2025/05/23 22:21)

コメント一覧

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



2025年5月20日

glibcのsigprocmask()とpthread_sigmask()の実装

目次: C言語とlibc

以前、シグナルマスク(sigprocmaskのマニュアル)の「規定されていない」使い方をするとどうなるか?を見ました。前回までに確認したことは、5つのマルチスレッド(親スレッド+4つの子スレッド)で全員でsigwait()するのは共通で、誰がsigprocmask()を呼ぶか?を変えながら、下記4パターンを試しました。

  • 最初のスレッドがsigprocmask()
  • 最初のスレッド「以外」の1スレッドがsigprocmask()
  • 全スレッドがsigprocmask()
  • 全スレッドがpthread_sigmask()

結果は1と2はabortし、4は「正しい方法」なので正しく動くとして、なぜか3も正しく動いていました。予想としてはsigprocmask()とpthread_sigmask()は実装が似ていて偶然こうなるのでしょう。

やっと本題

今回はGNU libc(glibc-2.41)のソースコードを確認して予想の答え合わせをします。繰り返しますが、マルチスレッドでsigprocmask()未定義動作なので3番の方法が正しく動く保証はないし、将来実装が変わって動かなくなる可能性があります。

まずpthread_sigmask()のコードを見ます。pthreadの制御に使うシグナルのマスクを消して、rt_sigprocmaskシステムコールを呼ぶだけです。

glibcのpthread_sigmask()の実装

// glibc/nptl/pthread_sigmask.c

int
__pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
{
  sigset_t local_newmask;

  /* The only thing we have to make sure here is that SIGCANCEL and
     SIGSETXID is not blocked.  */
  if (newmask != NULL
      && (__glibc_unlikely (__sigismember (newmask, SIGCANCEL))
         || __glibc_unlikely (__sigismember (newmask, SIGSETXID))))
    {
      local_newmask = *newmask;
      clear_internal_signals (&local_newmask);
      newmask = &local_newmask;
    }

  /* We know that realtime signals are available if NPTL is used.  */
  int result = INTERNAL_SYSCALL_CALL (rt_sigprocmask, how, newmask,
				      oldmask, __NSIG_BYTES);

  return (INTERNAL_SYSCALL_ERROR_P (result)
	  ? INTERNAL_SYSCALL_ERRNO (result)
	  : 0);
}
libc_hidden_def (__pthread_sigmask)

versioned_symbol (libc, __pthread_sigmask, pthread_sigmask, GLIBC_2_32);

次にsigprocmask()のコードを見ます。見ての通りpthread_sigmask()を呼び出しているだけです。

glibcのsigprocmask()の実装

// glibc/sysdeps/unix/sysv/linux/sigprocmask.c

/* Get and/or change the set of blocked signals.  */
int
__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
{
  int result = __pthread_sigmask (how, set, oset);
  if (result == 0)
    return 0;
  __set_errno (result);
  return -1;
}
libc_hidden_def (__sigprocmask)
weak_alias (__sigprocmask, sigprocmask)

似ているどころか完全に一致していました。道理で同じ動作になるわけですね。

編集者:すずき(2025/05/23 03:18)

コメント一覧

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



link もっと前
2025年6月1日 >>> 2025年5月19日
link もっと後

管理用メニュー

link 記事を新規作成

<2025>
<<<06>>>
1234567
891011121314
15161718192021
22232425262728
2930-----

最近のコメント5件

  • link 18年8月12日
    すずきさん (05/29 16:57)
    「コメントありがとうございます。\n\nこ...」
  • link 18年8月12日
    ARM926EJ-Sさん (05/29 14:27)
    「この記事が書かれたのは2018年ですが、...」
  • link 17年9月3日
    すずきさん (05/26 23:59)
    「>ちょさんさん\nご参考になれば幸いです...」
  • link 17年9月3日
    ちょさんさん (05/26 20:34)
    「自分もこの機種と全く同じCN-SP700...」
  • link 25年2月19日
    katanaさん (03/21 05:30)
    「katana」

最近の記事3件

  • link 20年10月23日
    すずき (05/29 16:53)
    「[ROCK64/ROCKPro64 - まとめリンク] 目次: ROCK64/ROCKPro64[ROCK64] ROCK64ブート...」
  • link 18年8月12日
    すずき (05/29 16:53)
    「[ARM PCで開発できるか?] 目次: ROCK64/ROCKPro64最近のARM搭載SoCはかなり速くなっています。もし...」
  • link 18年12月15日
    すずき (05/29 16:52)
    「[ARMワンボードPCのネットワーク速度] 目次: ROCK64/ROCKPro64Raspberry Pi対抗ボードの多くは...」
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 2025年
open/close 過去日記について

その他の情報

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

合計:  counter total
本日:  counter today

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

最終更新: 05/29 16:57