Skip to content

Commit 7dd59a8

Browse files
committed
gdbtool works without modify registers
Major improvements to Photon GDB debugging infrastructure: 1. Symbol-based offset export (thread.cpp) - Export struct offsets as global C symbols (gdb_thread_offset_*, gdb_vcpu_offset_*) - Remove obsolete gdb_get_* helper functions 2. photongdb.py enhancements - Dynamic offset loading from libphoton.so symbols with fallback defaults - Works for both living process and coredump records. 3. Documentation updates for both English and Chinese - Updated example outputs to reflect new vCPU format - Clarified CURRENT vs RUNNING state semantics
1 parent 3d89682 commit 7dd59a8

6 files changed

Lines changed: 1400 additions & 447 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
100100
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
101101

102102
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
103-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-packed-bitfield-compat")
103+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-packed-bitfield-compat -fno-omit-frame-pointer")
104104
endif()
105105

106106
if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
@@ -109,7 +109,7 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
109109
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcrc32")
110110
endif ()
111111
elseif ((CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) OR (CMAKE_SYSTEM_PROCESSOR STREQUAL arm64))
112-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char -fno-stack-protector -fomit-frame-pointer")
112+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char -fno-stack-protector -fno-omit-frame-pointer")
113113
if (NOT CMAKE_CXX_FLAGS MATCHES "-march=|-mcpu=")
114114
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=generic+crc+crypto+lse")
115115
endif ()

doc/docs/miscellaneous/debugging.md

Lines changed: 75 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -5,153 +5,123 @@ toc_max_heading_level: 5
55

66
# Debugging
77

8-
`photongdb.py` is a gdb extension to help debugging running process with photon threads.
8+
`photongdb.py` is a GDB extension for debugging processes with Photon threads. It supports both live debugging and coredump analysis.
99

10-
It provides a group of extra gdb command to inspect photon thread status, even able to switch to background photon
11-
stack to inspect stack frames and variables if needed.
10+
It provides extra GDB commands to inspect Photon thread status and view stack traces of background threads.
1211

1312
## Build
1413

15-
Build with `-D CMAKE_BUILD_TYPE=Debug`
14+
Build with `-D CMAKE_BUILD_TYPE=Debug` and `-fno-omit-frame-pointer` for best debugging experience.
1615

1716
## Usage
1817

19-
When using GDB to debugging (debug running or attaching), load the script to enable this extension
18+
When using GDB for debugging (attach to process or analyze coredump), load the script to enable this extension:
2019

2120
```gdb
2221
(gdb) source <repo_dir>/tools/photongdb.py
23-
INFO Photon-GDB-extension loaded
24-
```
25-
It will print hint to tells that extension is loaded.
26-
Extra gdb-commands are added to environment:
27-
28-
:::note
29-
The `repo_dir` in debugging machine should be the same as the one in build machine.
30-
:::
31-
32-
```gdb
33-
photon_current
34-
photon_ls
35-
photon_init
36-
photon_fini
37-
photon_rst
38-
photon_fr
22+
INFO Photon-GDB-extension v2 loaded
23+
INFO Commands: photon_ls, photon_fr <n>, photon_bt [n], photon_ps, photon_current
24+
INFO Use photon_fr to select thread, then photon_bt to show its backtrace
3925
```
4026

4127
### Commands
4228

43-
#### `photon_init`
29+
| Command | Description |
30+
|---------|-------------|
31+
| `photon_ls` | List all Photon threads across all vCPUs |
32+
| `photon_fr <n>` | Select thread n for subsequent operations |
33+
| `photon_bt [n]` | Show backtrace of selected (or specified) thread |
34+
| `photon_ps` | Show all threads with their backtraces |
35+
| `photon_current` | Show currently selected Photon thread info |
4436

45-
Initializing photon thread lookup mode.
37+
Legacy commands (`photon_init`, `photon_fini`, `photon_rst`) are kept for backward compatibility but no longer needed.
4638

47-
This command will store current stack registers in gdb value `$saved_rsp`, `$saved_rbp`, `$saved_rip`, and enabling
48-
commands in photon thread lookup mode.
49-
50-
Since to inspect background photon threads needs simulating stack switch for gdb, it will change some registers.
51-
All commands in this group should be called only after entered photon debugging mode.
39+
#### `photon_ls`
5240

53-
During photon debugging mode, user should NEVER try to continue running (even step in) before exit the mode, or
54-
process running status will be messed up, result in unpredictable failure.
41+
List all Photon threads on all vCPUs. Output format is similar to GDB's `info threads`.
5542

