Hatena::ブログ(Diary)

Glass_saga このページをアンテナに追加 RSSフィード

 

2014-02-03

Install systemtap-server on Amazon Linux 2013.09

sudo yum install avahi systemtap systemtap-server
sudo service avahi-daemon start
sudo service stap-server start
sudo chkconfig avahi-daemon on
sudo chkconfig stap-server on
% sudo stap -e 'probe begin { printf("It works!\n"); exit() }' --use-server
It works!

2013-11-07

既に存在するSSHの秘密鍵をAES256で暗号化し直す

暗号化されていない秘密鍵や、3DES等で暗号化されている秘密鍵を、AES256で暗号化する。

openssl rsa -aes256 -in 現在の秘密鍵 -out 新しい秘密鍵

2013-09-11

RubyでTCP_FASTOPENを使う

サーバ

setsockoptにTCP_FASTOPENを渡せば良い。

TCP_FASTOPENは、trunkのr42865以降Socket::TCP_FASTOPENとして定義されている。

require "socket"

TCP_FASTOPEN = Socket::TCP_FASTOPEN || 23

serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
serv.setsockopt(Socket::SOL_TCP, TCP_FASTOPEN, 5)
addrinfo = Addrinfo.new(Socket.sockaddr_in(8888, "localhost"))
serv.bind(addrinfo)
serv.listen(1)

loop do
  socket, addrinfo = serv.accept
  p socket, addrinfo
  p socket.gets
end

クライアント

RubyのSocketライブラリでは明示的にsendto(2)を呼ぶ事はできないが、

Socket#send(BasicSocket#send)の第3引数にソケットアドレス構造体をpackした文字列を渡す事で内部ではsendto(2)が使われる。

(詳しくはext/socket/init.cのrsock_bsock_send()を参照)

Server.tcpなどでTCPのソケットを作成した場合は既にconnectされてしまっているのでErrno::EISCONNが返ってくる。

そのためSocket.newから行う必要がある。

今のところtrunkでもMSG_FASTOPENは定数として定義されていない。

require "socket"

MSG_FASTOPEN = 0x20000000

socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
socket.send("foo\r\n", MSG_FASTOPEN, Socket.sockaddr_in(8888, "localhost"))

2013-07-02

長い文字列を全て表示させる

gdbのプロンプトで

(gdb) set print elements 0

2013-06-15

SystemTapでrubyのUser-Space Evnetsをフックする

SystemTapでrubyのUser-Space Evnetsをフックしてみる。

環境は以下の通り。

systemtapのインストール

sudo apt-get install systemtap systemtap-runtime systemtap-sdt-dev

ruby 2.0.0p195のビルド

既にビルドしている場合はmake cleanしてからビルドし直す。

./configure
make
sudo make install

利用可能なUser-Space Eventsの確認

stap -L 'process("rubyのパス").provider("ruby").mark("*")'

出力例:

% stap -L 'process("/usr/local/bin/ruby").provider("ruby").mark("*")'
process("/usr/local/bin/ruby").provider("ruby").mark("array__create") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("cmethod__entry") $arg1:long $arg2:long $arg3:long $arg4:long
process("/usr/local/bin/ruby").provider("ruby").mark("cmethod__return") $arg1:long $arg2:long $arg3:long $arg4:long
process("/usr/local/bin/ruby").provider("ruby").mark("find__require__entry") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("find__require__return") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("gc__mark__begin")
process("/usr/local/bin/ruby").provider("ruby").mark("gc__mark__end")
process("/usr/local/bin/ruby").provider("ruby").mark("gc__sweep__begin")
process("/usr/local/bin/ruby").provider("ruby").mark("gc__sweep__end")
process("/usr/local/bin/ruby").provider("ruby").mark("hash__create") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("load__entry") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("load__return") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("method__entry") $arg1:long $arg2:long $arg3:long $arg4:long
process("/usr/local/bin/ruby").provider("ruby").mark("method__return") $arg1:long $arg2:long $arg3:long $arg4:long
process("/usr/local/bin/ruby").provider("ruby").mark("object__create") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("parse__begin") $arg1:long $arg2:long
process("/usr/local/bin/ruby").provider("ruby").mark("parse__end") $arg1:long $arg2:long
process("/usr/local/bin/ruby").provider("ruby").mark("raise") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("require__entry") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("require__return") $arg1:long $arg2:long $arg3:long
process("/usr/local/bin/ruby").provider("ruby").mark("string__create") $arg1:long $arg2:long $arg3:long

SystemTapスクリプトの作成

今回は試しに例外の発生をフックしてみる。

まず以下のようなSystemTapスクリプトを書く。

raise.stp:

probe process("/usr/local/bin/ruby").provider("ruby").mark("raise") {
  printf("%s %s %d\n", user_string($arg1), user_string($arg2), $arg3)
}

以下のコマンドで実行:

sudo stap <SystemTapスクリプト> -c <実行するコマンド>

出力例:

% sudo stap raise.stp -c "ruby --disable-gems -e 'raise rescue nil'"
RuntimeError -e 1

RuntimeErrorの発生をフックする事ができた。

参考資料