みちくさを楽しむ

IT関係の雑多な内容の日記

ADBDのビルドをカスタマイズする

研究でAOSPのビルドを少し触ったので、メモとして残しておきます。

 

qiita.com

 

ビルドの環境構築については上の記事や公式サイトの内容を参照してください。

source.android.com

 

上記の手順を元に環境構築ができたら、ビルドのコマンドが実行できます。

 

公式サイトにも書かれていますが、ubuntu18.04以前の環境でビルドを実行するにはdockerコンテナの内部でビルドするとうまくいきました。

 

ubuntu20.04以降では、公式サイトのコマンドのままにするとうまくいきます。

 

adbdのビルド時のコマンドをみる 

lunchコマンドを実行したときに実際にどのようなコマンドが実行されているかを見るには以下のようにできます。ここでは、adbdをビルドするときのコマンド例を示します。

古いバージョンのAOSP

m showcommands adbd

新しいバージョンのAOSP

showcommandsは廃止され、out/verbose.log.gzの中に実行コマンドが書かれています。

 

adbdのビルドをカスタマイズする

古いバージョンのAOSP

adbのソースコードは、system/core/adb配下にあり、ビルドの設定は、 Android.mkファイルに書かれています。

adb - platform/system/core - Git at Google

 

android.googlesource.com

のファイルをいい感じにいじることでadbdのビルドをカスタマイズすることができます。

それぞれの項目は以下のようになっています。

include $(CLEAR_VARS) →前の項目との区切り、変数などをリセットする
LOCAL_SRC_FILES := \ →ビルド対象のファイル
    adb.c \
    backup_service.c \
    fdevent.c \
    transport.c \
    transport_local.c \
    transport_usb.c \
    adb_auth_client.c \
    sockets.c \
    services.c \
    file_sync_service.c \
    jdwp_service.c \
    framebuffer_service.c \
    remount_service.c \
    usb_linux_client.c \
    log_service.c
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif
LOCAL_MODULE := adbd →ビルドするときに指定する名前
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
LOCAL_STATIC_LIBRARIES := liblog libcutils libc libmincrypt
include $(BUILD_EXECUTABLE) →実行ファイルとしてビルドするために必要?

 

新しいバージョンのAOSP

packages/modules/adbにファイルが移動しています。また、デーモン用のファイルとクライアント用のファイルが分かれるようになりました。

android.googlesource.com

このファイルのビルドの設定は、Android.bpというファイルに書かれています。

android.googlesource.com

 

adbdのビルドの内容については以下のようになっています。

cc_binary {
    name: "adbd",
    defaults: ["adbd_defaults", "host_adbd_supported", "libadbd_binary_dependencies"],
    recovery_available: true,
    min_sdk_version: "30",
    apex_available: ["com.android.adbd"],
    srcs: [
        "daemon/main.cpp", →main関数が置かれるファイル
    ],
    cflags: [
        "-D_GNU_SOURCE",
        "-Wno-deprecated-declarations",
    ],
    strip: {
        keep_symbols: true,
    },
    static_libs: [
        "libadb_protos",
        "libadbd",
        "libadbd_services",
        "libasyncio",
        "libcap",
        "liblz4",
        "libminijail",
        "libssl",
    ],
    shared_libs: [
        "libadbd_auth",
    ],
    target: {
        recovery: {
            exclude_shared_libs: [
                "libadb_pairing_auth",
                "libadb_pairing_connection",
            ],
        }
    },
}

この内容やソースコードをいい感じにカスタマイズすれば自分専用のADBDが作れます。

 

ISUCON13にソロ参加した。

 

2023/11/25(土) に開催されたISUCON13に参加しました。

 

swamp というソロチームで参加して結果は32位でした。あと少しで30位だったので、少し悔しさが残りますがまずはFailではなくて結果を残せてよかったです。

あと、おそらくソロの学生という限られた母集団の中では2位かなと思います。(1位のtakonomuraさんには圧倒的差をつけられていますが笑)

 

前回のISUCON12も参加したので2回目の参加ではありますが、前回は外出先からの片手間の参加だったので、実質今回が初参加みたいなものでした。(前回は、mysqlの分割しただけで終わった)

 

今回は、最初の出だしは良くて、一瞬ですが4位になった時もありました!

isucon13の11:38時点の順位表のスクリーンショット

(うれしくてスクショ取りました)

しかし、途中のベンチが止まっている間にした変更で、エラーになってしまい、それの解消に時間がかかったのと、複数台構成にするときにつまってしまい、後半は全然スコアが伸びませんでした。

 

