392 {
393
394 pid_t attach_pid = 0;
395 std::string attach_name;
396 bool wait_for = false;
397 uint16_t port = 9999;
398
399 for (int i = 1; i < argc; i++) {
400 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
401 printUsage(argv[0]);
402 return 0;
403 } else if (strcmp(argv[i], "--attach") == 0 && i + 1 < argc) {
404
405 unsigned long pid_val = 0;
406 if (
parse_ulong(argv[++i], &pid_val, 1, ULONG_MAX) != ASCIICHAT_OK) {
407 fprintf(stderr, "Error: Invalid PID value\n");
408 return 1;
409 }
410 attach_pid = static_cast<pid_t>(pid_val);
411 } else if (strcmp(argv[i], "--attach-name") == 0 && i + 1 < argc) {
412 attach_name = argv[++i];
413 } else if (strcmp(argv[i], "--wait") == 0) {
414 wait_for = true;
415 } else if (strcmp(argv[i], "--port") == 0 && i + 1 < argc) {
416
417 if (
parse_port(argv[++i], &port) != ASCIICHAT_OK) {
418 fprintf(stderr, "Error: Invalid port number (must be 1-65535)\n");
419 return 1;
420 }
421 } else {
422 fprintf(stderr, "Unknown option: %s\n", argv[i]);
423 printUsage(argv[0]);
424 return 1;
425 }
426 }
427
428
429 if (attach_pid == 0 && attach_name.empty()) {
430 fprintf(stderr, "Error: Must specify --attach <pid> or --attach-name <name>\n\n");
431 printUsage(argv[0]);
432 return 1;
433 }
434
435
436 signal(SIGINT, signalHandler);
437 signal(SIGTERM, signalHandler);
438#ifndef _WIN32
439 signal(SIGPIPE, SIG_IGN);
440#endif
441
442
444 g_controller = &controller;
445
447 fprintf(stderr,
"Error: Failed to initialize LLDB: %s\n", controller.
lastError().c_str());
448 return 1;
449 }
450
451
452 fprintf(stderr, "[ascii-query-server] Attaching to ");
453 if (attach_pid > 0) {
454 fprintf(stderr, "PID %llu...\n", static_cast<unsigned long long>(attach_pid));
455 if (!controller.
attach(attach_pid)) {
456 fprintf(stderr,
"Error: Failed to attach: %s\n", controller.
lastError().c_str());
457 return 1;
458 }
459 } else {
460 fprintf(stderr, "process '%s'%s...\n", attach_name.c_str(), wait_for ? " (waiting)" : "");
462 fprintf(stderr,
"Error: Failed to attach: %s\n", controller.
lastError().c_str());
463 return 1;
464 }
465 }
466
467 fprintf(stderr,
"[ascii-query-server] Attached to %s (PID %llu)\n", controller.
targetName().c_str(),
468 static_cast<unsigned long long>(controller.
targetPid()));
469
470
472 fprintf(stderr, "[ascii-query-server] Resuming target...\n");
474 }
475
476
478 g_server = &server;
479
480 setupRoutes(server, controller);
481
482
483 if (!server.
start(port)) {
484 fprintf(stderr,
"Error: Failed to start HTTP server: %s\n", server.
lastError().c_str());
486 return 1;
487 }
488
489 fprintf(stderr, "[ascii-query-server] HTTP server listening on http://localhost:%d\n", port);
490 fprintf(stderr, "[ascii-query-server] Press Ctrl+C to stop\n");
491
492
493 while (!g_shutdown_requested && controller.
isAttached()) {
494#ifdef _WIN32
495 Sleep(100);
496#else
497 usleep(100000);
498#endif
501 fprintf(stderr, "[ascii-query-server] Target %s, shutting down\n",
503 break;
504 }
505 }
506
507
508 fprintf(stderr, "[ascii-query-server] Shutting down...\n");
512
513 fprintf(stderr, "[ascii-query-server] Done\n");
514 return 0;
515}
Simple single-threaded HTTP server.
bool start(uint16_t port)
Start the server.
const std::string & lastError() const
Get the last error message.
void stop()
Stop the server.
bool attachByName(const std::string &process_name, bool wait_for=false)
Attach to a process by name.
pid_t targetPid() const
Get the PID of the attached process.
std::string targetName() const
Get the name of the attached process.
const std::string & lastError() const
Get the last error message.
bool initialize()
Initialize LLDB. Must be called before any other methods.
void shutdown()
Shutdown LLDB and release resources.
bool isAttached() const
Check if attached to a process.
bool resume()
Resume the target process.
void detach()
Detach from the current process.
bool attach(pid_t pid)
Attach to a process by PID.
ProcessState state() const
Get the current process state.
ProcessState
Process state enumeration.
@ Exited
Process has exited.
@ Crashed
Process crashed.
@ Stopped
Process is stopped (breakpoint, signal, etc.)
asciichat_error_t parse_ulong(const char *str, unsigned long *out_value, unsigned long min_value, unsigned long max_value)
asciichat_error_t parse_port(const char *str, uint16_t *out_port)