2011年1月27日木曜日

Zygoteは何をしているのか?

脱線コーナーを抜けて一休み後、とりあえず、続きです。

さて、/system/bin/app_processがZygoteの本体で、JavaのZygoteInit.main()を呼び出すという話を以前の勉強会で出しました。で、前回はそのまま、system_serverプロセスをforkするお話に突入してしまったわけですが、ここからは、その続きの始まりです。ここからは、コードを拾い出して書いて行きますが、かなり大幅に省略していたりしますのでご了承下さい。

public static void main(String argv[]) {
        :
        :
    registerZygoteSocket();
        :
        :
    if (argv[1].equals("true")) {
        startSystemServer();  //前回はここまで
    } else if (!argv[1].equals("false")) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
    }

    Log.i(TAG, "Accepting command socket connections");

    if (ZYGOTE_FORK_MODE) {
        runForkMode();
    } else {
        runSelectLoopMode();
    }

    closeServerSocket();
}
まず先に、registerZygoteSocket()を見ておきます。名前からしてZygoteの必要なソケットの登録とわかります。
        :
        :
private static void registerZygoteSocket() {
    String env = System.getenv(ANDROID_SOCKET_ENV);
    fileDesc = Integer.parseInt(env);
    sServerSocket = new LocalServerSocket(
    createFileDescriptor(fileDesc));

とりあえず、環境変数を取得してLocalServerSocketを生成しています。

続いては前回入り込んだstartSystemServer()では、子プロセスをforkしていましたが、system_serverの生成が終わると、親のプロセスは普通にここまで戻ってきます。続きを見てみると、if文に囲まれた個所が目に入ります。このif文ですが
    private static final boolean ZYGOTE_FORK_MODE = false;
ということで、Gingerbreadさんのコードだと、runSelectLoopMode()に入ります。というわけで処理を追いかけて見ます。
private static void runSelectLoopMode() throws MethodAndArgsCaller {
        :
        :
   while (true) {
       int index;
       /*
       * Call gc() before we block in select().
       * It's work that has to be done anyway, and it's better
       * to avoid making every child do it. It will also
       * madvise() any free memory as a side-effect.
       *
       * Don't call it every time, because walking the entire
       * heap is a lot of overhead to free a few hundred bytes.
       */
       if (loopCount <= 0) {
            gc();
            loopCount = GC_LOOP_COUNT;
        } else {
            loopCount--;
        }
        try {
            fdArray = fds.toArray(fdArray);
            index = selectReadable(fdArray);
        } catch (IOException ex) {
            throw new RuntimeException("Error in select()", ex);
        }
        if (index < 0) {
            throw new RuntimeException("Error in select()");
        } else if (index == 0) {
            ZygoteConnection newPeer = acceptCommandPeer();
            peers.add(newPeer);
            fds.add(newPeer.getFileDesciptor());
        } else {
            boolean done; done = peers.get(index).runOnce();
            if (done) {
                peers.remove(index);
                fds.remove(index);
            }
        }
    }
}

「先生!!なんだか、Zygoteちゃんがgc()呼んでます!」的なコードが見える気がしますが、とりあえず今は無視します。「え〜」って声が聞こえる気はしますが、今回はそこはメインじゃないですし。誰か、ここを追いかけてPF部で発表してくれる人はいないものかな・・・・。

とりあえず進みます。ここでは保持しているfdのリストを元にselectReadable()を呼び出します。selectReadable()は、Nativeコードで、実体は frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp にあります。
Jniのためコードがちょっと面倒なので簡単に何をやってるかだけ抜き出すと、引数で渡したfdのArrayをfdsetにFD_SETした後、

do {
    err = select (nfds, &fdset, NULL, NULL, NULL);
} while (err < 0 && errno == EINTR);

とまぁ、select待ちしたうえで、selectを抜けると、Arrayの何番目がFD_ISSETかを判定して返します。

index==0の場合、つまり、最初に待ち受けしているFDに接続要求が来ると
private static ZygoteConnection acceptCommandPeer() {
    try {
        return new ZygoteConnection(sServerSocket.accept());
    } catch (IOException ex) {
        throw new RuntimeException("IOException during accept()", ex);
    }
}

ということで、acceptしたfdを持ったZygoteConnectionを生成しており、それをarrayに追加した後、acceptしたfdをfdsに追加しているわけです。

で、もしも0以外のfd(つまりsServerSocket.accept()でacceptしたfd)がreadableになると、対象となるZygoteConnection#runOnce()を呼び出します。

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
        :
        :
    args = readArgumentList();
        :
        :
   parsedArgs = new Arguments(args);

    applyUidSecurityPolicy(parsedArgs, peer);
    applyDebuggerSecurityPolicy(parsedArgs);
    applyRlimitSecurityPolicy(parsedArgs, peer);
    applyCapabilitiesSecurityPolicy(parsedArgs, peer);

    int[][] rlimits = null;

    if (parsedArgs.rlimits != null) {
        rlimits = parsedArgs.rlimits.toArray(intArray2d);
    }

    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                                                        parsedArgs.gids, parsedArgs.debugFlags, rlimits);
        :
        :
    if (pid == 0) {
        // in child
        handleChildProc(parsedArgs, descriptors, newStderr);
        // should never happen
        return true;
    } else { /* pid != 0 */
        // in parent...pid of < 0 means failure
        return handleParentProc(pid, descriptors, parsedArgs);
    }

readArgumentList()は、acceptした時のsocketから引数のリストを読み出しています。何をどう読み込んでパースしているのか、その後のチェック等は後日に回すものとして先に進みます。

取得した引数に従って、まずは子プロセスをforkしています。何となく想像がつくかと思いますが、uid,gid等の設定に従って子プロセスをSpecializeしているわけです。

その後、親プロセスであるZygoteの本体は
private boolean handleParentProc(int pid,FileDescriptor[] descriptors, Arguments parsedArgs) {
        :
        :
    ZygoteInit.setpgid(pid, ZygoteInit.getpgid(peer.getPid()));
        :
        :
    for (FileDescriptor fd: descriptors) {
        ZygoteInit.closeDescriptor(fd);
    }
        :
        :
    mSocketOutStream.writeInt(pid);
        :
        :
    if (parsedArgs.peerWait) {
        mSocket.close();
        return true;
    }
    return false;
}
のように、子プロセスをpeerのプロセスグループへの登録を行った後、descriptorを閉じ、要求をしてきた相手にpidを返した後、peerを維持する必要がなければ、socketを閉じて処理をLoopに戻し、ZygoteConnectionを削除します。

起こされた子プロセスは・・・というと
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
                                               PrintStream newStderr) {
    if (parsedArgs.peerWait) {
        ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true);
        sPeerWaitSocket = mSocket;
    } else {
        closeSocket();
        ZygoteInit.closeServerSocket();
    }

    if (descriptors != null) {
        ZygoteInit.reopenStdio(descriptors[0],
        descriptors[1], descriptors[2]);

        for (FileDescriptor fd: descriptors) {
            ZygoteInit.closeDescriptor(fd);
        }
        newStderr = System.err;
    }
