OpenSource版swiftでLLDB Debuggerを使ってみました
概要
ここを参考にして、OpenSource版swiftでLLDB Debuggerを使ってみました。GDB風のソースデバッグが可能です。
OSは、Ubuntu14.04です。
$ swift -version Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 778f82939c) Target: x86_64-unknown-linux-gnu
デバッグ手順
ソース作成
階乗計算処理を実行するswiftソースを作成します。
$ cat Factorial.swift func factorial(n: Int) -> Int { if n <= 1 { return n } return n * factorial(n - 1) } let number = 4 print("\(number)! is equal to \(factorial(number))")
ビルド
デバッグ情報付きでビルドします。
$ swiftc -g Factorial.swift $ ls -l 合計 32 -rwxrwxr-x 1 unokun unokun 24952 12月 20 16:58 Factorial -rw-rw-r-- 1 unokun unokun 161 12月 20 16:57 Factorial.swift
デバッグ
ビルドしたモジュールをデバッグします。
$ lldb Factorial (lldb) target create "Factorial" Current executable set to 'Factorial' (x86_64).
ソースコードの2行目にブレイクポイントを設定します。
(lldb) b 2 Breakpoint 1: where = Factorial`Factorial.factorial (Swift.Int) -> Swift.Int + 12 at Factorial.swift:2, address = 0x0000000000400f1c
プログラムを実行します。
ブレークポイントにヒットすると、止まっている場所がソースコードと一緒に表示されます。
(lldb) r Process 3497 launched: '/home/unokun/work/factorial/Factorial' (x86_64) Process 3497 stopped * thread #1: tid = 3497, 0x0000000000400f1c Factorial`factorial(n=4) -> Int + 12 at Factorial.swift:2, name = 'Factorial', stop reason = breakpoint 1.1 frame #0: 0x0000000000400f1c Factorial`factorial(n=4) -> Int + 12 at Factorial.swift:2 1 func factorial(n: Int) -> Int { -> 2 if n <= 1 { return n } 3 return n * factorial(n - 1) 4 } 5 let number = 4 6 print("\(number)! is equal to \(factorial(number))")
変数の値を出力します。
(lldb) p n (Int) $R0 = 4
バックトレースを出力します。
(lldb) bt * thread #1: tid = 3497, 0x0000000000400f1c Factorial`factorial(n=4) -> Int + 12 at Factorial.swift:2, name = 'Factorial', stop reason = breakpoint 1.1 * frame #0: 0x0000000000400f1c Factorial`factorial(n=4) -> Int + 12 at Factorial.swift:2 frame #1: 0x0000000000400e53 Factorial`main + 291 at Factorial.swift:6 frame #2: 0x00007ffff6be7ec5 libc.so.6`__libc_start_main(main=(Factorial`main at Factorial.swift), argc=1, argv=0x00007fffffffe308, init=, fini= , rtld_fini= , stack_end=0x00007fffffffe2f8) + 245 at libc-start.c:287 frame #3: 0x0000000000400c69 Factorial
lldbのコマンド一覧
helpと入力するとコマンド一覧が表示されます。
(lldb) help Debugger commands: apropos -- Find a list of debugger commands related to a particular word/subject. breakpoint -- A set of commands for operating on breakpoints. Also see _regexp-break. bugreport -- Set of commands for creating domain specific bugreports. command -- A set of commands for managing or customizing the debugger commands. disassemble -- Disassemble bytes in the current function, or elsewhere in the executable program as specified by the user. expression -- Evaluate an expression (ObjC++ or Swift) in the current program context, using user defined variables and variables currently in scope. frame -- A set of commands for operating on the current thread's frames. gdb-remote -- Connect to a remote GDB server. If no hostname is provided, localhost is assumed. gui -- Switch into the curses based GUI mode. help -- Show a list of all debugger commands, or give details about specific commands. kdp-remote -- Connect to a remote KDP server. udp port 41139 is the default port number. language -- A set of commands for managing language-specific functionality.'. log -- A set of commands for operating on logs. memory -- A set of commands for operating on memory. platform -- A set of commands to manage and create platforms. plugin -- A set of commands for managing or customizing plugin commands. process -- A set of commands for operating on a process. quit -- Quit out of the LLDB debugger. register -- A set of commands to access thread registers. script -- Pass an expression to the script interpreter for evaluation and return the results. Drop into the interactive interpreter if no expression is given. settings -- A set of commands for manipulating internal settable debugger variables. source -- A set of commands for accessing source file information target -- A set of commands for operating on debugger targets. thread -- A set of commands for operating on one or more threads within a running process. type -- A set of commands for operating on the type system version -- Show version of LLDB debugger. watchpoint -- A set of commands for operating on watchpoints. Current command abbreviations (type 'help command alias' for more info): add-dsym -- ('target symbols add') Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for. attach -- ('_regexp-attach') Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to. b -- ('_regexp-break') Set a breakpoint using a regular expression to specify the location, whereis in decimal and is in hex. bt -- ('_regexp-bt') Show a backtrace. An optional argument is accepted; if that argument is a number, it specifies the number of frames to display. If that argument is 'all', full backtraces of all threads are displayed. c -- ('process continue') Continue execution of all threads in the current process. call -- ('expression --') Evaluate an expression (ObjC++ or Swift) in the current program context, using user defined variables and variables currently in scope. continue -- ('process continue') Continue execution of all threads in the current process. detach -- ('process detach') Detach from the current process being debugged. di -- ('disassemble') Disassemble bytes in the current function, or elsewhere in the executable program as specified by the user. dis -- ('disassemble') Disassemble bytes in the current function, or elsewhere in the executable program as specified by the user. display -- ('_regexp-display') Add an expression evaluation stop-hook. down -- ('_regexp-down') Go down "n" frames in the stack (1 frame by default). env -- ('_regexp-env') Implements a shortcut to viewing and setting environment variables. exit -- ('quit') Quit out of the LLDB debugger. f -- ('frame select') Select a frame by index from within the current thread and make it the current frame. file -- ('target create') Create a target using the argument as the main executable. finish -- ('thread step-out') Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified). image -- ('target modules') A set of commands for accessing information for one or more target modules. j -- ('_regexp-jump') Sets the program counter to a new address. jump -- ('_regexp-jump') Sets the program counter to a new address. kill -- ('process kill') Terminate the current process being debugged. l -- ('_regexp-list') Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands. list -- ('_regexp-list') Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands. n -- ('thread step-over') Source level single step in specified thread (current thread, if none specified), stepping over calls. next -- ('thread step-over') Source level single step in specified thread (current thread, if none specified), stepping over calls. nexti -- ('thread step-inst-over') Single step one instruction in specified thread (current thread, if none specified), stepping over calls. ni -- ('thread step-inst-over') Single step one instruction in specified thread (current thread, if none specified), stepping over calls. p -- ('expression --') Evaluate an expression (ObjC++ or Swift) in the current program context, using user defined variables and variables currently in scope. po -- ('expression -O -- ') Evaluate an expression (ObjC++ or Swift) in the current program context, using user defined variables and variables currently in scope. print -- ('expression --') Evaluate an expression (ObjC++ or Swift) in the current program context, using user defined variables and variables currently in scope. q -- ('quit') Quit out of the LLDB debugger. r -- ('process launch -X true --') Launch the executable in the debugger. rbreak -- ('breakpoint set -r %1') Sets a breakpoint or set of breakpoints in the executable. repl -- ('expression -r -- ') Evaluate an expression (ObjC++ or Swift) in the current program context, using user defined variables and variables currently in scope. run -- ('process launch -X true --') Launch the executable in the debugger. s -- ('thread step-in') Source level single step in specified thread (current thread, if none specified). si -- ('thread step-inst') Single step one instruction in specified thread (current thread, if none specified). step -- ('thread step-in') Source level single step in specified thread (current thread, if none specified). stepi -- ('thread step-inst') Single step one instruction in specified thread (current thread, if none specified). t -- ('thread select') Select a thread as the currently active thread. tbreak -- ('_regexp-tbreak') Set a one shot breakpoint using a regular expression to specify the location, where is in decimal and is in hex. undisplay -- ('_regexp-undisplay') Remove an expression evaluation stop-hook. up -- ('_regexp-up') Go up "n" frames in the stack (1 frame by default). x -- ('memory read') Read from the memory of the process being debugged.