coreファイルを使ったgoのデバッグ

以下の記事を参考にcore dumpからgoプログラムのデバッグする方法をためしてみた。

Analyzing Core Dump Generated By Go Program - Speaker Deck

C言語の場合gdbを使うが、go言語の場合、dlvを使うようだ。

覚えておいて損はなさそう。ただし、macosではcoreファイルが作成されないようだ。残念。

$ ulimit -c unlimited
$ cat main.go
package main

func main() {
    var p *int
    p = nil
    *p = 1
}

$ export GOTRACEBACK=crash
$ go build main.go
$ ./main
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x44ebb2]

goroutine 1 [running]:
panic(0x45d560, 0x4b7ce0)
    /usr/local/go/src/runtime/panic.go:556 +0x2cb fp=0xc000032720 sp=0xc000032690 pc=0x421edb
runtime.panicmem()
    /usr/local/go/src/runtime/panic.go:82 +0x5e fp=0xc000032740 sp=0xc000032720 pc=0x420f1e
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:390 +0x182 fp=0xc000032790 sp=0xc000032740 pc=0x4342f2
main.main()
    /home/unokun/work/go/main.go:6 +0x2 fp=0xc000032798 sp=0xc000032790 pc=0x44ebb2
runtime.main()
    /usr/local/go/src/runtime/proc.go:201 +0x207 fp=0xc0000327e0 sp=0xc000032798 pc=0x423bc7
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000327e8 sp=0xc0000327e0 pc=0x448d21

goroutine 2 [force gc (idle)]:
runtime.gopark(0x470bd8, 0x4b9ae0, 0x1410, 0x1)
    /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc000032f80 sp=0xc000032f60 pc=0x423fab
runtime.goparkunlock(0x4b9ae0, 0x1410, 0x1)
    /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc000032fb0 sp=0xc000032f80 pc=0x424053
runtime.forcegchelper()
    /usr/local/go/src/runtime/proc.go:251 +0xb3 fp=0xc000032fe0 sp=0xc000032fb0 pc=0x423e23
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000032fe8 sp=0xc000032fe0 pc=0x448d21
created by runtime.init.4
    /usr/local/go/src/runtime/proc.go:240 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x470bd8, 0x4b9ba0, 0x41140c, 0x1)
    /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc000033780 sp=0xc000033760 pc=0x423fab
runtime.goparkunlock(0x4b9ba0, 0x47140c, 0x1)
    /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc0000337b0 sp=0xc000033780 pc=0x424053
runtime.bgsweep(0xc000052000)
    /usr/local/go/src/runtime/mgcsweep.go:52 +0x8f fp=0xc0000337d8 sp=0xc0000337b0 pc=0x418a9f
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000337e0 sp=0xc0000337d8 pc=0x448d21
created by runtime.gcenable
    /usr/local/go/src/runtime/mgc.go:216 +0x58
[1]    29625 abort (core dumped)  ./main

$ ls
core.29625  main  main.go

$ dlv core main core.29625
Type 'help' for list of commands.
(dlv) bt
 0  0x000000000044a624 in runtime.raise
    at /usr/local/go/src/runtime/sys_linux_amd64.s:146
 1  0x00000000004344ab in runtime.dieFromSignal
    at /usr/local/go/src/runtime/signal_unix.go:424
 2  0x0000000000434928 in runtime.sigfwdgo
    at /usr/local/go/src/runtime/signal_unix.go:629
 3  0x0000000000433d08 in runtime.sigtrampgo
    at /usr/local/go/src/runtime/signal_unix.go:289
 4  0x000000000044a913 in runtime.sigtramp
    at /usr/local/go/src/runtime/sys_linux_amd64.s:353
 5  0x000000000044aa00 in runtime.sigreturn
    at /usr/local/go/src/runtime/sys_linux_amd64.s:445
 6  0x000000000043466a in runtime.crash
    at /usr/local/go/src/runtime/signal_unix.go:518
 7  0x00000000004224d7 in runtime.fatalpanic
    at /usr/local/go/src/runtime/panic.go:708
 8  0x0000000000421edb in runtime.gopanic
    at /usr/local/go/src/runtime/panic.go:556
 9  0x0000000000420f1e in runtime.panicmem
    at /usr/local/go/src/runtime/panic.go:82
10  0x00000000004342f2 in runtime.sigpanic
    at /usr/local/go/src/runtime/signal_unix.go:390
11  0x000000000044ebb2 in main.main
    at ./main.go:6
12  0x0000000000423bc7 in runtime.main
    at /usr/local/go/src/runtime/proc.go:201
13  0x0000000000448d21 in runtime.goexit
    at /usr/local/go/src/runtime/asm_amd64.s:1333
(dlv) frame 11
> runtime.raise() /usr/local/go/src/runtime/sys_linux_amd64.s:146 (PC: 0x44a624)
Warning: debugging optimized function
Frame 11: ./main.go:6 (PC: 44ebb2)
     1: package main
     2:
     3: func main() {
     4:     var p *int
     5:     p = nil
=>   6:      *p = 1
     7: }
