揮発性のメモ2

http://d.hatena.ne.jp/iww/

gccで、配列の範囲を超えてアクセスしてる人を探してぶっ殺したい

gccで、配列の範囲を超えてアクセスしてる人を探してぶっ殺したい。
そのためにはgccの ASAN(Address Sanitizer)機能を使う

-fsanitize=address

ソース
#include <stdio.h>
int main()
{
    char buf[15];

    printf("MAIN\n");
    for(int i=0; i<16; i++){
        printf("%08X:buf[%d]\n", &buf[i], i);
        buf[i] = i;
    }

    return 0;
}

配列が15個しかないのに16回まわるのではみ出る、というサンプルプログラム

コンパイル
gcc -g -fsanitize=address main.c

-gオプションは無くてもよいが、つけると検知時に行番号が表示されるのでつける

実行結果
MAIN
621FF520:buf[0]
621FF521:buf[1]
(中略)
621FF52E:buf[14]
621FF52F:buf[15]
=================================================================
==1594509==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd621ff52f at pc 0x55660474d2aa bp 0x7ffd621ff4e0 sp 0x7ffd621ff4d8
WRITE of size 1 at 0x7ffd621ff52f thread T0
    #0 0x55660474d2a9 in main /tmp/main.c:9
    #1 0x7f68a29f8189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #2 0x7f68a29f8244 in __libc_start_main_impl ../csu/libc-start.c:381
    #3 0x55660474d0e0 in _start (/tmp/a.out+0x10e0)

Address 0x7ffd621ff52f is located in stack of thread T0 at offset 47 in frame
    #0 0x55660474d1b8 in main /tmp/main.c:3

  This frame has 1 object(s):
    [32, 47) 'buf' (line 4) <== Memory access at offset 47 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/main.c:9 in main

はみ出た時点でABORTする。 ちゃんと何行目ではみ出たかを検知している。
(はみ出なければ何も起きない)

-fsanitize=bounds

配列をはみ出たことだけを検知したいときは bounds を使う。
またこのときは ABORTせずに適当にごまかして先に進めてしまうので、それを回避したいときは
-fno-sanitize-recover=all オプションも指定すると、そこでプログラムが終了する。

コンパイル
gcc -g -fno-sanitize-recover=all -fsanitize=bounds main.c
実行結果
MAIN
9ED8575D:buf[0]
9ED8575E:buf[1]
(中略)
9ED8576B:buf[14]
9ED8576C:buf[15]
main.c:9:12: runtime error: index 15 out of bounds for type 'char [15]'

情報量が無いしcoreも吐けないので これはまあ使わない

コアダンプの設定

ABORTしたときにcoreを吐かせる方法。
まずそもそもulimitでコアが出るようにした上で、環境変数ASAN_OPTIONSでcoreを吐くように設定する

実行結果
$ ulimit -c unlimited
$ export ASAN_OPTIONS=abort_on_error=1:disable_coredump=0:unmap_shadow_on_exit=1

$ ./a.out
(中略)
==1594730==ABORTING
Aborted (core dumped)

吐かれたcoreには、はみ出しを検知してから実際にABORTするまでの間に ASANの関数がいっぱい挟まるので 解析利用時には最後の8~9層くらいは読み飛ばす

処理能力

3倍くらい遅くなる気がする

Googleドライブで、「エラーが発生しました。」と出て同期されないとき

Googleドライブで、「エラーが発生しました。」と出て同期されないとき

エラーの原因はだいたいファイルがロックされているとかの場合。
このエラーが出ると、ロックしていたアプリが終了し問題が解消しても同期は再開されない。

解消する方法は

エラーリスト画面から再試行する

タスクトレイの右クリックメニューから 歯車⇒「エラーリスト」をクリック
ファイルの一覧が表示されるので、右の ・・・ でアップロードさせる。
全部解消したら、同期が再開する

Googleドライブの再起動

エラーリストの数が多いときはやってられないので、
Googleドライブをいったん終了し、再起動する。
一時停止⇒再開 ではエラーは解消されず再開しない

原作の改変について

原作者がNoを出さない限りは、何をどう改変しようとも全てOKであって
極端に言えばリスペクトすらも要らない派。

アラミスが女性になっても マルコがバイアブランカに行っても ホームズが犬になっても ノーチラス号が亜光速宇宙船になっても
面白ければ特に問題を感じません

POSTFIXで、TLSで送信するよう設定

/etc/postfix/main.cf に次の設定を追記する

# ルート証明書のファイル指定
smtp_tls_CAfile = /etc/pki/tls/cert.pem

# TLS送信設定  may:可能であればTLSで送信
smtp_tls_security_level = may

# TLSログ設定  1:ログを残す
smtp_tls_loglevel = 1

画面外のウィンドウを呼び戻す呪文(Windows10以降)

  1. 画面外に行ったウィンドウをアクティブにする
  2. Win+Shift+← を押す
  3. ウィンドウが隣の画面に移動する

ウィンドウのスナップ機能をオフにしているとこの裏技は使えないので、オンにしておくこと

Windowsで、ジャンクション機能を使う

ジャンクションとは NTFSの機能で、フォルダに対するシンボリックリンクみたいな機能のこと。

NTFSでのシンボリックリンクは管理者権限が必要で面倒くさいので、ジャンクションを使う。
DOS窓から、mklinkコマンドで シンボリックリンクを張るようにジャンクションを作成する。

ショートカットと違い、ファイルのフルパスはジャンクションの下に見える。
エクスプローラで見たらショートカットの記号がついているが、どこへのジャンクションかはエクスプローラ上からは知りえない。dirコマンドの結果には出る。

