Skip to content

Commit 43bea48

Browse files
Add script to be able to debug evergreen-x64 with vscode (#9040)
Fixed: 483449996
1 parent 1907448 commit 43bea48

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright 2026 The Cobalt Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
GDB script to automatically load symbols for Evergreen libraries.
16+
17+
This script sets a breakpoint on elf_loader::ProgramTable::PublishEvergreenInfo
18+
to detect when an ELF file is loaded and then uses the add-symbol-file command
19+
to load the symbols at the correct memory offset.
20+
21+
# pylint: disable=line-too-long
22+
To use it, add the following to your .vscode/launch.json:
23+
{
24+
"name": "Cobalt Evergreen (gdb)",
25+
"type": "cppdbg",
26+
"request": "launch",
27+
"program": "${workspaceFolder}/out/evergreen-x64_devel/elf_loader_sandbox",
28+
"args": ["--evergreen_content=.", "--evergreen_library=libcobalt.so"],
29+
// other fields...
30+
"setupCommands": [
31+
{
32+
"description": "Load Evergreen Symbol Hook",
33+
"text": "source ${workspaceFolder}/starboard/tools/vscode_debug_evergreen.py"
34+
}
35+
]
36+
}
37+
38+
# pylint: enable=line-too-long
39+
"""
40+
41+
import gdb
42+
import shlex
43+
44+
45+
class LoadEvergreenLibrary(gdb.Breakpoint):
46+
"""
47+
A GDB Breakpoint that hooks into the Evergreen loader to load symbols.
48+
"""
49+
50+
def __init__(self):
51+
# Set a breakpoint on the function where the library is fully loaded
52+
# and we have the base address and file path available.
53+
super().__init__(
54+
"elf_loader::ProgramTable::PublishEvergreenInfo", internal=True)
55+
self.silent = True
56+
57+
def stop(self):
58+
try:
59+
# Access the 'file_path' argument
60+
file_path_val = gdb.parse_and_eval("file_path")
61+
file_path = file_path_val.string()
62+
63+
# Access the 'base_memory_address_' member of the 'this' object
64+
# We cast to uintptr_t to ensure we get an integer address
65+
base_addr_val = gdb.parse_and_eval("this->base_memory_address_")
66+
base_addr = int(base_addr_val)
67+
68+
print("[Evergreen Loader Hook] Detected "
69+
f"load of {file_path} at {hex(base_addr)}")
70+
71+
# Construct and execute the add-symbol-file command
72+
# The -o option offsets all sections by the base address, which matches
73+
# how the ELF loader maps the segments (assuming 0-based ELF segments).
74+
cmd = f"add-symbol-file {shlex.quote(file_path)} -o {hex(base_addr)}"
75+
76+
# We use from_tty=False to avoid "add symbol table from file? (y or n)"
77+
# prompts but add-symbol-file might still prompt.
78+
# To suppress confirmation, we can use "noconfirm" if available or
79+
# set confirm off temporarily.
80+
gdb.execute("set confirm off")
81+
try:
82+
gdb.execute(cmd)
83+
finally:
84+
gdb.execute("set confirm on")
85+
86+
print("[Evergreen Loader Hook] Symbols loaded successfully.")
87+
88+
except Exception as e: # pylint: disable=broad-exception-caught
89+
print(f"[Evergreen Loader Hook] Error loading symbols: {e}")
90+
91+
# Return False to continue execution immediately
92+
return False
93+
94+
95+
# Instantiate the breakpoint
96+
LoadEvergreenLibrary()
97+
print("[Evergreen Loader Hook] Initialized. "
98+
"Waiting for Evergreen libraries to load...")

0 commit comments

Comments
 (0)