サーバー側のFDをcloseした後、
    if (parsedArgs.runtimeInit) {
        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
    } else {
        ClassLoader cloader;

        if (parsedArgs.classpath != null) {
            cloader
                = new PathClassLoader(parsedArgs.classpath,
                                                        ClassLoader.getSystemClassLoader());
        } else {
            cloader = ClassLoader.getSystemClassLoader();
        }
        String className;
        className = parsedArgs.remainingArgs[0];
        String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1];

        System.arraycopy(parsedArgs.remainingArgs, 1,mainArgs, 0, mainArgs.length);
        ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
    }
}
runtimeInitがどのような場合にtrueになっているのか調べ切れていませんが、後者の処理になった場合、引数で指定されたクラスをロードし、Static Mainを呼び出しているようです。

大ざっぱにまとめると、Zygoteは、socketを生成して待ち受け、要求が来ると、自身のコピーである子プロセスで送信されてきた引数を元にJavaのアプリケーションを起動していると考えて良いかと思います。

とりあえず、今夜の調査はここまでとしておきましょう。

2011年1月26日水曜日

Javaのアプリは本当にZygoteのコピーなのかを示すためのメモ

相変わらず勉強会のための・・・・。



1. psの結果を見せる
# ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     268    180   c009b74c 0000875c S /init
root      2     0     0      0     c004e72c 00000000 S kthreadd
root      3     2     0      0     c003fdc8 00000000 S ksoftirqd/0
root      4     2     0      0     c004b2c4 00000000 S events/0
root      5     2     0      0     c004b2c4 00000000 S khelper
root      6     2     0      0     c004b2c4 00000000 S suspend
root      7     2     0      0     c004b2c4 00000000 S kblockd/0
root      8     2     0      0     c004b2c4 00000000 S cqueue
root      9     2     0      0     c018179c 00000000 S kseriod
root      10    2     0      0     c004b2c4 00000000 S kmmcd
root      11    2     0      0     c006fc74 00000000 S pdflush
root      12    2     0      0     c006fc74 00000000 S pdflush
root      13    2     0      0     c00744e4 00000000 S kswapd0
root      14    2     0      0     c004b2c4 00000000 S aio/0
root      22    2     0      0     c017ef48 00000000 S mtdblockd
root      23    2     0      0     c004b2c4 00000000 S kstriped
root      24    2     0      0     c004b2c4 00000000 S hid_compat
root      25    2     0      0     c004b2c4 00000000 S rpciod/0
root      26    2     0      0     c019d16c 00000000 S mmcqd
root      27    1     248    152   c009b74c 0000875c S /sbin/ueventd
system    28    1     804    260   c01a94a4 afd0b6fc S /system/bin/servicemanager
root      29    1     3916   472   ffffffff afd0bdac S /system/bin/vold
root      30    1     3888   412   ffffffff afd0bdac S /system/bin/netd
root      31    1     664    232   c01b52b4 afd0c0cc S /system/bin/debuggerd
radio     32    1     5412   520   ffffffff afd0bdac S /system/bin/rild
root      33    1     63964  22764 c009b74c afd0b844 S zygote
media     34    1     18236  1412  ffffffff afd0b6fc S /system/bin/mediaserver
root      35    1     812    280   c02181f4 afd0b45c S /system/bin/installd
keystore  36    1     1796   320   c01b52b4 afd0c0cc S /system/bin/keystore
root      38    1     824    316   c00b8fec afd0c51c S /system/bin/qemud
shell     40    1     732    244   c0158eb0 afd0b45c S /system/bin/sh
root      41    1     3364   168   ffffffff 00008294 S /sbin/adbd
system    61    33    125500 31392 ffffffff afd0b6fc S system_server
app_12    111   33    76020  19736 ffffffff afd0c51c S jp.co.omronsoft.openwnn
radio     115   33    88384  21124 ffffffff afd0c51c S com.android.phone
system    116   33    76360  21672 ffffffff afd0c51c S com.android.systemui
app_1     121   33    81328  24320 ffffffff afd0c51c S com.android.launcher
app_3     218   33    85192  18708 ffffffff afd0c51c S com.android.mms
app_9     221   33    75264  19804 ffffffff afd0c51c S android.process.media
app_13    250   33    75620  19768 ffffffff afd0c51c S com.android.email
app_11    264   33    72832  17240 ffffffff afd0c51c S com.android.protips
app_20    276   33    73256  17572 ffffffff afd0c51c S com.android.music
root      279   41    732    344   c003da38 afd0c3ac S /system/bin/sh
app_26    285   33    73852  18392 ffffffff afd0c51c S com.android.quicksearchbox
root      294   279   888    332   00000000 afd0b45c R ps

2. /procの情報を見せる
# ls -l /proc/111
dr-xr-xr-x app_12 app_12 2011-01-25 02:57 task
dr-x------ app_12 app_12 2011-01-25 02:57 fd
dr-x------ app_12 app_12 2011-01-25 02:57 fdinfo
dr-xr-xr-x app_12 app_12 2011-01-25 02:57 net
-r-------- app_12 app_12 0 2011-01-25 02:57 environ
-r-------- app_12 app_12 0 2011-01-25 02:57 auxv
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 status
-r-------- app_12 app_12 0 2011-01-25 02:57 personality
-r-------- app_12 app_12 0 2011-01-25 02:57 limits
-rw-r--r-- app_12 app_12 0 2011-01-25 02:57 sched
-r--r--r-- app_12 app_12 0 2011-01-25 02:50 cmdline
-r--r--r-- app_12 app_12 0 2011-01-25 02:50 stat
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 statm
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 maps
-rw------- app_12 app_12 0 2011-01-25 02:57 mem
lrwxrwxrwx app_12 app_12 2011-01-25 02:57 cwd -> /
lrwxrwxrwx app_12 app_12 2011-01-25 02:57 root -> /
lrwxrwxrwx app_12 app_12 2011-01-25 02:57 exe -> /system/bin/app_process
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 mounts
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 mountinfo
-r-------- app_12 app_12 0 2011-01-25 02:57 mountstats
--w------- app_12 app_12 0 2011-01-25 02:57 clear_refs
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 smaps
-r-------- app_12 app_12 0 2011-01-25 02:57 pagemap
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 wchan
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 schedstat
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 cgroup
-r--r--r-- app_12 app_12 0 2011-01-25 02:57 oom_score
-rw-r--r-- app_12 app_12 0 2011-01-25 02:57 oom_adj
-rw-r--r-- app_12 app_12 0 2011-01-25 02:57 coredump_filter