(dlv) locals
p = (unreadable empty OP stack)
(dlv) disass
TEXT main.main(SB) /home/unokun/work/go/main.go
    main.go:6   0x44ebb0    31c0        xor eax, eax
    main.go:6   0x44ebb2    48c70001000000  mov qword ptr [rax], 0x1
    main.go:7   0x44ebb9    c3      ret
(dlv) regs
...
     Rax = 0x0000000000000000
...
(dlv)

Spring Boot(Jar)ファイルをAzure App Serviceにデプロイしてみました

以下の記事を参考にSpring Boot(Jar)ファイルをAzure App Serviceにデプロイしてみました。

Maven と Azure を使用して Spring Boot JAR ファイルのアプリをクラウドにデプロイする | Microsoft Docs

ポイントは、Azure CLIでpomを書き換えるところです。

ここでデプロイ先、モジュール(Jar/War)を決めることができます。後はデプロイするだけです。

Azure CLI のインストールは以下を参照してください。 Azure CLI のインストール | Microsoft Docs

spring-bootのサンプルアプリを使うので簡単に試すことができました。

手順

$ git clone https://github.com/spring-guides/gs-spring-boot
$ cd gs-spring-boot/complete

# ビルド & 実行
$ ./mvnw clean package
$ ./mvnw spring-boot:run

# 動作確認します
$ curl http://localhost:8080

# pom のbuildセクションに追加します。
$ cat pom.xml
<plugin>
 <groupId>com.microsoft.azure</groupId>
 <artifactId>azure-webapp-maven-plugin</artifactId>
 <version>1.6.0</version>
</plugin>

$ ./mvnw azure-webapp:config
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< org.springframework:gs-spring-boot >-----------------
[INFO] Building gs-spring-boot 0.1.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- azure-webapp-maven-plugin:1.6.0:config (default-cli) @ gs-spring-boot ---
[WARNING] The plugin may not work if you change the os of an existing webapp.
Define value for OS(Default: Linux):
1. linux [*]
2. windows
3. docker
Enter index to use:
Define value for javaVersion(Default: jre8):
1. jre8 [*]
2. java11
Enter index to use:
Define value for runtimeStack(Default: TOMCAT 8.5):
1. TOMCAT 9.0
2. jre8
3. TOMCAT 8.5 [*]
4. WILDFLY 14
Enter index to use: 2
Please confirm webapp properties
AppName : gs-spring-boot-1559091271202
ResourceGroup : gs-spring-boot-1559091271202-rg
Region : westeurope
PricingTier : Premium_P1V2
OS : Linux
RuntimeStack : JAVA 8-jre8
Deploy to slot : false
Confirm (Y/N)? : Y

# pomのpluginセクションに追加されていることを確認します。

# デプロイします
$ ./mvnw clean package
$ ./mvnw azure-webapp:deploy

Home - Microsoft Azureにデプロイされていることを確認しブラウザでアクセスしてみます。

以下の画面が表示されれば成功です。 f:id:unokun3:20190804153850p:plain

GraalVMを試してみました

遅まきながら、GraalVMのサイトのGetting Startを試してみました。

Getting started with GraalVM

試してみるようdockerイメージが用意されています。Docker Desktopをインストール済みであればこれを使うのが簡単です。

サイトには、Node、RubyPythonを使ったサンプルもありますがまずはJavaで試してみました。

手順

# docker image取得
$ docker pull oracle/graalvm-ce:19.1.1

# docker imageに接続
$ docker run -it oracle/graalvm-ce:19.1.1 bash
bash-4.2# 

# 気持ち的にrootにファイルは作成しにくい
bash-4.2# cd home

# "Hello Word!"を出力するjavaファイル作成
bash-4.2# vi HelloWorld.java

bash-4.2# cat HelloWorld.java
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

bash-4.2# javac HelloWorld.java
bash-4.2# java HelloWorld
Hello, World!

# native-imageを作成
# デフォルトでは入っていないのでダウンロードする
bash-4.2# install native-image
bash-4.2# native-image HelloWorld
bash-4.2# ./helloWorld
Hello, World!

# バイナリをhexdumpする
# elfファイルになっている。
bash-4.2# hexdump -C helloworld | head
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  00 10 40 00 00 00 00 00  |..>.......@.....|
00000020  40 00 00 00 00 00 00 00  d0 0c 23 00 00 00 00 00  |@.........#.....|
00000030  00 00 00 00 40 00 38 00  09 00 40 00 26 00 25 00  |....@.8...@.&.%.|
00000040  06 00 00 00 05 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
00000050  40 00 40 00 00 00 00 00  40 00 40 00 00 00 00 00  |@.@.....@.@.....|
00000060  f8 01 00 00 00 00 00 00  f8 01 00 00 00 00 00 00  |................|
00000070  08 00 00 00 00 00 00 00  03 00 00 00 04 00 00 00  |................|
00000080  38 02 00 00 00 00 00 00  38 02 40 00 00 00 00 00  |8.......8.@.....|
00000090  38 02 40 00 00 00 00 00  1c 00 00 00 00 00 00 00  |8.@.............|

