曲曲的秘密学术基地

纯化欲望、坚持严肃性

欢迎!我是曲泽慧(@zququ),目前在深圳(ICBI,BCBDI,SIAT)任职助理研究员。


病毒学、免疫学及结构生物学背景,可以在 RG 上找到我已发表的论文

本站自2019年7月已访问web counter

My lldb cheat sheet

Do my summarize about the official tutorial

Command structure

<noun> <verb> [-options [optian-value]] [argument [argument...]]

For example:

breakpoint set --name foo
breakpoint set -n foo

And make a breakpoint on a set of functions,

breakpoint set --name foo --name bar

Also can set breakpoint for a method:

breakpoint set -method foo
or
breakpoint set -M foo

For a selector or specific executable image:

# for selector
breakpoint set --selector aligenLeftEdges:
or 
breakpoint set -S aligenLeftEdges:

# for shlib
breakpoint set --shlib foo.dylib --name foo
or
breakpoint set -s foo.dylib -n foo

If set breakpoint to specific line of specific file:

breakpoint set --file foo.c --line 12

To give a short alias for this command:

command alias bfl breakpoint set -f %1 -l %2
# for short:
bfl foo.c 12

# or alias to a much simple single alphabet
command alias b breakpoint

Program loading

lldb "file dir" # in shell
or
(lldb) file "file dir"

Settings breakpoint

# find out about the breakpoints
(lldb) breakpoint list

After setting the breakpoint, if no locations were found, there will be the warning:

(lldb) breakpoint set --file foo.c --line 12
Breakpoint created: 2: file ='foo.c', line = 12, locations = 0 (pending)
WARNING: Unable to resolve breakpoint to any actual locations.

It just like to activate the pending mode in gdb

(gdb) set breakpoint pending on

After setting the breakpoint successfully,

(lldb) breakpoint list
Current breakpoints:
1: name = 'alignLeftEdges:', locations = 1, resolved = 1
1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0

Note the ID 1.1 , you can do operations on it, like:

(lldb) breakpoint command add 1.1
Enter your debugger command(s). Type 'DONE' to end.
> bt
> DONE

Here, add can add a set of command so a breakpoint, you can find further help by:

(lldb) help break command add
Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit.

Syntax: breakpoint command add <cmd-options> <breakpt-id>
etc...

Breakpoint names

You can modify the name of breakpoint, e.g.:

(lldb) breakpoint modify -c "self == nil" -C bt --auto-continue 1 2 3
# modify          : modify the breakpoint
# -c "expression" : set condition of when to break
# -C "command"    : what command will be executed when break
# --auto-continue : program will not stop during lldb running
# 1 2 3           : breakpoint ID

To avoid needing to input breakpoint ID every time, it may be more simple to give a name:

breakpoint set -N SelfNil

You can also use another logical operation to do the same thing, using:

(lldb) breakpoint name configure -c "self == nil" -C bt --auto-continue SelfNil
# do breakpoint name configure operation if condition fulfiled

All command lines here are used when all the breakpoints are selected, if only one breakpoint is needed:

(lldb) breakpoint name configure -B 1 SelfNil
# only breakpoint will be selected to name as SlfNil

Setting watchpoints

Watchpoint is different from breakpoint, for breakpoint, it just include when the program stop. While watchpoint will watch the memory or the variable value changee, e.g.:

(lldb) watch set var global
Watchpoint created: Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
   declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
# tell which variable will be watched (`global` here)

(lldb) watch modify -c '(global==5)'
# tell when watch operation will be executed (`global==5` here)

(lldb) watch list
Current watchpoints:
Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
   declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
   condition = '(global==5)'
# list all watchpoints and show their ID.