3. map情報を比較してみる?
# cat /proc/33/maps
00008000-00009000 r-xp 00000000 1f:00 321 /system/bin/app_process
00009000-0000a000 rwxp 00001000 1f:00 321 /system/bin/app_process
0000a000-001ab000 rwxp 0000a000 00:00 0 [heap]
40000000-40008000 r-xs 00000000 00:0a 197 /dev/__properties__ (deleted)
40008000-40009000 r-xp 40008000 00:00 0
40009000-4054b000 rwxp 00000000 00:07 355 /dev/ashmem/dalvik-heap (deleted)
4054b000-41009000 ---p 00542000 00:07 355 /dev/ashmem/dalvik-heap (deleted)
41009000-41049000 rwxp 00000000 00:07 356 /dev/ashmem/dalvik-bitmap-1 (deleted)
41049000-41089000 rwxp 00000000 00:07 357 /dev/ashmem/dalvik-bitmap-2 (deleted)
41089000-410aa000 rwxp 00000000 00:07 358 /dev/ashmem/dalvik-card-table (deleted)
410aa000-410ad000 rwxp 410aa000 00:00 0
410ad000-410ae000 ---p 00000000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
410ae000-41289000 rwxp 00001000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
41289000-415ad000 ---p 001dc000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
415ad000-415ae000 r-xs 00002000 1f:00 467 /system/framework/core-junit.jar
415ae000-415b4000 r-xp 00000000 1f:01 283 /data/dalvik-cache/system@framework@core-junit.jar@classes.dex
415be000-415bf000 r-xs 001c6000 1f:00 480 /system/framework/core.jar
415bf000-419e7000 r-xp 00000000 1f:01 277 /data/dalvik-cache/system@framework@core.jar@classes.dex
419e7000-41a26000 rwxp 419e7000 00:00 0
41a26000-41a27000 r-xs 00046000 1f:00 479 /system/framework/bouncycastle.jar
41a27000-41ad4000 r-xp 00000000 1f:01 278 /data/dalvik-cache/system@framework@bouncycastle.jar@classes.dex
41ad4000-41ad5000 r-xs 0007d000 1f:00 476 /system/framework/ext.jar
41ad5000-41c0a000 r-xp 00000000 1f:01 279 /data/dalvik-cache/system@framework@ext.jar@classes.dex
41c0a000-41c0b000 r-xs 002c8000 1f:00 472 /system/framework/framework.jar
41c0b000-422b0000 r-xp 00000000 1f:01 280 /data/dalvik-cache/system@framework@framework.jar@classes.dex
422b0000-4233c000 rwxp 422b0000 00:00 0
4233c000-4233d000 r-xs 00015000 1f:00 475 /system/framework/android.policy.jar
4233d000-4236b000 r-xp 00000000 1f:01 281 /data/dalvik-cache/system@framework@android.policy.jar@classes.dex
4236b000-4236c000 r-xs 00097000 1f:00 473 /system/framework/services.jar
4236c000-424ba000 r-xp 00000000 1f:01 282 /data/dalvik-cache/system@framework@services.jar@classes.dex
424ba000-42a77000 r-xs 00000000 1f:00 519 /system/usr/icu/icudt44l.dat
42a88000-42ab7000 r-xs 00000000 1f:00 261 /system/fonts/DroidSans.ttf
42ab7000-42b32000 r-xs 00000000 1f:00 508 /system/usr/share/zoneinfo/zoneinfo.dat
42b32000-42b6a000 r-xs 00606000 1f:00 478 /system/framework/framework-res.apk
42b6a000-42dbc000 r-xs 003b5000 1f:00 478 /system/framework/framework-res.apk
42dbc000-42dcf000 rwxp 42dbc000 00:00 0
42de0000-42e01000 rwxp 42de0000 00:00 0
80000000-80003000 r-xp 00000000 1f:00 597 /system/lib/liblog.so
80003000-80004000 rwxp 00003000 1f:00 597 /system/lib/liblog.so
80100000-8010e000 r-xp 00000000 1f:00 557 /system/lib/libcutils.so
8010e000-8010f000 rwxp 0000e000 1f:00 557 /system/lib/libcutils.so
8010f000-8011e000 rwxp 8010f000 00:00 0
80200000-80228000 r-xp 00000000 1f:00 633 /system/lib/libutils.so
80228000-80229000 rwxp 00028000 1f:00 633 /system/lib/libutils.so
80300000-80314000 r-xp 00000000 1f:00 592 /system/lib/libz.so
80314000-80315000 rwxp 00014000 1f:00 592 /system/lib/libz.so
80400000-80422000 r-xp 00000000 1f:00 621 /system/lib/libbinder.so
80422000-80428000 rwxp 00022000 1f:00 621 /system/lib/libbinder.so
80500000-8057f000 r-xp 00000000 1f:00 594 /system/lib/libandroid_runtime.so
8057f000-80587000 rwxp 0007f000 1f:00 594 /system/lib/libandroid_runtime.so
80587000-80588000 rwxp 80587000 00:00 0
80600000-80613000 r-xp 00000000 1f:00 559 /system/lib/libexpat.so
80613000-80615000 rwxp 00013000 1f:00 559 /system/lib/libexpat.so
80700000-8072e000 r-xp 00000000 1f:00 583 /system/lib/libnativehelper.so
8072e000-80731000 rwxp 0002e000 1f:00 583 /system/lib/libnativehelper.so
80800000-808bc000 r-xp 00000000 1f:00 574 /system/lib/libcrypto.so
808bc000-808cc000 rwxp 000bc000 1f:00 574 /system/lib/libcrypto.so
808cc000-808ce000 rwxp 808cc000 00:00 0
80900000-809fb000 r-xp 00000000 1f:00 618 /system/lib/libicui18n.so
809fb000-80a00000 rwxp 000fb000 1f:00 618 /system/lib/libicui18n.so
80a00000-80ac8000 r-xp 00000000 1f:00 549 /system/lib/libicuuc.so
80ac8000-80ad0000 rwxp 000c8000 1f:00 549 /system/lib/libicuuc.so
80ad0000-80ad3000 rwxp 80ad0000 00:00 0
80b00000-80b4e000 r-xp 00000000 1f:00 625 /system/lib/libsqlite.so
80b4e000-80b50000 rwxp 0004e000 1f:00 625 /system/lib/libsqlite.so
80c00000-80c2b000 r-xp 00000000 1f:00 612 /system/lib/libssl.so
80c2b000-80c2f000 rwxp 0002b000 1f:00 612 /system/lib/libssl.so
80d00000-80d04000 r-xp 00000000 1f:00 560 /system/lib/libnetutils.so
80d04000-80d05000 rwxp 00004000 1f:00 560 /system/lib/libnetutils.so
80e00000-80e31000 r-xp 00000000 1f:00 551 /system/lib/libui.so
80e31000-80e34000 rwxp 00031000 1f:00 551 /system/lib/libui.so
80f00000-80f09000 r-xp 00000000 1f:00 585 /system/lib/libEGL.so
80f09000-80f0a000 rwxp 00009000 1f:00 585 /system/lib/libEGL.so
80f0a000-80f0c000 rwxp 80f0a000 00:00 0
81000000-8101a000 r-xp 00000000 1f:00 613 /system/lib/libpixelflinger.so
8101a000-8101c000 rwxp 0001a000 1f:00 613 /system/lib/libpixelflinger.so
81100000-81104000 r-xp 00000000 1f:00 569 /system/lib/libhardware_legacy.so
81104000-81105000 rwxp 00004000 1f:00 569 /system/lib/libhardware_legacy.so
81200000-81202000 r-xp 00000000 1f:00 553 /system/lib/libwpa_client.so
81202000-81203000 rwxp 00002000 1f:00 553 /system/lib/libwpa_client.so
81300000-81301000 r-xp 00000000 1f:00 558 /system/lib/libhardware.so
81301000-81302000 rwxp 00001000 1f:00 558 /system/lib/libhardware.so
81400000-8140a000 r-xp 00000000 1f:00 607 /system/lib/libgui.so
8140a000-8140c000 rwxp 0000a000 1f:00 607 /system/lib/libgui.so
81500000-81518000 r-xp 00000000 1f:00 637 /system/lib/libsurfaceflinger_client.so
81518000-8151b000 rwxp 00018000 1f:00 637 /system/lib/libsurfaceflinger_client.so
81600000-81611000 r-xp 00000000 1f:00 641 /system/lib/libcamera_client.so
81611000-81614000 rwxp 00011000 1f:00 641 /system/lib/libcamera_client.so
81700000-8170a000 r-xp 00000000 1f:00 608 /system/lib/libskiagl.so
8170a000-8170b000 rwxp 0000a000 1f:00 608 /system/lib/libskiagl.so
81800000-81914000 r-xp 00000000 1f:00 609 /system/lib/libskia.so
81914000-81918000 rwxp 00114000 1f:00 609 /system/lib/libskia.so
81918000-8191b000 rwxp 81918000 00:00 0
81a00000-81a02000 r-xp 00000000 1f:00 578 /system/lib/libemoji.so
81a02000-81a03000 rwxp 00002000 1f:00 578 /system/lib/libemoji.so
81b00000-81b32000 r-xp 00000000 1f:00 567 /system/lib/libjpeg.so
81b32000-81b33000 rwxp 00032000 1f:00 567 /system/lib/libjpeg.so
81c00000-81c05000 r-xp 00000000 1f:00 570 /system/lib/libGLESv1_CM.so
81c05000-81c06000 rwxp 00005000 1f:00 570 /system/lib/libGLESv1_CM.so
81d00000-81da2000 r-xp 00000000 1f:00 572 /system/lib/libdvm.so
81da2000-81da9000 rwxp 000a2000 1f:00 572 /system/lib/libdvm.so
81da9000-81dab000 rwxp 81da9000 00:00 0
81e00000-81e04000 r-xp 00000000 1f:00 634 /system/lib/libGLESv2.so
81e04000-81e05000 rwxp 00004000 1f:00 634 /system/lib/libGLESv2.so
81f00000-81f02000 r-xp 00000000 1f:00 619 /system/lib/libETC1.so
81f02000-81f03000 rwxp 00002000 1f:00 619 /system/lib/libETC1.so
82000000-82051000 r-xp 00000000 1f:00 547 /system/lib/libsonivox.so
82051000-82052000 rwxp 00051000 1f:00 547 /system/lib/libsonivox.so
82052000-82057000 rwxp 82052000 00:00 0
82100000-82159000 r-xp 00000000 1f:00 561 /system/lib/libmedia.so
82159000-82168000 rwxp 00059000 1f:00 561 /system/lib/libmedia.so
82200000-82201000 r-xp 00000000 1f:00 636 /system/lib/libnfc_ndef.so
82201000-82202000 rwxp 00001000 1f:00 636 /system/lib/libnfc_ndef.so
82300000-8230c000 r-xp 00000000 1f:00 591 /system/lib/libmedia_jni.so
8230c000-8230d000 rwxp 0000c000 1f:00 591 /system/lib/libmedia_jni.so
82400000-8255d000 r-xp 00000000 1f:00 639 /system/lib/libstagefright.so
8255d000-82567000 rwxp 0015d000 1f:00 639 /system/lib/libstagefright.so
82567000-82568000 rwxp 82567000 00:00 0
82600000-8261c000 r-xp 00000000 1f:00 600 /system/lib/libvorbisidec.so
8261c000-8261d000 rwxp 0001c000 1f:00 600 /system/lib/libvorbisidec.so
82700000-8270c000 r-xp 00000000 1f:00 640 /system/lib/libstagefright_amrnb_common.so
8270c000-8270d000 rwxp 0000c000 1f:00 640 /system/lib/libstagefright_amrnb_common.so
82800000-82801000 r-xp 00000000 1f:00 615 /system/lib/libstagefright_enc_common.so
82801000-82802000 rwxp 00001000 1f:00 615 /system/lib/libstagefright_enc_common.so
82900000-82905000 r-xp 00000000 1f:00 614 /system/lib/libstagefright_avc_common.so
82905000-82906000 rwxp 00005000 1f:00 614 /system/lib/libstagefright_avc_common.so
82a00000-82a09000 r-xp 00000000 1f:00 568 /system/lib/libstagefright_foundation.so
82a09000-82a0a000 rwxp 00009000 1f:00 568 /system/lib/libstagefright_foundation.so
82b00000-82b03000 r-xp 00000000 1f:00 647 /system/lib/libstagefright_color_conversion.so
82b03000-82b04000 rwxp 00003000 1f:00 647 /system/lib/libstagefright_color_conversion.so
82c00000-82c09000 r-xp 00000000 1f:00 632 /system/lib/libexif.so
82c09000-82c0a000 rwxp 00009000 1f:00 632 /system/lib/libexif.so
82c0a000-82c0c000 rwxp 82c0a000 00:00 0
82d00000-82d06000 r-xp 00000000 1f:00 598 /system/lib/libsoundpool.so
82d06000-82d07000 rwxp 00006000 1f:00 598 /system/lib/libsoundpool.so
82e00000-82e3a000 r-xp 00000000 1f:00 554 /system/lib/libstlport.so
82e3a000-82e3c000 rwxp 0003a000 1f:00 554 /system/lib/libstlport.so
83000000-83415000 r-xp 00000000 1f:00 628 /system/lib/libwebcore.so
83415000-8346f000 rwxp 00415000 1f:00 628 /system/lib/libwebcore.so
8346f000-83471000 rwxp 8346f000 00:00 0
afb00000-afb20000 r-xp 00000000 1f:00 595 /system/lib/libm.so
afb20000-afb21000 rwxp 00020000 1f:00 595 /system/lib/libm.so
afc00000-afc01000 r-xp 00000000 1f:00 623 /system/lib/libstdc++.so
afc01000-afc02000 rwxp 00001000 1f:00 623 /system/lib/libstdc++.so
afd00000-afd40000 r-xp 00000000 1f:00 588 /system/lib/libc.so
afd40000-afd43000 rwxp 00040000 1f:00 588 /system/lib/libc.so
afd43000-afd4e000 rwxp afd43000 00:00 0
b0001000-b0009000 r-xp 00001000 1f:00 293 /system/bin/linker
b0009000-b000a000 rwxp 00009000 1f:00 293 /system/bin/linker
b000a000-b0013000 rwxp b000a000 00:00 0
bef58000-bef6d000 rw-p befeb000 00:00 0 [stack]