以下やったことの一覧です。(大体、やった順番)

  • getUserStatisticsのN+1の一部解消
  •  インデックスを貼る
  • タグをアプリに乗せる
  • アイコンをファイルに書き出してDBに挿入をやめる
  • usersテーブルにdark_modeカラムを追加する
  • ユーザーのキャッシュ
  • 新たに追加したngwordだけを対象にチェックする。
  • コメントを投稿した際の、ngwordsの判定をSQLを使わずにstrings.Containを使う
  • getLivestreamStatisticsHandlerのN+1の解消
  •  iconのsha256sumの結果のキャッシュ
  •  livestream_tagのキャッシュ
  •  userのキャッシュ
  •  dbを2台目に移行
反省

ドキュメントの読み込みが足りませんでした。特に、dns周りはドキュメントをちゃんと読めておらず、全く触ることができませんでした。また、IconのIf-None-Matchなどについてもちゃんと読めてませんでした。

また、セキュリティグループを意識しない環境で素振りなどをやっていたため、DB分割に時間がかかってしまったり、2台目にinitializeのリクエストを送る方法などで苦労したため、順位表凍結の前の段階から、最後までずっと2台構成にすることに時間を使ってしまいました。ここはちゃんと練習しておくべきでした。

 

ソロ参加ということで、素振りをやってみたり計測ツールを用意したりといった準備をして迎えましたが、まだまだ実力が足りないことがわかりました。来年からは社会人になり学生枠ではなくなりますが、次のIsuconに向けてもっと実力をつけたいなと思います。

最後になりますが、運営していただいた方に感謝を述べたいと思います。ありがとうございました。とても楽しかったです!

 

Goのコードから「Goのコードを生成するためのAstのコード」を自動生成できるツールを作った。

 

概要

Goのコードから「Goのコードを生成するためのAstのコード」を生成するツールを作りました。以下のサイトから利用できます。何を言っているかよく分からないと思うので、以下で詳しく機能を説明します。

 

goast-generator.net

機能紹介

例として、次のGoのコードのAstを生成してみます。

package main
 
import (
"fmt"
)
 
func main() {
fmt.Println("Hello, playground")
}

 

冒頭で紹介したページに飛んで、該当のコードを入力して、左上にあるRunを押します。

goastgeneratorの使い方の例

すると、以下の結果が出力されました。


&ast.File{ Name: ast.NewIdent("main"), Decls: []ast.Decl{ &ast.GenDecl{ Tok: token.IMPORT, Specs: []ast.Spec{ &ast.ImportSpec{ Path: &ast.BasicLit{ Kind: token.STRING, Value: strconv.Quote("fmt"), }, }, }, }, &ast.FuncDecl{ Name: ast.NewIdent("main"), Type: &ast.FuncType{ Params: &ast.FieldList{ List: []*ast.Field{ }, }, Results: &ast.FieldList{ List: []*ast.Field{ }, }, }, Body: &ast.BlockStmt{ List: []ast.Stmt{ &ast.ExprStmt{ X: &ast.CallExpr{ Fun: &ast.SelectorExpr{ X: ast.NewIdent("fmt"), Sel: ast.NewIdent("Println"), }, Args: []ast.Expr{ &ast.BasicLit{ Kind: token.STRING, Value: strconv.Quote("Hello, playground"), }, }, }, }, }, }, }, }, }

 

逆にこれを、復元してみます。次のようなコードで復元できます。

package main
 
import "fmt"
 
func main() {
fmt.Println("Hello, 世界")
fset := token.NewFileSet()
node :=  (上記の出力結果(&ast.Fileからはじまるもの)をコピー)
printer.Fprint(os.Stdout,fset,node)

上のコードを実行してみると下の出力のようになり、正しくAstが作成できていることがわかります。

(実際にgo-playgroudで実行するにはGo Playground - The Go Programming Language )

package main

import "fmt"

func main() {
    fmt.Println("Hello, playground")
}

また、以下のtentenさんの記事で手入力で作ろうとしているコードを入力してみました。

qiita.com

入力したコード

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}

生成したコード

&ast.File{
    Name: ast.NewIdent("main"),
    Decls: []ast.Decl{
        &ast.GenDecl{
            Tok: token.IMPORT,
            Specs: []ast.Spec{
                &ast.ImportSpec{
                    Path: &ast.BasicLit{
                         Kind: token.STRING,
                         Value: strconv.Quote("fmt"),
                    },
                },
            },
        },
        &ast.FuncDecl{
            Name: ast.NewIdent("main"),
            Type: &ast.FuncType{
                Params: &ast.FieldList{
                    List: []*ast.Field{
                    },
                },
                Results: &ast.FieldList{
                    List: []*ast.Field{
                    },
                },
            },
            Body: &ast.BlockStmt{
                List: []ast.Stmt{
                    &ast.ExprStmt{
                        X: &ast.CallExpr{
                            Fun: &ast.SelectorExpr{
                                X: ast.NewIdent("fmt"),
                                Sel: ast.NewIdent("Println"),
                            },
                            Args: []ast.Expr{
                                &ast.BasicLit{
                                     Kind: token.STRING,
                                     Value: strconv.Quote("Hello, 世界"),
                                },
                            },
                        },
                    },
                },
            },
        },
    },
}