# ファイルサイズ
bash-4.2# ls -l
total 2256
-rwxr-xr-x 1 root root 2299472 Jul 21 01:23 helloworld
-rw-r--r-- 1 root root     427 Jul 21 01:20 HelloWorld.class
-rw-r--r-- 1 root root     116 Jul 21 01:20 HelloWorld.java

# 実行時間
bash-4.2# time ./helloworld
Hello, World!

real    0m0.002s
user    0m0.000s
sys 0m0.000s
bash-4.2# java HelloWorld
Hello, World!
bash-4.2# time java HelloWorld
Hello, World!

real    0m0.076s
user    0m0.060s
sys 0m0.000s

以下の記事はJavaフレームワークをnative-imageで起動した結果です。今後の動きから目が離せません。

きしだのHatena

あと、同じ著者が書いたこの記事も参考になります。 native-imageとJITは同程度だと思っていたのですが、JITの方がこんなに早いとは思いませんでした。

GraalVMはどれだけ遅いか - きしだのHatena

pyOxidizerを試しててみました

以下のページを参考にしてpyOxidizerを試してみました。 PyOxidizer を試してみた - Qiita

python環境を持ち運ぶ(repl)として使うとか、アプリをpythonをインストールしていない環境で実行するなど使い道はありそうです。

環境

macOS Mojave 10.14.5

事前準備

rust環境をインストールする必要があります。 homebrewでインストールした場合pyOxidizerに必要なモジュールがインストールされないので、rustセットアップシェルを実行しました。

$ curl https://sh.rustup.rs -sSf | sh

アプリ環境作成

$ pyoxidizer init pyapp

pythonファイル作成

パッケージのルートディレクトに作成します。

$ cat helloworld.py
print("hello world")

設定ファイル()編集

$ cat pyoxidizer.toml
# Package .py files discovered in a local directory.
[[packaging_rule]]
type = "package-root"
path = "."
packages = ["helloworld"]

[[embedded_python_run]]
# Run an interactive Python interpreter.
#mode = "repl"     <-- init時にはここが有効になっています 

# Import a Python module and run it.
mode = "module"
module = "helloworld"
#module = "mypackage.__main__"

ビルド & 実行

$  pyoxidizer build
$  pyoxidizer run
packaging application into /.../pyapp/build/apps/pyapp/debug
purging /.../pyapp/build/apps/pyapp/debug
copying /.../pyapp/build/target/x86_64-apple-darwin/debug/pyapp to /.../pyapp/build/apps/pyapp/debug/pyapp
resolving packaging state...
pyapp packaged into /.../pyapp/build/apps/pyapp/debug
hello world

ファイルサイズは約27M。

$ ls -l build/target/x86_64-apple-darwin/debug/pyapp
-rwxr-xr-x  2 unokun  staff  27291660  7 14 09:23 build/target/x86_64-apple-darwin/debug/pyapp

リンク

SwiftUIチュートリアル(Landmarks)を試してみました

遅ればせながら、SwiftUIチュートリアル(Landmarks)を試してみました。

Creating and Combining Views — SwiftUI Tutorials | Apple Developer Documentation

MacOS 10.15(beta)を使っていれば、XCode project内のpreviewを見ながら開発できるので便利そうです。 MacOS 10.15が待ち遠しいです。

チュートリアルもよく出来ておりわかりやすいです。

f:id:unokun3:20190623112721p:plain

参考

Windows版Leelaを使って見ました

ニューラルネットベースの囲碁AI梱包のLeelaを使って見ました。 簡単にインストールできるので興味がある人は使ってみると良いと思います。

設定

ニューラルネットワークを使うがチェックされています。 人間 vs Leela、Leela vs Leelaが選択できます。

f:id:unokun3:20190526095500p:plain

棋譜読み込み

SGFファイル形式のファイルを読み込むことができます。 自分の棋譜はもちろん、公開されている棋譜も読み込むことができます。 f:id:unokun3:20190526095422p:plain

最善手選択

メニューから「Show Best Move」を選択する(あるいはF4をクリックする)と最善手(候補一覧)が表示されます。 f:id:unokun3:20190526100052p:plain

リンク

AWS Cloud9に移行しました

Cloud9が終了するということでAWS Cloud9に移行しました。 とても親切な移行手順だったので特に困ることはありませんでした。

12月まで使えると思っていましたので、6月30日に使えなくなるのに驚きました。 f:id:unokun3:20190519134515p:plain

メールはちゃんと読まないといけませんね....

we plan to discontinue the ability to create new or to use existing workspaces on c9.io on June 30, 2019 and to discontinue all access on December 31, 2019. We would love it if you would join us on AWS Cloud9.