Julia - ソースコードを読んでみる

gdb を使って Julia のソースコードを追ってみる

環境

gdbソースコードリーディング

gdb で追う場合ソースコードからビルドする必要がある。

$ wget https://github.com/JuliaLang/julia/releases/download/v1.3.0/julia-1.3.0-full.tar.gz
$ tar xvf julia-1.3.0-full.tar.gz
$ cd julia-1.3.0
$ export JULIA_BUILD_MODE=debug
$ make
$ ./julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.3.0 (2019-11-26)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

julia> 

新規にターミナルを開いて

$ ps aux | grep julia
arch       14398  3.4  2.4 537996 195032 pts/0   Sl+  20:20   0:00 ./julia

$ gdb -p 14398      # 起動中の Julia の pid に attach

(gdb) b jl_arrayset # 適当なところに breakpoint を入れる
Breakpoint 1 at 0x7f1f71a38e70: file /home/arch/.local/julia/julia-1.3.0/src/array.c, line 568.
(gdb) c
Continuing.

# REPL に戻って適当に x = [1, 2] とか打ってみる

Thread 1 "julia" hit Breakpoint 1, jl_arrayset (a=0x7f1f63aa77f0, rhs=0x7f1f611ee050, i=i@entry=0)
    at /home/arch/.local/julia/julia-1.3.0/src/array.c:568
568    {

(gdb) n
802        return jl_svec_data(t)[i];

(gdb) 
571        if (eltype != (jl_value_t*)jl_any_type) {

(gdb) p jl_any_type
$1 = (jl_datatype_t *) 0x7fd8d9b601d0 <jl_system_image_data+16>

(gdb) ptype jl_datatype_t
type = struct _jl_datatype_t {
    jl_typename_t *name;
    struct _jl_datatype_t *super;
    jl_svec_t *parameters;
    jl_svec_t *types;
    jl_svec_t *names;
    jl_value_t *instance;
    const jl_datatype_layout_t *layout;
    int32_t size;
    int32_t ninitialized;
    uint32_t uid;
    uint8_t abstract;
    uint8_t mutabl;
    uint8_t hasfreetypevars;
    uint8_t isconcretetype;
    uint8_t isdispatchtuple;
    uint8_t isbitstype;
    uint8_t zeroinit;
    uint8_t isinlinealloc;
    uint8_t has_concrete_subtype;
    void *struct_decl;
    void *ditype;
}
 
(gdb) ptype jl_svec_t
type = struct {
    size_t length;
}

(gdb) p jl_any_type->parameters->length
$20 = 0

その時その時にどんな値が入ってきているのかわかって面白い。

gdbptrace: operation not permitted. と出たら以下を打つ

$ sudo su -
# echo 0 > /proc/sys/kernel/yama/ptrace_scope

stackoverflow.com

お試し用の Dockerfile

github.com