tokuhirom's blog

java と strace

java command は clone(2) するので、普通に strace してもダメ。 strace -f java ... のように -f オプションをつければ、clone した先も追ってくれるので、トレース可能となる。

ためしに以下のような何もしないプログラムを用意してみる。

public class Hello {
    public static void main(String[] args) {
    }
}

javac Hello.java とした後、strace -o java.log -f java Hello とすると、java.log というファイルが作成され、どのようなシステムコールを JVM が発行しているかがわかる。

ちなみに /usr/bin/perl -e0 した場合と比べると以下のようになり、Java で開発を行うと何もしないプログラムでもたくさんの system call を呼ぶことができて 便利 だということがわかる。

$ wc -l java.log perl.log
16735 java.log
232 perl.log
Created: 2015-06-30 07:40:02
Updated: 2015-06-30 07:40:02

golang で regexp のキャッシュ

golang で regexp をコンパイルするときは

    var stack_at_re = regexp.MustCompile(`\s*at ([^(]+)\(`)

のように MustCompile を利用して、global 変数に格納するのが基本なそうで。

(const で格納したいところだが、golang では MustCompile の結果が定数ではないので、それはできない。このへんが他の言語と違うところだ。)

Created: 2015-06-28 10:39:45
Updated: 2015-06-28 10:39:45

pthread のバージョンを確認したいでござる

pthread で NPTL が使われてるかどうか確認したかったのだけど、ただしく確認する方法がよくわからなかったので confstr で調べた。

#include <malloc.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    char *buf;
    size_t n;

    n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
    buf = malloc(n);
    if (buf == NULL) {
        printf("Cannot allocate memory\n");
        return;
    }
    confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, n);
    printf("%s\n", buf);
}

昔の LinuxThreads では SIGUSR1, SIGUSR2 を使っていたりしていてユーザーが SIGUSER[12] 使えないなどの問題があったために、Linux 2.6 以後は NPTL に置き換えられており、もはや動作しているシステムでは殆どの場合、NPTL であると仮定してしまってよいように思う。とくに、新規で何かを作る場合、あえて LinuxThreads をサポートする必要はない。のだと思う。

Created: 2015-06-22 09:18:44
Updated: 2015-06-22 09:18:44

h2o の fastcgi サポートで Plack::Handler::FCGI を動かす

h2o で PHP を FCGI で動かすという話題が最近見かけますが、もちろん h2o+FCGI+Perl も快適に動作します。 具体的には以下のように書けばよろしい。

listen: 9090
hosts:
  default:
    paths:
      /:
        file.dir: /path/to/htdocs/
        fastcgi.spawn: "exec /opt/perl-5.18/bin/plackup -s FCGI --nproc 10 /path/to/app/"

簡単すぎて、とくに解説することがないです。

h2o+FCGI で運用した場合のメリットとして、Starlet 等の application server を立ち上げる場合と異なり、application server のプロセスを daemon tools や systemctl 等で管理する必要がないというメリットがある。

一方で、TCP+HTTP/1.1 でやっていれば通信を見るのが簡単なのに、STDIN で通信する FCGI では通信経路を観測するのが難しいので、そのへんをどう見るか、というところでしょうか。

Created: 2015-06-20 23:10:15
Updated: 2015-06-20 23:10:15

golang で os/user 使ってるとクロスコンパイル時にうまく動かないってとき

http://qiita.com/hironobu_s/items/da2f97c2154075d3fbbe

cgo 使ってる部分が動かないとのことで。

user name 取りたいときは os.Getenv("USER") とでもするのが妥当そうである。

なお、windows だとなんか動いていて謎いな、って状況になるのは、この問題は cgo を使ってるから発生するってことなんで、windows だと実行時に dll をあれするので cgo 関係ないから、とのこと。

Created: 2015-06-14 18:51:23
Updated: 2015-06-14 18:51:23

golangで、制御文字を表示させたい

なんか文字列を比較して見た目には同じなのだがマッチしないというような場合、"\x00" のような制御文字が混入している可能性がある。 このような場合、Perl では Devel::Peek を利用して値を dump するのが普通だが、golang で>はどうしたらよいか。

fmt.Printf("%#v", value)

とすればよい。これで golang literal としての表現が印字されるため、制御文字はエスケープされるからだ。

Created: 2015-06-14 08:58:30
Updated: 2015-06-14 08:58:30

jps を自前で実装してみる

tools.jar の中に入ってるクラスを呼べば、同じようなことができるとのこと。

import java.net.URISyntaxException;
import java.util.Set;

import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;

public class MyJps {
    public static void main(String[] args) throws URISyntaxException, MonitorException {
        String hostname = null;
        final MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier(hostname));
        final Set<Integer> lvmids = monitoredHost.activeVms();
        for (Integer lvmid: lvmids) {
            String vmidString = "//" + lvmid + "?mode=r";
            final VmIdentifier vmIdentifier = new VmIdentifier(vmidString);
            final MonitoredVm vm = monitoredHost.getMonitoredVm(vmIdentifier);
            final String mainClass = MonitoredVmUtil.mainClass(vm, true);
            System.out.printf("%d %s\n", lvmid, mainClass);
        }
    }
}
Created: 2015-06-12 15:18:04
Updated: 2015-06-12 15:18:04

How do I include git.properties file into war/tar with gradle?

You can put the task like following:

task generateGitProperties {
    def revisionHash = ["sh",  "-c",  "cd ${project.rootDir} ; git rev-parse --short HEAD"].execute().in.text.trim()
    def date=new Date().format("yyyy--MM-dd HH:mm:ss")
    def outfile = new File("${project.rootDir}/build/resources/main/git.properties")
    file(outfile.parent).mkdirs()
    outfile.write("revision=$revisionHash\nbuildAt=${date}")
}
processResources.dependsOn generateGitProperties
Created: 2015-06-07 17:46:23
Updated: 2015-06-07 17:46:23

shipped tinyorm 1.6.0

I shipped tinyorm 1.6.0

Added mysql's SET type support #22

I added @SetColumn annotation. TinyORM inflate/deflate column annotated by @SetColumn annotation.

Better constructor type mismatch deteciton

If the constructor throws exception when creating row object, tinyorm shows detail information.

Created: 2015-06-07 16:13:25
Updated: 2015-06-07 16:13:25

My latest hack around Server::Starter

In past few days, I sent some p-r to Sever-Stater. This is my note around these commits.

Added --stop option #28

I added --stop option. You can stop server process by this option. Then, we can write deployment script easier.

Do not close STDIN if fd=0 was duplicated. #29

Few days ago, I added --port=$PORT=$FD option. But it doesn't work with --daemon option. Because --daemon option closes STDIN after duplicate fd.

In this p-r, --daemon option don't close STDIN if file descriptor zero is duplicated fd.

Do not unlink status_file if the process doesn't create it. #32

https://github.com/kazuho/p5-Server-Starter/pull/32

server::starter unlink the status-file before exit. It remove another server-stater process' status file.

This issue caused by user's miss operation, but it's serious issue.

  • 1. start_server --status-file=foo.status ...
  • 2. start_server --status-file=foo.status ...
  • 3. start_server --restart --status-file=foo.status ...

In this case, 2nd step unlinks foo.status. As a result, 3rd step wouldn't work.

Created: 2015-06-05 13:04:32
Updated: 2015-06-05 13:04:32