Skip to content

Commit 1b38e26

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 200818c commit 1b38e26

4 files changed

Lines changed: 120 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: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,38 +2252,66 @@ R"(
22522252
// =========================================================================
22532253
// GDB Offset Export - Global Symbols
22542254
// These symbols are directly readable by GDB, no separate tool needed.
2255-
// GDB Python script reads: gdb.parse_and_eval("gdb_thread_offset_vcpu")
2255+
// GDB Python script reads: gdb.parse_and_eval("gdb_offsets")
22562256
// =========================================================================
22572257

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

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)