5643
```gdb
57-
(gdb) photon_init
58-
WARNING Entered photon thread lookup mode. PLEASE do not trying step-in or continue before `photon_fini`
59-
60-
(gdb) p $saved_rsp
61-
$1 = 140737488343040
62-
(gdb) p $saved_rbp
63-
$2 = 140737488343040
64-
(gdb) p $saved_rip
65-
$3 = 4358880
66-
6744
(gdb) photon_ls
68-
CURRENT [0] 0x5555558a9e20 0x7fffffffdb30 0x7fffffffe1a0 0x55555556a029
69-
READY [1] 0x7ffff6afb340 0x7ffff6afb1b0 0x7ffff6afb1d0 0x5555555696e0
70-
SLEEP [2] 0x5555558c0740 0x5555558c0310 0x5555558c0310 0x5555558c0740
71-
SLEEP [3] 0x7ffff6165b40 0x7ffff6165690 0x7ffff6165690 0x7ffff6165b40
45+
Thread 0, 0xffffad92cf80 (CURRENT) vCPU 1 (0xaaab0e9b4e00)
46+
at photon::vcpu_ctx::run () at thread/thread.cpp:1295
47+
Thread 1, 0xaaab0eb78030 (STANDBY) vCPU 1 (0xaaab0e9b4e00)
48+
at photon::thread_stub () at thread/thread.cpp:502
49+
Thread 2, 0xaaab0ec98030 (SLEEP) vCPU 1 (0xaaab0e9b4e00)
50+
at photon::thread_usleep_defer () at thread/thread.cpp:952
51+
* Thread 3, 0xaaab0ed44030 (SLEEP) vCPU 1 (0xaaab0e9b4e00)
52+
at photon::mutex::lock () at thread/thread.cpp:1605
7253
```
7354

74-
:::info
75-
There are two situations:
76-
1. You have set a `breakpoint` in a specific line of your code.
77-
2. You suspend the `gdb` by `ctrl + C`, and the program halts inside libc or syscall.
55+
The `*` marks the currently selected thread (via `photon_fr`).
56+
57+
#### `photon_fr`
7858

79-
For situation 2, you MUST first switch to the Photon code, for instance, by the command of `frame 3`.
80-
You should make sure the current stack has the `photon::CURRENT` symbol when initializing.
59+
Select a Photon thread for subsequent `photon_bt` and `photon_current` commands.
8160

82-
After init, you MUST go back to the top frame by the command of `frame 0`.
83-
:::
61+
```gdb
62+
(gdb) photon_fr 3
63+
[Switching to Thread 3, 0xaaab0ed44030 (SLEEP) vCPU 1 (0xaaab0e9b4e00)]
8464
65+
(gdb) photon_fr
66+
Current selected thread: 3
67+
```
8568

86-
#### `photon_current`
69+
#### `photon_bt`
8770

88-
Print out `CURRENT` running photon thread struct. No side effects, can be called any time.
71+
Show backtrace of the selected thread (or specify a thread index). Output format is similar to GDB's `backtrace`.
8972

9073
```gdb
91-
(gdb) photon_current
92-
CURRENT {<intrusive_list_node<photon::thread>> = {<__intrusive_list_node> = {__prev_ptr = 0x7ffff2bf9bc0, __next_ptr = 0x7ffff2bf9bc0}, <No data fields>}, state = photon::RUNNING, error_number = 0, idx = -172836528, flags = 0, reserved = 7564776, joinable = false, shutting_down = false, lock = {_lock = {<std::__atomic_flag_base> = {_M_i = false}, <No data fields>}}, waitq = 0x0, vcpu = 0x7ffff7db5600 <photon::vcpus>, start = 0x736de8, arg = 0x0, retval = 0x736fe8, buf = 0x7ffff7dd46c0 <(anonymous namespace)::c_locale_impl> "\020", stack = {_ptr = 0x7fffffffd0c8}, ts_wakeup = 0, cond = {<photon::waitq> = {q = {th = 0x0, lock = {_lock = {<std::__atomic_flag_base> = {_M_i = false}, <No data fields>}}}}, <No data fields>}}
74+
(gdb) photon_bt
75+
#0 0x0000ffffaf79bde0 in photon::thread_usleep_defer ()
76+
#1 0x0000ffffaf79b410 in photon::mutex::lock ()
77+
#2 0x0000aaab0e9f6a48 in TestFunc () at test.cpp:42
78+
79+
(gdb) photon_bt 0
80+
#0 0x0000ffffaf7a9e58 in photon::vcpu_ctx::run () at thread/thread.cpp:1295
81+
#1 0x0000ffffaf7aa0c4 in photon::vcpu_task () at thread/thread.cpp:1342
9382
```
9483

95-
#### `photon_ls`
84+
#### `photon_ps`
9685

97-
List all photon threads on current vCPU. No side effects, can be called any time.
86+
Show all Photon threads with their backtraces.
9887

