Skip to content

Commit 24102eb

Browse files
committed
gdbtool Unify offset struct
1. Single GDBOffsets struct - All offsets now accessed via gdb_offsets.thread_* and gdb_offsets.vcpu_* - Cleaner symbol export with single struct instance 2. Add version field inside GDBOffsets struct - Version is independent of struct size - Allows detection of field reordering/semantic changes - Increment when adding/removing/modifying/reordering fields gdb: Remove unused gdb_pointer_size export
1 parent 7dd59a8 commit 24102eb

4 files changed

Lines changed: 122 additions & 68 deletions

File tree

common/stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ limitations under the License.
2020
#include <stdlib.h>
2121
#include <sys/types.h>
2222

23+
#include <cstdint>
2324
#include <memory>
2425

2526
struct iovec;

thread/thread.cpp

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,38 +2241,68 @@ R"(
22412241
// =========================================================================
22422242
// GDB Offset Export - Global Symbols
22432243
// These symbols are directly readable by GDB, no separate tool needed.
2244-
// GDB Python script reads: gdb.parse_and_eval("gdb_thread_offset_vcpu")
2244+
// GDB Python script reads: gdb.parse_and_eval("gdb_offsets")
22452245
// =========================================================================
22462246

2247-
// Export as C symbols to avoid name mangling
2248-
extern "C" {
2249-
2250-
// Thread structure offsets
2251-
[[gnu::used]] const size_t gdb_thread_size = sizeof(photon::thread);
2252-
[[gnu::used]] const size_t gdb_thread_offset_prev = 0;
2253-
[[gnu::used]] const size_t gdb_thread_offset_next = sizeof(void*);
2254-
[[gnu::used]] const size_t gdb_thread_offset_vcpu = offsetof(photon::thread, vcpu);
2255-
[[gnu::used]] const size_t gdb_thread_offset_stack_ptr = offsetof(photon::thread, stack);
2256-
[[gnu::used]] const size_t gdb_thread_offset_idx = offsetof(photon::thread, idx);
2257-
[[gnu::used]] const size_t gdb_thread_offset_error_number = offsetof(photon::thread, error_number);
2258-
[[gnu::used]] const size_t gdb_thread_offset_waitq = offsetof(photon::thread, waitq);
2259-
[[gnu::used]] const size_t gdb_thread_offset_flags = offsetof(photon::thread, flags);
2260-
[[gnu::used]] const size_t gdb_thread_offset_state = offsetof(photon::thread, state);
2261-
[[gnu::used]] const size_t gdb_thread_offset_ts_wakeup = offsetof(photon::thread, ts_wakeup);
2262-
[[gnu::used]] const size_t gdb_thread_offset_tls = offsetof(photon::thread, tls);
2263-
[[gnu::used]] const size_t gdb_thread_offset_buf = offsetof(photon::thread, buf);
2264-
[[gnu::used]] const size_t gdb_thread_offset_stack_size = offsetof(photon::thread, stack_size);
2265-
2266-
// vCPU structure offsets
2267-
[[gnu::used]] const size_t gdb_vcpu_size = sizeof(photon::vcpu_t);
2268-
[[gnu::used]] const size_t gdb_vcpu_offset_sleepq = offsetof(photon::vcpu_t, sleepq);
2269-
[[gnu::used]] const size_t gdb_vcpu_offset_nthreads = offsetof(photon::vcpu_t, nthreads);
2270-
[[gnu::used]] const size_t gdb_vcpu_offset_idle_worker = offsetof(photon::vcpu_t, idle_worker);
2271-
[[gnu::used]] const size_t gdb_vcpu_offset_standbyq = offsetof(photon::vcpu_t, standbyq);
2272-
[[gnu::used]] const size_t gdb_vcpu_offset_list_node_prev = offsetof(photon::vcpu_t, __prev_ptr);
2273-
[[gnu::used]] const size_t gdb_vcpu_offset_list_node_next = offsetof(photon::vcpu_t, __next_ptr);
2274-
2275-
// Pointer size for architecture detection
2276-
[[gnu::used]] const size_t gdb_pointer_size = sizeof(void*);
2277-
2278-
} // extern "C"
2247+
// All offsets in a single struct for easy access
2248+
struct GDBOffsets {
2249+
// Version number for compatibility checking
2250+
// Increment when adding/removing/modifying/reordering offset fields
2251+
uint32_t version;
2252+
uint32_t _reserved; // Padding for alignment
2253+
2254+
// Thread structure
2255+
size_t thread_size;
2256+
size_t thread_offset_prev;
2257+
size_t thread_offset_next;
2258+
size_t thread_offset_vcpu;
2259+
size_t thread_offset_stack_ptr;
2260+
size_t thread_offset_idx;
2261+
size_t thread_offset_error_number;
2262+
size_t thread_offset_waitq;
2263+
size_t thread_offset_flags;
2264+
size_t thread_offset_state;
2265+
size_t thread_offset_ts_wakeup;
2266+
size_t thread_offset_tls;
2267+
size_t thread_offset_buf;
2268+
size_t thread_offset_stack_size;
2269+
2270+
// vCPU structure
2271+
size_t vcpu_size;
2272+
size_t vcpu_offset_sleepq;
2273+
size_t vcpu_offset_nthreads;
2274+
size_t vcpu_offset_idle_worker;
2275+
size_t vcpu_offset_standbyq;
2276+
size_t vcpu_offset_list_node_prev;
2277+
size_t vcpu_offset_list_node_next;
2278+
};
2279+
2280+
extern "C" const GDBOffsets gdb_offsets = {
2281+
.version = 1,
2282+
._reserved = 0,
2283+
2284+
// Thread structure
2285+
.thread_size = sizeof(photon::thread),
2286+
.thread_offset_prev = 0,
2287+
.thread_offset_next = sizeof(void*),
2288+
.thread_offset_vcpu = offsetof(photon::thread, vcpu),
2289+
.thread_offset_stack_ptr = offsetof(photon::thread, stack),
2290+
.thread_offset_idx = offsetof(photon::thread, idx),
2291+
.thread_offset_error_number = offsetof(photon::thread, error_number),
2292+
.thread_offset_waitq = offsetof(photon::thread, waitq),
2293+
.thread_offset_flags = offsetof(photon::thread, flags),
2294+
.thread_offset_state = offsetof(photon::thread, state),
2295+
.thread_offset_ts_wakeup = offsetof(photon::thread, ts_wakeup),
2296+
.thread_offset_tls = offsetof(photon::thread, tls),
2297+
.thread_offset_buf = offsetof(photon::thread, buf),
2298+
.thread_offset_stack_size = offsetof(photon::thread, stack_size),
2299+
2300+
// vCPU structure
2301+
.vcpu_size = sizeof(photon::vcpu_t),
2302+
.vcpu_offset_sleepq = offsetof(photon::vcpu_t, sleepq),
2303+
.vcpu_offset_nthreads = offsetof(photon::vcpu_t, nthreads),
2304+
.vcpu_offset_idle_worker = offsetof(photon::vcpu_t, idle_worker),
2305+
.vcpu_offset_standbyq = offsetof(photon::vcpu_t, standbyq),
2306+
.vcpu_offset_list_node_prev = offsetof(photon::vcpu_t, __prev_ptr),
2307+
.vcpu_offset_list_node_next = offsetof(photon::vcpu_t, __next_ptr),
2308+
};