tentenさんの記事のコードと同様なコードが出力されることが確認できました。

 

これを活用することで、goの静的解析などでAstを特定のコードに自動的に書き換えたいときなどに使えるのではないかと思っています。

 

作成した経緯

最近、Goの静的解析について興味を持ち、勉強していく中で、GoのAstを使った操作でコードの書き換えを自動化してみたい場面がありました。

 

そこで、Go言語の任意のAstを作るにはどうしたらよいのか調べてみましたが、さきほどの記事のように、手動で作る方法しか見つかりませんでした。

qiita.com


それならば、自分で作ってみようと思って作ったのが上記のサイトです。

入力画面に、Go Playgroundのソースコード (https://github.com/golang/playground)

を流用させていただくことで、ほとんど、サーバーサイドのロジックの作成だけですみました。

 

GoのAstを使った操作をしてみたいという方は、ぜひ使ってみてください!

 

ただし、テストが十分ではないため、対応していない機能やエラーなどがあるかもしれませんので、ご使用の際は自己責任でお願いします。

実装の際は、以下の2つのサイトに大変お世話になりました。

ありがとうございました。

https://yuroyoro.github.io/goast-viewer/

zenn.dev

 

ネットワークスペシャリストに合格しました。

2023ネスぺ合格

 

2023年度のネットワークスペシャリスト試験に合格しました。

 

去年ネスぺに落ちたのを記録するためにこのブログを始めたので、それから1年たちました。去年の記録はこれです。

swamp.hatenablog.jp

 

もし不合格だとここからさらに1年後になるし、受験してから結果が出るまでも2カ月以上待たないと行けないのがいやだったので今回合格出来てとてもうれしいです。

 

去年の点数が 午前2 88点 午後1 75点 午後2 55点で今年の点数が午前2 92点 午後1 79点

午後2 72点なのですべての科目でレベルアップした感があるのもうれしいです。

ただ、午後1は自己採点で60点いくかどうかくらいだったので大分採点が甘いか下駄がある気がします。午後2に関しては合格点は行っている自信はあったのですが、予想よりも少し低い印象を受けました。

やったこと

・情報処理教科書 翔泳社

去年に引きつづきお世話になりました。

去年一周していたので、今年はざっと見て忘れてそうなところを確認する程度でした。

・過去問演習

こちらも去年結構しっかり解いていたので、本番と同じ時間を取って解くことはせずざっと問題をみて復習したり、去年の解かなかった問題を解いたりするといった感じでした。

 

ネスぺに向けて勉強した時間は去年と比べると大分短いですが、去年に行ったYahooのインターンやセキスぺの対策などいろいろ経験・勉強していたのが良かったのかなと思います。

総勉強時間は記録付けてないのでわかりません。

 

最後に

次は忙しさによりますが、データベース受けようと思います。

でも、IPA以外にも普通に簿記とかFPとか勉強してみたさもある。

さくらのレンタルサーバでrubyをインストールする方法

naoya.aja0.com

nehori.com

qiita.com

 

 

さくらのレンタルサーバrubyをインストールする方法について書いてある情報は上記のようにたくさんありましたが、最終的にsyntaxエラーなどがたくさん出てきてうまく行きませんでした。

rbenv とruby-build をgitから持ってきてbashrcなどに書くところまでは上の手順に従えばできます。最終的にinstallする際は、以下の

TMPDIR=~/tmp RUBY_CONFIGURE_OPTS="--disable-dtrace" rbenv install 2.7.2

でいけました。

TMPDIR=~/tmp RUBY_CONFIGURE_OPTS="--disable-dtrace" rbenv install 2.7.2
To follow progress, use 'tail -f /home/user/tmp/ruby-build.000000000000000.log' or pass --verbose
Downloading ruby-2.7.2.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.bz2
Installing ruby-2.7.2...

WARNING: ruby-2.7.2 is nearing its end of life.
It only receives critical security updates, no bug fixes.

pkg: Unable to open '/usr/local/etc/pkg/repos//sakura11-repo.conf':Permission denied
pkg: Insufficient privileges to query the package database
pkg: Unable to open '/usr/local/etc/pkg/repos//sakura11-repo.conf':Permission denied
pkg: Insufficient privileges to query the package database
Installed ruby-2.7.2 to /home/user/local/rbenv/versions/2.7.2

一部エラーがでますが問題なくインストールできます。

 

 

 

cyberagent ワークショプとuteoneに参加した。

cyberagent.connpass.com

 

uteone.jp

 

上の2つに参加しました。どちらもgolangを使うものでした。

最近パフォーマンスチューニングを勉強しているのでどちらも非常に有意義な経験でした。