|
4 | 4 | Usage: |
5 | 5 | gdb-cli load --binary ./my_program --core ./core.1234 |
6 | 6 | gdb-cli attach --pid 9876 |
| 7 | + gdb-cli target --remote 192.168.0.21:3333 |
7 | 8 | gdb-cli eval-cmd --session <id> "lock_mgr->buckets[0]" |
8 | 9 | gdb-cli threads --session <id> [--limit 20] |
9 | 10 | gdb-cli bt --session <id> [--thread 12] [--limit 30] |
|
21 | 22 | from . import __version__ |
22 | 23 | from .client import GDBClient, GDBClientError, GDBCommandError |
23 | 24 | from .i18n import t |
24 | | -from .launcher import GDBLauncherError, launch_attach, launch_core |
| 25 | +from .launcher import GDBLauncherError, launch_attach, launch_core, launch_target |
25 | 26 | from .session import ( |
26 | 27 | cleanup_dead_sessions, |
27 | 28 | find_session_by_core, |
28 | 29 | find_session_by_pid, |
| 30 | + find_session_by_remote, |
29 | 31 | get_session, |
30 | 32 | list_sessions, |
31 | 33 | ) |
@@ -181,6 +183,68 @@ def attach( |
181 | 183 | raise click.exceptions.Exit(1) |
182 | 184 |
|
183 | 185 |
|
| 186 | +@main.command() |
| 187 | +@click.option("--remote", "-r", required=True, type=str, help=t("cli.target.remote_help")) |
| 188 | +@click.option("--binary", "-b", help=t("cli.target.binary_help")) |
| 189 | +@click.option("--scheduler-locking/--no-scheduler-locking", default=True, help=t("cli.target.scheduler_locking_help")) |
| 190 | +@click.option("--non-stop/--no-non-stop", default=False, help=t("cli.target.non_stop_help")) |
| 191 | +@click.option("--timeout", default=600, help=t("cli.target.timeout_help")) |
| 192 | +@click.option("--allow-write", is_flag=True, help=t("cli.target.allow_write_help")) |
| 193 | +@click.option("--allow-call", is_flag=True, help=t("cli.target.allow_call_help")) |
| 194 | +@click.option("--gdb-path", default="gdb", help=t("cli.load.gdb_path_help")) |
| 195 | +def target( |
| 196 | + remote: str, |
| 197 | + binary: Optional[str], |
| 198 | + scheduler_locking: bool, |
| 199 | + non_stop: bool, |
| 200 | + timeout: int, |
| 201 | + allow_write: bool, |
| 202 | + allow_call: bool, |
| 203 | + gdb_path: str, |
| 204 | +) -> None: |
| 205 | + """Connect to remote GDB server""" |
| 206 | + existing = find_session_by_remote(remote) |
| 207 | + if existing: |
| 208 | + print_json({ |
| 209 | + "session_id": existing.session_id, |
| 210 | + "mode": existing.mode, |
| 211 | + "remote": existing.remote, |
| 212 | + "status": "reused", |
| 213 | + "message": "Session already exists for this remote" |
| 214 | + }) |
| 215 | + return |
| 216 | + |
| 217 | + try: |
| 218 | + gdb_process = launch_target( |
| 219 | + remote=remote, |
| 220 | + binary=binary, |
| 221 | + scheduler_locking=scheduler_locking, |
| 222 | + non_stop=non_stop, |
| 223 | + timeout=timeout, |
| 224 | + allow_write=allow_write, |
| 225 | + allow_call=allow_call, |
| 226 | + gdb_path=gdb_path |
| 227 | + ) |
| 228 | + |
| 229 | + session = gdb_process.session |
| 230 | + |
| 231 | + print_json({ |
| 232 | + "session_id": session.session_id, |
| 233 | + "mode": session.mode, |
| 234 | + "remote": session.remote, |
| 235 | + "binary": session.binary, |
| 236 | + "remote": session.remote, |
| 237 | + "sock_path": session.sock_path, |
| 238 | + "gdb_pid": gdb_process.pid, |
| 239 | + "safety_level": session.safety_level, |
| 240 | + "status": "started" |
| 241 | + }) |
| 242 | + |
| 243 | + except GDBLauncherError as e: |
| 244 | + print_error("Failed to connect to target", str(e)) |
| 245 | + raise click.exceptions.Exit(1) |
| 246 | + |
| 247 | + |
184 | 248 | @main.command() |
185 | 249 | @click.option("--session", "-s", required=True, help=t("cli.eval_cmd.session_help")) |
186 | 250 | @click.argument("expr") |
@@ -330,7 +394,9 @@ def sessions() -> None: |
330 | 394 | "mode": s.mode, |
331 | 395 | "binary": s.binary, |
332 | 396 | "pid": s.pid, |
| 397 | + "remote": s.remote, |
333 | 398 | "core": s.core, |
| 399 | + "gdb_pid": s.gdb_pid, |
334 | 400 | "started_at": s.started_at, |
335 | 401 | } |
336 | 402 | for s in session_list |
|
0 commit comments