# cat /proc/111/maps
00008000-00009000 r-xp 00000000 1f:00 321 /system/bin/app_process
00009000-0000a000 rwxp 00001000 1f:00 321 /system/bin/app_process
0000a000-001d2000 rwxp 0000a000 00:00 0 [heap]
10000000-10001000 ---p 10000000 00:00 0
10001000-10100000 rwxp 10001000 00:00 0
40000000-40008000 r-xs 00000000 00:0a 197 /dev/__properties__ (deleted)
40008000-40009000 r-xp 40008000 00:00 0
40009000-405fb000 rwxp 00000000 00:07 355 /dev/ashmem/dalvik-heap (deleted)
405fb000-41009000 ---p 005f2000 00:07 355 /dev/ashmem/dalvik-heap (deleted)
41009000-41049000 rwxp 00000000 00:07 356 /dev/ashmem/dalvik-bitmap-1 (deleted)
41049000-41089000 rwxp 00000000 00:07 357 /dev/ashmem/dalvik-bitmap-2 (deleted)
41089000-410aa000 rwxp 00000000 00:07 358 /dev/ashmem/dalvik-card-table (deleted)
410aa000-410ad000 rwxp 410aa000 00:00 0
410ad000-410ae000 ---p 00000000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
410ae000-41294000 rwxp 00001000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
41294000-415ad000 ---p 001e7000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
415ad000-415ae000 r-xs 00002000 1f:00 467 /system/framework/core-junit.jar
415ae000-415b4000 r-xp 00000000 1f:01 283 /data/dalvik-cache/system@framework@core-junit.jar@classes.dex
415b4000-415bd000 rwxp 415b4000 00:00 0
415bd000-415be000 r-xs 00000000 00:07 409 /dev/ashmem/SurfaceFlinger read-only heap (deleted)
415be000-415bf000 r-xs 001c6000 1f:00 480 /system/framework/core.jar
415bf000-419e7000 r-xp 00000000 1f:01 277 /data/dalvik-cache/system@framework@core.jar@classes.dex
419e7000-41a26000 rwxp 419e7000 00:00 0
41a26000-41a27000 r-xs 00046000 1f:00 479 /system/framework/bouncycastle.jar
41a27000-41ad4000 r-xp 00000000 1f:01 278 /data/dalvik-cache/system@framework@bouncycastle.jar@classes.dex
41ad4000-41ad5000 r-xs 0007d000 1f:00 476 /system/framework/ext.jar
41ad5000-41c0a000 r-xp 00000000 1f:01 279 /data/dalvik-cache/system@framework@ext.jar@classes.dex
41c0a000-41c0b000 r-xs 002c8000 1f:00 472 /system/framework/framework.jar
41c0b000-422b0000 r-xp 00000000 1f:01 280 /data/dalvik-cache/system@framework@framework.jar@classes.dex
422b0000-4233c000 rwxp 422b0000 00:00 0
4233c000-4233d000 r-xs 00015000 1f:00 475 /system/framework/android.policy.jar
4233d000-4236b000 r-xp 00000000 1f:01 281 /data/dalvik-cache/system@framework@android.policy.jar@classes.dex
4236b000-4236c000 r-xs 00097000 1f:00 473 /system/framework/services.jar
4236c000-424ba000 r-xp 00000000 1f:01 282 /data/dalvik-cache/system@framework@services.jar@classes.dex
424ba000-42a77000 r-xs 00000000 1f:00 519 /system/usr/icu/icudt44l.dat
42a77000-42a83000 rwxp 42a77000 00:00 0
42a88000-42ab7000 r-xs 00000000 1f:00 261 /system/fonts/DroidSans.ttf
42ab7000-42b32000 r-xs 00000000 1f:00 508 /system/usr/share/zoneinfo/zoneinfo.dat
42b32000-42b6a000 r-xs 00606000 1f:00 478 /system/framework/framework-res.apk
42b6a000-42dbc000 r-xs 003b5000 1f:00 478 /system/framework/framework-res.apk
42dbc000-42dcf000 rwxp 42dbc000 00:00 0
42dcf000-42dd9000 r-xs 00286000 1f:00 426 /system/app/OpenWnn.apk
42de0000-42e01000 rwxp 42de0000 00:00 0
42e01000-42e02000 ---p 42e01000 00:00 0
42e02000-42f01000 rwxp 42e02000 00:00 0
42f01000-42f02000 ---p 42f01000 00:00 0
42f02000-43001000 rwxp 42f02000 00:00 0
43001000-43002000 ---p 43001000 00:00 0
43002000-43101000 rwxp 43002000 00:00 0
43101000-43102000 ---p 43101000 00:00 0
43102000-43201000 rwxp 43102000 00:00 0
43201000-432ff000 r-xp 00000000 00:0a 61 /dev/binder
432ff000-43300000 ---p 432ff000 00:00 0
43300000-433ff000 rwxp 43300000 00:00 0
433ff000-43400000 ---p 433ff000 00:00 0
43400000-434ff000 rwxp 43400000 00:00 0
434ff000-43509000 r-xs 00286000 1f:00 426 /system/app/OpenWnn.apk
43509000-43544000 r-xp 00000000 1f:01 444 /data/dalvik-cache/system@app@OpenWnn.apk@classes.dex
43544000-43555000 r-xs 00276000 1f:00 426 /system/app/OpenWnn.apk
43555000-435d5000 r-xp 00000000 00:07 700 /dev/ashmem/dalvik-jit-code-cache (deleted)
435d5000-43609000 rwxp 435d5000 00:00 0
80000000-80003000 r-xp 00000000 1f:00 597 /system/lib/liblog.so
80003000-80004000 rwxp 00003000 1f:00 597 /system/lib/liblog.so
80100000-8010e000 r-xp 00000000 1f:00 557 /system/lib/libcutils.so
8010e000-8010f000 rwxp 0000e000 1f:00 557 /system/lib/libcutils.so
8010f000-8011e000 rwxp 8010f000 00:00 0
80200000-80228000 r-xp 00000000 1f:00 633 /system/lib/libutils.so
80228000-80229000 rwxp 00028000 1f:00 633 /system/lib/libutils.so
80300000-80314000 r-xp 00000000 1f:00 592 /system/lib/libz.so
80314000-80315000 rwxp 00014000 1f:00 592 /system/lib/libz.so
80400000-80422000 r-xp 00000000 1f:00 621 /system/lib/libbinder.so
80422000-80428000 rwxp 00022000 1f:00 621 /system/lib/libbinder.so
80500000-8057f000 r-xp 00000000 1f:00 594 /system/lib/libandroid_runtime.so
8057f000-80587000 rwxp 0007f000 1f:00 594 /system/lib/libandroid_runtime.so
80587000-80588000 rwxp 80587000 00:00 0
80600000-80613000 r-xp 00000000 1f:00 559 /system/lib/libexpat.so
80613000-80615000 rwxp 00013000 1f:00 559 /system/lib/libexpat.so
80700000-8072e000 r-xp 00000000 1f:00 583 /system/lib/libnativehelper.so
8072e000-80731000 rwxp 0002e000 1f:00 583 /system/lib/libnativehelper.so
80800000-808bc000 r-xp 00000000 1f:00 574 /system/lib/libcrypto.so
808bc000-808cc000 rwxp 000bc000 1f:00 574 /system/lib/libcrypto.so
808cc000-808ce000 rwxp 808cc000 00:00 0
80900000-809fb000 r-xp 00000000 1f:00 618 /system/lib/libicui18n.so
809fb000-80a00000 rwxp 000fb000 1f:00 618 /system/lib/libicui18n.so
80a00000-80ac8000 r-xp 00000000 1f:00 549 /system/lib/libicuuc.so
80ac8000-80ad0000 rwxp 000c8000 1f:00 549 /system/lib/libicuuc.so
80ad0000-80ad3000 rwxp 80ad0000 00:00 0
80b00000-80b4e000 r-xp 00000000 1f:00 625 /system/lib/libsqlite.so
80b4e000-80b50000 rwxp 0004e000 1f:00 625 /system/lib/libsqlite.so
80c00000-80c2b000 r-xp 00000000 1f:00 612 /system/lib/libssl.so
80c2b000-80c2f000 rwxp 0002b000 1f:00 612 /system/lib/libssl.so
80d00000-80d04000 r-xp 00000000 1f:00 560 /system/lib/libnetutils.so
80d04000-80d05000 rwxp 00004000 1f:00 560 /system/lib/libnetutils.so
80e00000-80e31000 r-xp 00000000 1f:00 551 /system/lib/libui.so
80e31000-80e34000 rwxp 00031000 1f:00 551 /system/lib/libui.so
80f00000-80f09000 r-xp 00000000 1f:00 585 /system/lib/libEGL.so
80f09000-80f0a000 rwxp 00009000 1f:00 585 /system/lib/libEGL.so
80f0a000-80f0c000 rwxp 80f0a000 00:00 0
81000000-8101a000 r-xp 00000000 1f:00 613 /system/lib/libpixelflinger.so
8101a000-8101c000 rwxp 0001a000 1f:00 613 /system/lib/libpixelflinger.so
81100000-81104000 r-xp 00000000 1f:00 569 /system/lib/libhardware_legacy.so
81104000-81105000 rwxp 00004000 1f:00 569 /system/lib/libhardware_legacy.so
81200000-81202000 r-xp 00000000 1f:00 553 /system/lib/libwpa_client.so
81202000-81203000 rwxp 00002000 1f:00 553 /system/lib/libwpa_client.so
81300000-81301000 r-xp 00000000 1f:00 558 /system/lib/libhardware.so
81301000-81302000 rwxp 00001000 1f:00 558 /system/lib/libhardware.so
81400000-8140a000 r-xp 00000000 1f:00 607 /system/lib/libgui.so
8140a000-8140c000 rwxp 0000a000 1f:00 607 /system/lib/libgui.so
81500000-81518000 r-xp 00000000 1f:00 637 /system/lib/libsurfaceflinger_client.so
81518000-8151b000 rwxp 00018000 1f:00 637 /system/lib/libsurfaceflinger_client.so
81600000-81611000 r-xp 00000000 1f:00 641 /system/lib/libcamera_client.so
81611000-81614000 rwxp 00011000 1f:00 641 /system/lib/libcamera_client.so
81700000-8170a000 r-xp 00000000 1f:00 608 /system/lib/libskiagl.so
8170a000-8170b000 rwxp 0000a000 1f:00 608 /system/lib/libskiagl.so
81800000-81914000 r-xp 00000000 1f:00 609 /system/lib/libskia.so
81914000-81918000 rwxp 00114000 1f:00 609 /system/lib/libskia.so
81918000-8191b000 rwxp 81918000 00:00 0
81a00000-81a02000 r-xp 00000000 1f:00 578 /system/lib/libemoji.so
81a02000-81a03000 rwxp 00002000 1f:00 578 /system/lib/libemoji.so
81b00000-81b32000 r-xp 00000000 1f:00 567 /system/lib/libjpeg.so
81b32000-81b33000 rwxp 00032000 1f:00 567 /system/lib/libjpeg.so
81c00000-81c05000 r-xp 00000000 1f:00 570 /system/lib/libGLESv1_CM.so
81c05000-81c06000 rwxp 00005000 1f:00 570 /system/lib/libGLESv1_CM.so
81d00000-81da2000 r-xp 00000000 1f:00 572 /system/lib/libdvm.so
81da2000-81da9000 rwxp 000a2000 1f:00 572 /system/lib/libdvm.so
81da9000-81dab000 rwxp 81da9000 00:00 0
81e00000-81e04000 r-xp 00000000 1f:00 634 /system/lib/libGLESv2.so
81e04000-81e05000 rwxp 00004000 1f:00 634 /system/lib/libGLESv2.so
81f00000-81f02000 r-xp 00000000 1f:00 619 /system/lib/libETC1.so
81f02000-81f03000 rwxp 00002000 1f:00 619 /system/lib/libETC1.so
82000000-82051000 r-xp 00000000 1f:00 547 /system/lib/libsonivox.so
82051000-82052000 rwxp 00051000 1f:00 547 /system/lib/libsonivox.so
82052000-82057000 rwxp 82052000 00:00 0
82100000-82159000 r-xp 00000000 1f:00 561 /system/lib/libmedia.so
82159000-82168000 rwxp 00059000 1f:00 561 /system/lib/libmedia.so
82200000-82201000 r-xp 00000000 1f:00 636 /system/lib/libnfc_ndef.so
82201000-82202000 rwxp 00001000 1f:00 636 /system/lib/libnfc_ndef.so
82300000-8230c000 r-xp 00000000 1f:00 591 /system/lib/libmedia_jni.so
8230c000-8230d000 rwxp 0000c000 1f:00 591 /system/lib/libmedia_jni.so
82400000-8255d000 r-xp 00000000 1f:00 639 /system/lib/libstagefright.so
8255d000-82567000 rwxp 0015d000 1f:00 639 /system/lib/libstagefright.so
82567000-82568000 rwxp 82567000 00:00 0
82600000-8261c000 r-xp 00000000 1f:00 600 /system/lib/libvorbisidec.so
8261c000-8261d000 rwxp 0001c000 1f:00 600 /system/lib/libvorbisidec.so
82700000-8270c000 r-xp 00000000 1f:00 640 /system/lib/libstagefright_amrnb_common.so
8270c000-8270d000 rwxp 0000c000 1f:00 640 /system/lib/libstagefright_amrnb_common.so
82800000-82801000 r-xp 00000000 1f:00 615 /system/lib/libstagefright_enc_common.so
82801000-82802000 rwxp 00001000 1f:00 615 /system/lib/libstagefright_enc_common.so
82900000-82905000 r-xp 00000000 1f:00 614 /system/lib/libstagefright_avc_common.so
82905000-82906000 rwxp 00005000 1f:00 614 /system/lib/libstagefright_avc_common.so
82a00000-82a09000 r-xp 00000000 1f:00 568 /system/lib/libstagefright_foundation.so
82a09000-82a0a000 rwxp 00009000 1f:00 568 /system/lib/libstagefright_foundation.so
82b00000-82b03000 r-xp 00000000 1f:00 647 /system/lib/libstagefright_color_conversion.so
82b03000-82b04000 rwxp 00003000 1f:00 647 /system/lib/libstagefright_color_conversion.so
82c00000-82c09000 r-xp 00000000 1f:00 632 /system/lib/libexif.so
82c09000-82c0a000 rwxp 00009000 1f:00 632 /system/lib/libexif.so
82c0a000-82c0c000 rwxp 82c0a000 00:00 0
82d00000-82d06000 r-xp 00000000 1f:00 598 /system/lib/libsoundpool.so
82d06000-82d07000 rwxp 00006000 1f:00 598 /system/lib/libsoundpool.so
82e00000-82e3a000 r-xp 00000000 1f:00 554 /system/lib/libstlport.so
82e3a000-82e3c000 rwxp 0003a000 1f:00 554 /system/lib/libstlport.so
82f00000-82f0b000 r-xp 00000000 1f:00 630 /system/lib/libwnndict.so
82f0b000-82f0c000 rwxp 0000b000 1f:00 630 /system/lib/libwnndict.so
83000000-83415000 r-xp 00000000 1f:00 628 /system/lib/libwebcore.so
83415000-8346f000 rwxp 00415000 1f:00 628 /system/lib/libwebcore.so
8346f000-83471000 rwxp 8346f000 00:00 0
83800000-83801000 r-xp 00000000 1f:00 593 /system/lib/libWnnJpnDic.so
83801000-83948000 rwxp 00001000 1f:00 593 /system/lib/libWnnJpnDic.so
83a00000-83a01000 r-xp 00000000 1f:00 646 /system/lib/libWnnEngDic.so
83a01000-83b23000 rwxp 00001000 1f:00 646 /system/lib/libWnnEngDic.so
afb00000-afb20000 r-xp 00000000 1f:00 595 /system/lib/libm.so
afb20000-afb21000 rwxp 00020000 1f:00 595 /system/lib/libm.so
afc00000-afc01000 r-xp 00000000 1f:00 623 /system/lib/libstdc++.so
afc01000-afc02000 rwxp 00001000 1f:00 623 /system/lib/libstdc++.so
afd00000-afd40000 r-xp 00000000 1f:00 588 /system/lib/libc.so
afd40000-afd43000 rwxp 00040000 1f:00 588 /system/lib/libc.so
afd43000-afd4e000 rwxp afd43000 00:00 0
b0001000-b0009000 r-xp 00001000 1f:00 293 /system/bin/linker
b0009000-b000a000 rwxp 00009000 1f:00 293 /system/bin/linker
b000a000-b0013000 rwxp b000a000 00:00 0
bef58000-bef6d000 rw-p befeb000 00:00 0 [stack]