9988
```gdb
100-
(gdb) photon_ls
101-
CURRENT [0] 0x5555558a9e20 0x7fffffffdb30 0x7fffffffe1a0 0x55555556a029
102-
READY [1] 0x7ffff6afb340 0x7ffff6afb1b0 0x7ffff6afb1d0 0x5555555696e0
103-
SLEEP [2] 0x5555558c0740 0x5555558c0310 0x5555558c0310 0x5555558c0740
104-
SLEEP [3] 0x7ffff6165b40 0x7ffff6165690 0x7ffff6165690 0x7ffff6165b40
105-
```
89+
(gdb) photon_ps
90+
Thread 0, 0xffffad92cf80 (CURRENT) vCPU 1 (0xaaab0e9b4e00)
91+
#0 0x0000ffffaf7a9e58 in photon::vcpu_ctx::run ()
92+
#1 0x0000ffffaf7aa0c4 in photon::vcpu_task ()
10693
107-
:::info
108-
This command will only work after `photon_init`
109-
:::
94+
Thread 1, 0xaaab0eb78030 (STANDBY) vCPU 1 (0xaaab0e9b4e00)
95+
#0 0x0000ffffaf79b7f4 in photon::thread_stub ()
11096
111-
#### `photon_fr`
97+
Thread 2, 0xaaab0ec98030 (SLEEP) vCPU 1 (0xaaab0e9b4e00)
98+
#0 0x0000ffffaf79bde0 in photon::thread_usleep_defer ()
99+
#1 0x0000aaab0e9f5c20 in main ()
100+
```
112101

113-
Look into any photon thread stack. Use with gdb `bt`.
102+
#### `photon_current`
103+
104+
Show the currently selected Photon thread info.
114105

115106
```gdb
116-
(gdb) photon_fr 1
117-
SWITCH to 0x7ffff2bf9ac8 0x7ffff2bf9ae0 0x7ffff5014ceb
118-
(gdb) bt
119-
#0 photon::switch_context (from=0x7ffff2bf9bc0, to=0x736c50) at photon/thread.cpp:478
120-
#1 0x00007ffff5014d22 in photon::switch_context (from=0x7ffff2bf9bc0, new_state=photon::READY, to=0x736c50) at photon/thread.cpp:482
121-
#2 0x00007ffff5010b51 in photon::thread_yield_to (th=0x736c50) at photon/thread.cpp:575
122-
#3 0x00007ffff5010465 in photon::thread_stub () at photon/thread.cpp:386
123-
#4 0x0000000000000000 in ?? ()
124-
(gdb) photon_fr 0
125-
SWITCH to 0x7fffffffd000 0x7fffffffd000 0x4282e0
126-
(gdb) bt
127-
#0 0x00000000004282e0 in <lambda(ILogOutput*)>::operator()(ILogOutput *) const (__closure=0x7fffffffd044, __output___LINE__=0x706280 <_log_output_null>)
128-
at test/test.cpp:132
129-
#1 0x00000000004488ba in LogBuilder<log_format()::<lambda(ILogOutput*)> >::~LogBuilder(void) (this=0x7fffffffd040, __in_chrg=<optimized out>)
130-
at test/../alog.h:519
131-
#2 0x0000000000428398 in log_format () at test/test.cpp:133
132-
#3 0x00000000004283c9 in ALog_fmt_perf_1m_Test::TestBody (this=0x736c00) at test/test.cpp:140
133-
#4 0x00000000004b6d13 in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
134-
#5 0x00000000004abeaa in testing::Test::Run() ()
135-
#6 0x00000000004abff8 in testing::TestInfo::Run() ()
136-
#7 0x00000000004ac0d5 in testing::TestCase::Run() ()
137-
#8 0x00000000004ac3c0 in testing::internal::UnitTestImpl::RunAllTests() ()
138-
#9 0x00000000004b7223 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
139-
#10 0x00000000004ac6a3 in testing::UnitTest::Run() ()
140-
#11 0x0000000000457f24 in RUN_ALL_TESTS () at ../../.dep_create_cache/var/alicpp/apsara/alicpp/built/gcc-4.9.2/gtest-1.7.0/include/gtest/gtest.h:2288
141-
#12 0x0000000000447737 in main (argc=1, argv=0x7fffffffd4d8) at test/test.cpp:1761
107+
(gdb) photon_current
108+
SLEEP [3] 0xaaab0ed44030 vCPU 1 (0xaaab0e9b4e00)
142109
```
143110

144-
:::info
145-
This command will only work after `photon_init`
146-
:::
111+
### Coredump Debugging
147112

148-
#### `photon_fini`
113+
The extension fully supports coredump debugging. Simply load the script and use the same commands:
149114

150-
Finish photon thread lookup mode, restore registers
115+
```bash
116+
gdb /path/to/executable /path/to/core.12345
117+
(gdb) source /path/to/photongdb.py
118+
(gdb) photon_ls
119+
(gdb) photon_ps
120+
```
151121

152-
This will restore registers, exit photon thread lookup mode, so it is able to continue running after `photon_init` called.
122+
### Notes
153123

154-
```gdb
155-
(gdb) photon_fini
156-
WARNING Finished photon thread lookup mode.
157-
```
124+
- For best stack unwinding results, compile with `-fno-omit-frame-pointer`
125+
- CURRENT threads show the actual OS thread stack from GDB (live debugging)
126+
- RUNNING state is shown for coredump analysis where GDB context is unavailable
127+
- Works with multiple vCPUs in multi-threaded applications

0 commit comments

Comments
 (0)