tools/photongdb.py

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,47 +173,54 @@ def _load_offsets_from_symbols():
173173
thread_offsets = {}
174174
vcpu_offsets = {}
175175

176-
# Thread offsets
177-
thread_symbols = [
178-
('_size', 'gdb_thread_size'),
179-
('prev', 'gdb_thread_offset_prev'),
180-
('next', 'gdb_thread_offset_next'),
181-
('vcpu', 'gdb_thread_offset_vcpu'),
182-
('stack_ptr', 'gdb_thread_offset_stack_ptr'),
183-
('idx', 'gdb_thread_offset_idx'),
184-
('error_number', 'gdb_thread_offset_error_number'),
185-
('waitq', 'gdb_thread_offset_waitq'),
186-
('flags', 'gdb_thread_offset_flags'),
187-
('state', 'gdb_thread_offset_state'),
188-
('ts_wakeup', 'gdb_thread_offset_ts_wakeup'),
189-
('tls', 'gdb_thread_offset_tls'),
190-
('buf', 'gdb_thread_offset_buf'),
191-
('stack_size', 'gdb_thread_offset_stack_size'),
176+
# Check version for compatibility (now inside struct)
177+
version = _read_gdb_symbol('gdb_offsets.version')
178+
if version is not None:
179+
cprint('INFO', f"GDB offsets version: {version}")
180+
181+
# Thread offsets (from unified struct GDBOffsets)
182+
thread_fields = [
183+
('_size', 'thread_size'),
184+
('prev', 'thread_offset_prev'),
185+
('next', 'thread_offset_next'),
186+
('vcpu', 'thread_offset_vcpu'),
187+
('stack_ptr', 'thread_offset_stack_ptr'),
188+
('idx', 'thread_offset_idx'),
189+
('error_number', 'thread_offset_error_number'),
190+
('waitq', 'thread_offset_waitq'),
191+
('flags', 'thread_offset_flags'),
192+
('state', 'thread_offset_state'),
193+
('ts_wakeup', 'thread_offset_ts_wakeup'),
194+
('tls', 'thread_offset_tls'),
195+
('buf', 'thread_offset_buf'),
196+
('stack_size', 'thread_offset_stack_size'),
192197
]
193198

194-
# vCPU offsets
195-
vcpu_symbols = [
196-
('_size', 'gdb_vcpu_size'),
197-
('sleepq', 'gdb_vcpu_offset_sleepq'),
198-
('nthreads', 'gdb_vcpu_offset_nthreads'),
199-
('idle_worker', 'gdb_vcpu_offset_idle_worker'),
200-
('standbyq', 'gdb_vcpu_offset_standbyq'),
201-
('list_node_prev', 'gdb_vcpu_offset_list_node_prev'),
202-
('list_node_next', 'gdb_vcpu_offset_list_node_next'),
199+
# vCPU offsets (from unified struct GDBOffsets)
200+
vcpu_fields = [
201+
('_size', 'vcpu_size'),
202+
('sleepq', 'vcpu_offset_sleepq'),
203+
('nthreads', 'vcpu_offset_nthreads'),
204+
('idle_worker', 'vcpu_offset_idle_worker'),
205+
('standbyq', 'vcpu_offset_standbyq'),
206+
('list_node_prev', 'vcpu_offset_list_node_prev'),
207+
('list_node_next', 'vcpu_offset_list_node_next'),
203208
]
204209

205210
success = True
206211

207-
for name, symbol in thread_symbols:
208-
val = _read_gdb_symbol(symbol)
212+
# Read thread offsets from unified struct
213+
for name, field in thread_fields:
214+
val = _read_gdb_symbol(f'gdb_offsets.{field}')
209215
if val is not None:
210216
thread_offsets[name] = val
211217
else:
212218
thread_offsets[name] = _DEFAULT_THREAD_OFFSETS.get(name, 0)
213219
success = False
214220

215-
for name, symbol in vcpu_symbols:
216-
val = _read_gdb_symbol(symbol)
221+
# Read vCPU offsets from unified struct
222+
for name, field in vcpu_fields:
223+
val = _read_gdb_symbol(f'gdb_offsets.{field}')
217224
if val is not None:
218225
vcpu_offsets[name] = val
219226
else:

tools/ppstack

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,32 @@ if test ! -f "$PHOTONDB"; then
5151
exit 1
5252
fi
5353

54+
# Detect libphoton.so location for solib-search-path
55+
PHOTON_LIB_PATH="${PHOTON_LIB_PATH:-}"
56+
if test -z "$PHOTON_LIB_PATH"; then
57+
# Try relative to script directory
58+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
59+
if test -f "$SCRIPT_DIR/../build/output/libphoton.so"; then
60+
PHOTON_LIB_PATH="$SCRIPT_DIR/../build/output"
61+
fi
62+
fi
63+
5464
GDB=${GDB:-gdb}
5565

56-
# Run GDB, strip out unwanted noise.
57-
$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <<EOF 2>&1 |
58-
set width 0
66+
# Build GDB commands
67+
GDB_CMDS="set width 0
5968
set height 0
60-
set pagination no
69+
set pagination no"
70+
if test -n "$PHOTON_LIB_PATH"; then
71+
GDB_CMDS="$GDB_CMDS
72+
set solib-search-path $PHOTON_LIB_PATH"
73+
fi
74+
GDB_CMDS="$GDB_CMDS
6175
source $PHOTONDB
62-
photon_ps
63-
EOF
76+
photon_ps"
77+
78+
# Run GDB, strip out unwanted noise.
79+
echo "$GDB_CMDS" | $GDB --quiet -nx $GDBARGS /proc/$1/exe $1 2>&1 |
6480
/bin/sed -n \
6581
-e 's/^\((gdb) \)*//' \
6682
-e '/^Thread [0-9]/p' \

0 commit comments

Comments
 (0)