* 差分
1c1
< # cat maps --- > # cat /proc/111/maps
4c4,6
< 0000a000-001ab000 rwxp 0000a000 00:00 0 [heap] --- > 0000a000-001d2000 rwxp 0000a000 00:00 0 [heap]
> 10000000-10001000 ---p 10000000 00:00 0
> 10001000-10100000 rwxp 10001000 00:00 0
7,8c9,10
< 40009000-4054b000 rwxp 00000000 00:07 355 /dev/ashmem/dalvik-heap (deleted) < 4054b000-41009000 ---p 00542000 00:07 355 /dev/ashmem/dalvik-heap (deleted) --- > 40009000-405fb000 rwxp 00000000 00:07 355 /dev/ashmem/dalvik-heap (deleted)
> 405fb000-41009000 ---p 005f2000 00:07 355 /dev/ashmem/dalvik-heap (deleted)
14,15c16,17
< 410ae000-41289000 rwxp 00001000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted) < 41289000-415ad000 ---p 001dc000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted) --- > 410ae000-41294000 rwxp 00001000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
> 41294000-415ad000 ---p 001e7000 00:07 359 /dev/ashmem/dalvik-LinearAlloc (deleted)
17a20,21
> 415b4000-415bd000 rwxp 415b4000 00:00 0
> 415bd000-415be000 r-xs 00000000 00:07 409 /dev/ashmem/SurfaceFlinger read-only heap (deleted)
32a37
> 42a77000-42a83000 rwxp 42a77000 00:00 0
37a43
> 42dcf000-42dd9000 r-xs 00286000 1f:00 426 /system/app/OpenWnn.apk
38a45,62
> 42e01000-42e02000 ---p 42e01000 00:00 0
> 42e02000-42f01000 rwxp 42e02000 00:00 0
> 42f01000-42f02000 ---p 42f01000 00:00 0
> 42f02000-43001000 rwxp 42f02000 00:00 0
> 43001000-43002000 ---p 43001000 00:00 0
> 43002000-43101000 rwxp 43002000 00:00 0
> 43101000-43102000 ---p 43101000 00:00 0
> 43102000-43201000 rwxp 43102000 00:00 0
> 43201000-432ff000 r-xp 00000000 00:0a 61 /dev/binder
> 432ff000-43300000 ---p 432ff000 00:00 0
> 43300000-433ff000 rwxp 43300000 00:00 0
> 433ff000-43400000 ---p 433ff000 00:00 0
> 43400000-434ff000 rwxp 43400000 00:00 0
> 434ff000-43509000 r-xs 00286000 1f:00 426 /system/app/OpenWnn.apk
> 43509000-43544000 r-xp 00000000 1f:01 444 /data/dalvik-cache/system@app@OpenWnn.apk@classes.dex
> 43544000-43555000 r-xs 00276000 1f:00 426 /system/app/OpenWnn.apk
> 43555000-435d5000 r-xp 00000000 00:07 700 /dev/ashmem/dalvik-jit-code-cache (deleted)
> 435d5000-43609000 rwxp 435d5000 00:00 0
138a163,164
> 82f00000-82f0b000 r-xp 00000000 1f:00 630 /system/lib/libwnndict.so
> 82f0b000-82f0c000 rwxp 0000b000 1f:00 630 /system/lib/libwnndict.so
141a168,171
> 83800000-83801000 r-xp 00000000 1f:00 593 /system/lib/libWnnJpnDic.so
> 83801000-83948000 rwxp 00001000 1f:00 593 /system/lib/libWnnJpnDic.so
> 83a00000-83a01000 r-xp 00000000 1f:00 646 /system/lib/libWnnEngDic.so
> 83a01000-83b23000 rwxp 00001000 1f:00 646 /system/lib/libWnnEngDic.so