(lldb) c
Process 15562 resuming
(lldb) about to write to 'global'...
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped
* thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1
   frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16
   13
   14        static void modify(int32_t &var) {
   15            ++var;
-> 16        }
   17
   18        int main(int argc, char** argv) {
   19            int local = 0;
# continue

(lldb) bt
* thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1
   frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16
   frame #1: 0x0000000100000eac a.out`main + 108 at main.cpp:25
   frame #2: 0x00007fff8ac9c7e1 libdyld.dylib`start + 1
# backtrace

(lldb) frame var global
(int32_t) global = 5
# watch the variable value every frame

(lldb) watch list -v
Current watchpoints:
Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
   declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
   condition = '(global==5)'
   hw_index = 0  hit_count = 5     ignore_count = 0
(lldb)
# give the watch point in verbose

Starting or attaching to your program

To run your program:

(lldb) process launch
(lldb) run
(lldb) r
# all of the raw command or alias are ok

If you want to attach a debugger to some process, you can do:

(lldb) process attach --pid 123
# attach the process by pid

(lldb) process attach --name Sketch
# attach the process by process name

(lldb) process attach --name Sketch --waitfor
# wait for the naxt process named Sketch to attach

After attach the debugger, when your process stop, there will output the reason, e.g.

(lldb) process attach -p 12345
Process 46915 Attaching
Process 46915 Stopped
1 of 3 threads stopped with reasons:
* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread
# here we can see one of the threads is stopped because of some reason.

Controlling your program

After the program has meet the breakpoint and stop, if we hope to continue our program:

(lldb) thread continue
Resuming thread 0x2c03 in process 46915
Resuming process 46915

However, thread continue only can make program continue until next breakpoint is meet, if we need more operations, we can do:

(lldb) thread step-in
or
(lldb) step
or
(lldb) s
# analyse the code one-by-one step. 

(lldb) thread step-out
or
(lldb) next
or
(lldb) n
# continue to run the program until this function has returned, used when you are not interested in this function.

(lldb) thread step-over
or
(lldb) finish
or
(lldb) f

# continue analyse the program one-by-one step, but don't step in any other funcion, means only concentrate in this function.

If you want to have a step by instruction versions,

(lldb) thread step-inst         // which is same as (gdb) stepi or (gdb) si

(lldb) thread step-over-inst    // which is same as (gdb) nexti or (gdb) ni

To avoid running for too long, lldb has a run until line or frame exit stepping mode:

(lldb) thread until 100

Sometimes, we don’t want to interrupt the interface, we can use

(lldb) process launch --stdio=/path/to/logfile.txt

which can be canceled by

(lldb) settings set tartget.process.disable-stdio true

If you can set a breakpoint and stop at a function or something,

(lldb) process continue
(lldb) breakpoint set --name stop_here // stop_here is a function or some named variable

And there are commands that currently work while running include

(lldb) process interrupt
(lldb) process status
(lldb) breakpoint [set|clear|enalbe|disable|list] ...

Examining thread state

(lldb) thread list
Process 46915 state is Stopped
* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread
thread #2: tid = 0x2e03, 0x00007fff85cbb08a, where = libSystem.B.dylib`kevent + 10, queue = com.apple.libdispatch-manager
thread #3: tid = 0x2f03, 0x00007fff85cbbeaa, where = libSystem.B.dylib`__workq_kernreturn + 10

The * indicates that Thread 1 is the current thread. To get a backtrace for that thread, do:

(lldb) thread backtrace
thread #1: tid = 0x2c03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: 0x0000000100010d5b, where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405
frame #1: 0x00007fff8602d152, where = AppKit`-[NSApplication sendAction:to:from:] + 95
frame #2: 0x00007fff860516be, where = AppKit`-[NSMenuItem _corePerformAction] + 365
frame #3: 0x00007fff86051428, where = AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 121
frame #4: 0x00007fff860370c1, where = AppKit`-[NSMenu performKeyEquivalent:] + 272
frame #5: 0x00007fff86035e69, where = AppKit`-[NSApplication _handleKeyEquivalent:] + 559
frame #6: 0x00007fff85f06aa1, where = AppKit`-[NSApplication sendEvent:] + 3630
frame #7: 0x00007fff85e9d922, where = AppKit`-[NSApplication run] + 474
frame #8: 0x00007fff85e965f8, where = AppKit`NSApplicationMain + 364
frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11
frame #10: 0x0000000100000f20, where = Sketch`start + 52

You can also provide a threads to backtrace or see all threads by,

(lldb) thread backtrace all

Or select to change the default current thread,

(lldb) thread select 2

Examining stack frame state

The most convenient way,

(lldb) frame variable
self = (SKTGraphicView *) 0x0000000100208b40
_cmd = (struct objc_selector *) 0x000000010001bae1
sender = (id) 0x00000001001264e0
selection = (NSArray *) 0x00000001001264e0
i = (NSUInteger) 0x00000001001264e0
c = (NSUInteger) 0x00000001001253b0

Or specify which variable

(lldb) frame variable self.isa
(struct objc_class *) self.isa = 0x0000000100023730

Which support some simple operations like &, *, ->, []

(lldb) frame variable *self
(SKTGraphicView *) self = 0x0000000100208b40
(NSView) NSView = {
(NSResponder) NSResponder = {
...

(lldb) frame variable &self
(SKTGraphicView **) &self = 0x0000000100304ab

(lldb) frame variable argv[0]
(char const *) argv[0] = 0x00007fff5fbffaf8 "/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS/Sketch"

(lldb) frame variable pStruct->field

In which,

'&'  : get the variable address
'*'  : get the pointer address
'->' : vist the member in struct
'[]' : get specific element in the array

When need to perform “object printing”

(lldb) frame variable -o self (SKTGraphicView *) self = 0x0000000100208b40 <SKTGraphicView: 0x100208b40>
You can select another frame to view with the "frame select" command

(lldb) frame select 9
frame #9: 0x0000000100015ae3, where = Sketch`function1 + 33 at /Projects/Sketch/SKTFunctions.m:11

basal commands

b   # breakpoint
r   # run
s   # step in
n   # next step
bt  # stack
f   # frame
c   # continue

Usually used commands

b test.c:12       // set breakpoint
p data            // print data
set -- test 1 2 3 // set parameter
bt 5              // print recent 5 layers fram
x/4xb data        // print former 4 hexadecimal bytes
x/4tb data        // print former 4 binary bytes

An example:

#inclue <stdio.h>
void to_upper(char *data) {
    for(int i = 0; data; i++)} {
        if(data[i] > = 'a' && data[i] <= 'z') {
            data[i] -= 32
        }
        printf("data = %s", data)
    }
}
int main(int argv, char** argc) {
    char *data = "Hello, World";
    to_upper(data);
    puts("main end.");
    return 0};
}
$ gcc -g test.c -o test // -g save the debug information
$ lldb // enter lldb
(lldb) file test // input the file test
(lldb) settings set target.run-args helloword // give the args in test.c (helloword)
(lldb) b test.c:12 // give the breakpoint at line 12
(lldb) r // run
(lldb) p argv  // print argv
(lldb) p argc[0] // print argc[0] -> the file path
(lldb) p argc[1] // print argc[1] -> "Hello, Word"
(11db) p argc[2] // blank value
(11db) s // enter the function
(11db) n // step out
(11db) q // quit
Next One

Parseval 定理的数学推导

Parseval 描述信号在时域以及频域上有着相同的能量这一关系,数学表达为:$$\mathfrak{F}{\lbrace x(t) \rbrace} = X(f)$$$$\int_{-\infty}^{\infty} \lvert x(t)\rvert ^2 \mathrm{d}t = \int_{-\infty}^{\infty} \lvert X(f)\rvert ^2 \mathrm{d}f$$定义一组可以在时域与频域相互转换的信号关系式,为了证明这一点,分别表示在时域和频域上的能...…

cryoEMMore