Skip to content

Commit 4b7b78d

Browse files
authored
Merge pull request #31636 from mikeash/add-debugging-tips
2 parents 1406409 + d50a3f1 commit 4b7b78d

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

docs/DebuggingTheCompiler.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ benefit of all Swift developers.
3737
- [Debugging Swift Executables](#debugging-swift-executables)
3838
- [Determining the mangled name of a function in LLDB](#determining-the-mangled-name-of-a-function-in-lldb)
3939
- [Manually symbolication using LLDB](#manually-symbolication-using-lldb)
40+
- [Viewing allocation history, references, and page-level info](#viewing-allocation-history-references-and-page-level-info)
41+
- [Printing memory contents](#printing-memory-contents)
4042
- [Debugging LLDB failures](#debugging-lldb-failures)
4143
- ["Types" Log](#types-log)
4244
- ["Expression" Log](#expression-log)
@@ -680,6 +682,90 @@ One can perform manual symbolication of a crash log or an executable using LLDB
680682
without running the actual executable. For a detailed guide on how to do this,
681683
see: https://lldb.llvm.org/symbolication.html.
682684

685+
## Viewing allocation history, references, and page-level info
686+
687+
The `malloc_history` tool (macOS only) shows the history of `malloc` and `free`
688+
calls for a particular pointer. To enable malloc_history, you must run the
689+
target process with the environment variable MallocStackLogging=1. Then you can
690+
see the allocation history of any pointer:
691+
692+
malloc_history YourProcessName 0x12345678
693+
694+
By default, this will show a compact call stack representation for each event
695+
that puts everything on a single line. For a more readable but larger
696+
representation, pass -callTree.
697+
698+
This works even when you have the process paused in the debugger!
699+
700+
The `leaks` tool (macOS only) can do more than just find leaks. You can use its
701+
pointer tracing engine to show you where a particular block is referenced:
702+
703+
leaks YourProcessName --trace=0x12345678
704+
705+
Like malloc_history, this works even when you're in the middle of debugging the
706+
process.
707+
708+
Sometimes you just want to know some basic info about the region of memory an
709+
address is in. The `memory region` lldb command will print out basic info about
710+
the region containing a pointer, such as its permissions and whether it's stack,
711+
heap, or a loaded image.
712+
713+
lldb comes with a heap script that offers powerful tools to search for pointers:
714+
715+
(lldb) p (id)[NSApplication sharedApplication]
716+
(id) $0 = 0x00007fc50f904ba0
717+
(lldb) script import lldb.macosx.heap
718+
"crashlog" and "save_crashlog" command installed, use the "--help" option for detailed help
719+
"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.
720+
(lldb) ptr_refs 0x00007fc50f904ba0
721+
0x0000600003a49580: malloc( 48) -> 0x600003a49560 + 32
722+
0x0000600003a6cfe0: malloc( 48) -> 0x600003a6cfc0 + 32
723+
0x0000600001f80190: malloc( 112) -> 0x600001f80150 + 64 NSMenuItem55 bytes after NSMenuItem
724+
0x0000600001f80270: malloc( 112) -> 0x600001f80230 + 64 NSMenuItem55 bytes after NSMenuItem
725+
0x0000600001f80350: malloc( 112) -> 0x600001f80310 + 64 NSMenuItem55 bytes after NSMenuItem
726+
...
727+
728+
## Printing memory contents
729+
730+
lldb's `x` command is cryptic but extremely useful for printing out memory
731+
contents. Example:
732+
733+
(lldb) x/5a `(Class)objc_getClass("NSString")`
734+
0x7fff83f6d660: 0x00007fff83f709f0 (void *)0x00007fff8c6550f0: NSObject
735+
0x7fff83f6d668: 0x00007fff8c655118 (void *)0x00007fff8c6550f0: NSObject
736+
0x7fff83f6d670: 0x000060000089c500 -> 0x00007fff2d49c550 "_getCString:maxLength:encoding:"
737+
0x7fff83f6d678: 0x000580100000000f
738+
0x7fff83f6d680: 0x000060000348e784
739+
740+
Let's unpack the command a bit. The `5` says that we want to print five entries.
741+
`a` means to print them as addresses, which gives you some automatic symbol
742+
lookups and pointer chasing as we see here. Finally, we give it the address. The
743+
backticks around the expression tells it to evaluate that expression and use the
744+
result as the address. Another example:
745+
746+
(lldb) x/10xb 0x000060000089c500
747+
0x60000089c500: 0x50 0xc5 0x49 0x2d 0xff 0x7f 0x00 0x00
748+
0x60000089c508: 0x77 0x63
749+
750+
Here, `x` means to print the values as hex, and `b` means to print byte by byte.
751+
The following specifiers are available:
752+
753+
* o - octal
754+
* x - hexadecimal
755+
* d - decimal
756+
* u - unsigned decimal
757+
* t - binary
758+
* f - floating point
759+
* a - address
760+
* c - char
761+
* s - string
762+
* i - instruction
763+
* b - byte
764+
* h - halfword (16-bit value)
765+
* w - word (32-bit value)
766+
* g - giant word (64-bit value)
767+
768+
683769
# Debugging LLDB failures
684770

685771
Sometimes one needs to be able to while debugging actually debug LLDB and its

0 commit comments

Comments
 (0)