2011年1月25日火曜日

kthreadd

相変わらず、次回勉強会へ向けての資料の下書きメモ。
今日は脱線コーナー

initから先の勉強の時点で、Androidのエミュレータにadb shellでつないだ上でpsした時のプロセスをtreeにした際に、kthreaddはカーネルのお話だからとすっ飛ばしていたら、日曜夜22時からのUst講座「V7から始めるUNIX講座」において、 生徒の@pakuqiさんが講師の@magoroku15 先生 に「PPIDが0のプロセスがいるんですが」なんてkthreaddの質問をしていてタイムリーだなぁと思ってしまいました。まぁ、先日の講座はV7におけるinitのお話で、質問はUbuntuに関してでしたので、同じところに行き着くわけですが。

ちなみに、kthreaddはカーネルスレッド・デーモンです。Linux kernelは、起動すると2つのスレッドを起こします。一つがinitプロセスを起動するためのkernel_initで、もう一つがこのkthreaddだったと思います(他には無かったと思う)。

カーネルは、今まさにやらなければならない仕事をこなしているわけですが、やっぱりどこかCPUがあいた時にでもやればいいような仕事もあるわけです。そんな時に、カーネル・スレッドが使われます(と隠者は理解しています)。

で、このカーネルスレッド、psコマンドで表示されることからなんとなく想像できるかと思いますが、一般のプロセスと同じプロセス情報を持っています。なぜかというと、カーネルスレッドのスケジューリングは、一般のプロセスと同じようにスケジューリングされているようなのです。