ジャンクション作成後、再起動しても消えない。
エクスプローラから普通に削除できる。削除しても実体が消えることはない。
DOSから削除するときは rmdir を使う。(うっかりdelで消すと、配下のファイルが消えてしまい死ぬ)

実体が削除されてもジャンクションは残る。
なんなら実体が無い状態から先にジャンクションを張ることもできる
ただし、ジャンクションは同一ドライブ内にしか作成できない。(ドライブをまたげない)

C:\>mklink
シンボリック リンクを作成します。

MKLINK [[/D] | [/H] | [/J]] リンク ターゲット

        /D          ディレクトリのシンボリック リンクを作成します。既定では、
                    ファイルのシンボリック リンクが作成されます。
        /H          シンボリック リンクではなく、ハード リンクを作成します。
        /J          ディレクトリ ジャンクションを作成します。
        リンク      新しいシンボリック リンク名を指定します。
        ターゲット  新しいリンクが参照するパス (相対または絶対)
                    を指定します。
C:\>mklink /J C:\include C:\cygwin64\usr\include
C:\include <<===>> C:\cygwin64\usr\include のジャンクションが作成されました

C:\>cd include

C:\include>
C:\>dir
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 0C26-7C75 です

 C:\ のディレクトリ

2021/12/07  13:04    <DIR>          AMD
2024/01/05  16:33    <DIR>          cygwin64
2024/03/02  18:53    <JUNCTION>     include [C:\cygwin64\usr\include]
2024/01/05  13:12    <DIR>          Program Files
2024/01/05  14:13    <DIR>          Program Files (x86)
2022/09/22  01:15    <DIR>          Users
2024/02/15  01:37    <DIR>          Windows
               0 個のファイル                   0 バイト
               7 個のディレクトリ  408,138,149,888 バイトの空き領域

Windowsで Google Driveを使う

やりたいこと:複数のPC間で、20GB程ある C:\Data\ を同期して仕事とかしたい


WindowsGoogle Drive について調査した
マニュアルが説明不足&項目がとっちらかってて全体像がいまいち見えなかった
アプリの動作は高速だしメッチャ安定してて 安心感が半端ない。

容量

容量 月額
15 GB ¥0
100 GB ¥250 3か月¥60円セール
2 TB ¥1300

インストーラ

パソコン版 Google ドライブを使用する - Google One ヘルプ
インストール時にはフォルダの追加をせず、すべてスキップする。


バックグラウンドプロセス

Google Drive」というバックグラウンドプロセスがたくさん常駐する
数も多いしメモリもそこそこ食う。大きいので1GBくらい。

同期フォルダ

マイドライブ と マイコンピュータ(パソコン) と Google Drive という3つの概念がある
用事があるのは マイドライブ の機能

マイドライブ

PC間で同期されるフォルダ。 デフォルトは C:\Users\HogeHoge\マイドライブ\
「ファイルをミラーリングする」を選択する際に 場所を好きに設定できる。(やり直す際はいったんストリーミングを選択・保存したあとに再度チャレンジする)
とりあえず、今回は C:\Data\ を対象としたいので、そう設定する。


タスクトレイのGoogleドライブのアイコンをクリックし、歯車で設定画面に行く。
Googleドライブ を選択し、「マイドライブの同期オプション」で「ファイルをミラーリングする」 を選択。
ここでマイドライブとして使用したいフォルダ C:\Data\ を選択する。

最初のPCの場合、もとからあったファイルは同期対象となり、クラウドにアップロードされる。
そしてクラウドのファイルがダウンロードされる。
別PCで設定する際も、空のフォルダを作成してそれを指定すると、クラウドからダウンロードを始める。

マイコンピュータ(パソコン)

PC間では同期されず、PC毎にクラウドにのみアップロードされる。
設定画面で「フォルダを追加」と表示されるのがこれ。 この機能に用は無い。

Google Drive (G:)

ほかのPCの「マイコンピュータ」を見ることができる。あとマイドライブへのショートカットが置いてある。
デフォルトでは複数のPCで「マイコンピュータ」という名前になるので、もしこの機能を使うなら名前の変更をとっととしておいた方がいい

同期状況

タスクトレイのGoogleドライブアイコンをクリックすると、今何を同期してるかがリアルタイムに表示される。

隠しフォルダ

マイドライブに .tmp.driveupload という隠しフォルダが出来て、多分これがアップロード待ちの作業用ファイルになっている。(同期が終われば空になる)
ダウンロード用の作業用ファイルも同じく隠しフォルダの .tmp.drivedownload に一旦保存される模様

異常にメモリを食うとき

大量にアップロードしている際、メモリ消費量が急に10GBとか20GBになったりしたときは たぶん頭がおかしくなっている。
Google Drive(G:) が ローカルドライブ(G:) になってるときは間違いなくアホになっている。
同期を一時停止してからパソコンを再起動して同期の再開をすると直る可能性がある。

同期の一時停止

タスクトレイのGoogleドライブアイコンから同期の一時停止ができる。

終了

Googleドライブアプリを終了すると、Google Drive (G:) は消える。 マイドライブは残る。

課金

マイドライブのアップグレードはアカウントごとにおこなわれる。
複数アカウントで合算とかそういうのは無い

空き容量

使用量、空き容量は数値で確認できるが 確認するまでの階層が結構深いし直感的な場所に無いので ちょっと面倒くさい
エクスプローラで確認できるGoogle Drive (G:) の空き領域が、どこのなんの空き領域を指しているかは不明。

アンインストール

アンインストールしても次のフォルダが残る。

C:\Users\HogeHoge\AppData\Local\Google\DriveFS

DriveFS はマイドライブの設定とかキャッシュとかなので アンインストール後は削除可能
マイドライブのフォルダは中身もちゃんと残るので問題ない