ところで、先日の日記では、kthreaddの下に子プロセスが複数いましたね。実はこれこそが、kthreaddのお仕事のようです。
先ほど、CPUが空いた時に行えば良い事をカーネルスレッドにやらせると言いましたが、後回しで良い処理のためにプロセス情報の初期化やスケジューラへの登録(これはつまり再スケジューリングの契機になる?)なんていう重たい処理が走るのは嫌なので、Kernelにおけるスレッドの生成は、何をスレッドとするのかの最低限の情報をリストに追加するだけにとどめ、kthreaddが後からそのリストを読み、必要なプロセス情報の初期化、スケジュールへの登録などの作業を行うわけですね。

とまぁ、偉そうに知ったかぶりな日記を書きましたが、隠者自身はここ最近この辺のコードを追いかけていません。仕事的にもカーネルのコード読みなんかはしないので、例によってただの趣味でちらちら見てた人です。こちらの情報は間違ってるとか、実はそうではないんだなという情報をお持ちの方は是非 twitterで@hermit4 までご教授下さい。

2011年1月20日木曜日

system_process以降

さて、先日に引き続き、initから先です。

第4回横浜PF部の勉強会(init 祭り)においては、Zygoteの非常に複雑な起動の仕組みを紹介しました。ただ、この時点では学習不足もあってZygoteとsystem_processをあまり分けて考えていませんでした。

Zygoteは、/system/bin/app_processを使って起動されるすべてのVMプロセスの親となるプロセスで、起動時にオプション --start-system-serverの引数が渡されると、起動時にsystem_processという名前の子プロセスを生成するように実装されています。

system_processは、Zygoteをコピーして生成されたAndroidの中枢を担うシステム用のVMプロセスで、Java側の各種サービススレッド群は、すべてこのsystem_processのスレッドとして生成されます。

DBMSを使ってスレッドの一覧を取得できます。

*159native6937main
*260vmwait21341HeapWorker
*361vmwait10618GC
*462vmwait00Signal Catcher
*563running138431JDWP
*664vmwait7654Compiler
765native10Binder Thread #1
866native00Binder Thread #2
971native479150android.server.ServerThread
1072native248311ActivityManager
1176timed-wait1921ProcessStats
1277native165PackageManager
1378native00FileObserver
1479native00AccountManagerService
1581native00SyncHandlerThread
1686native5510AlarmManager
1783native01UEventObserver
1884native10PowerManagerService.mScreenOffThread
1985native50PowerManagerService
2087native162WindowManager
2188native70664WindowManagerPolicy
2289native13InputDispatcher
2390native20InputReader
2491native44NetdConnector
2594native00WifiService
2692native60ConnectivityThread
2795native00Tethering
2896native00MountService
2997native40VoldConnector
3099native00AudioService
31101native00SoundPool
32102native00SoundPoolThread
33103native00backup
34107timed-wait717watchdog
35110native21LocationManagerService
36111native2113ThrottleService
37122native00GpsLocationProvider
38160native00Binder Thread #3
39163native00Binder Thread #4
40164native30Binder Thread #5
42292native00Binder Thread #9
44231native00Binder Thread #8
45217native00Binder Thread #6
46229native00Binder Thread #7
47293native00Binder Thread #10
48295native00Binder Thread #11

結構たくさんのスレッドが立ってますね。

勉強会でも話した内容ですが、ここまでの流れを簡単に述べると

  1. kernelが/initを起動する
  2. /initがinit.rcに従い /system/bin/app_process(Zygote) を --start-system-server引数付きで起動する
  3. app_processがfork後、com.android.server.SystemServer#main を実行する(system_server)
  4. com.android.server.SystemServer#main が android_server_SystemServer_init1(JNIEnv* env, jobject clazz)をJNI経由で呼び出し
  5. android_server_SystemServer_init1() が system_init()を呼び出し
  6. system_init()では Surfaceflingerのinstantiate等を行った後、SystemServer#init2をコールバック
  7. SystemServer#init2が、 amdrpod.server.ServerThreadを生成、runする。
  8. ServerThreadが各種サービス・マネージャー関連を生成、登録していく。それっぽい箇所を抜き出してみると
    • new EntropyService()
    • new PowerManagerService()
    • ActivityManagerService.main()
    • new TelephonyRegistry(context)
    • AttributeCache.init(context)
    • PackageManagerService.main()
    • ActivityManagerService.setSystemProcess()
    • context.getContentResolver()
    • new AccountManagerService(context)
    • ContentService.main()
    • ActivityManagerService.installSystemProviders()
    • new BatteryService(context)
    • new LightsService(context)
    • new VibratorService(context)
    • PowerManagerService#init()
    • new AlarmManagerService(context)
    • Watchdog.getInstance().init()
    • WindowManagerService.main()
    • ((ActivityManagerService)ServiceManager.getService("activity").setWindowManager
    • new BluetoothService(context)
    • new BluetoothA2dpService()
    • new DevicePolicyManagerService(context)
    • new StatusBarManagerService(context)
    • new ClipboardService(context)
    • new InputMethodManagerService()
    • new NetStatService()
    • NetworkManagementService.create()
    • ConnectivityService.getInstance()
    • new ThrottleService(context)
    • new AccessibilityManagerService(context)
    • new MountService(context)
    • new NotificationManagerService()
    • new DeviceStorageMonitorService(context)
    • new LocationManagerService(context)
    • new SearchManagerService(context)
    • new DropBoxManagerService()
    • new WallpaperManagerService(context)
    • new AudioService(context)
    • new HeadsetObserver(context)
    • new DockObserver()
    • new UsbObserver(context)
    • new UiModeManagerService(context)
    • new BackupManagerService(context)
    • new AppWidgetService(context)
    • new RecognitionManagerService(context)
    • new DiskStatsService(context)
    • new AdbSettingsObserver
    • VMRuntime.getRuntime().startJitCompilation()
  9. この後、生成したサービスの一部のsystemReady()メソッドを実行していく
  10. Looper.loop()

とまぁ、こんな処理が長々と一つのメソッドに・・・・長いわ!と途中で放り投げたくなるところでしたけど。余所からアクセスできるようにするものは、ServiceManager#addServiceしています。とりあえずにしておきました。なお、メソッドがstaticか否かまで確かめ切れていないので、色々記載に間違いがある気もしていますが・・・とりあえずメモ書きレベルだということでお許し下さい。

名前からもなんとなく想像がつきますが、Threadは、これらのクラス群の処理の中で生成、runされていくのではないでしょうか。近いうちにこのあたりも追いかけてみたいなと思います。

さて、このsystem_processも重要なのですが、先日psコマンドの一覧をtreeにして日記にあげた通り、他のJavaアプリケーションも、それぞれZygoteを親として生成されたVMプロセスとして動作しています。
  • jp.co.omronsoft.openwnn
  • com.android.phone
  • com.android.systemui
  • com.android.launcher
  • android.process.acore
  • com.android.mms
  • android.process.media
  • com.android.deskclock
  • com.android.email
  • com.android.protips
  • com.android.music
  • com.android.quicksearchbox
ここで気になるのが、第三回の勉強会で @l_b__ さんが疑問視されていた、Javaアプリを起動しているのは誰?という話です。
Zygoteが親なので、fork自体はZygoteプロセスなのでしょうが、誰がどのように起動しているものやら。このあたりも追いかけて次回のPF部のお題にあげたいところだったりします。