31
31
#include < climits>
32
32
#include < cstring>
33
33
#include < sys/stat.h>
34
+ #include < variant>
34
35
35
36
#if defined(__APPLE__)
36
37
#define DEBUGSERVER_BASENAME " debugserver"
@@ -894,11 +895,9 @@ FileSpec GDBRemoteCommunication::GetDebugserverPath(Platform *platform) {
894
895
}
895
896
896
897
Status GDBRemoteCommunication::StartDebugserverProcess (
897
- const char *url , Platform *platform, ProcessLaunchInfo &launch_info ,
898
- uint16_t *port , const Args *inferior_args, shared_fd_t pass_comm_fd ) {
898
+ std::variant<llvm::StringRef, shared_fd_t > comm , Platform *platform,
899
+ ProcessLaunchInfo &launch_info , const Args *inferior_args) {
899
900
Log *log = GetLog (GDBRLog::Process);
900
- LLDB_LOG (log, " Starting debug server: url={0}, port={1}" ,
901
- url ? url : " <empty>" , port ? *port : uint16_t (0 ));
902
901
903
902
FileSpec debugserver_file_spec = GetDebugserverPath (platform);
904
903
if (!debugserver_file_spec)
@@ -911,89 +910,58 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
911
910
912
911
#if !defined(__APPLE__)
913
912
// First argument to lldb-server must be mode in which to run.
914
- debugserver_args.AppendArgument (llvm::StringRef ( " gdbserver" ) );
913
+ debugserver_args.AppendArgument (" gdbserver" );
915
914
#endif
916
915
917
- // If a url is supplied then use it
918
- if (url && url[0 ])
919
- debugserver_args.AppendArgument (llvm::StringRef (url));
920
-
921
- if (pass_comm_fd != SharedSocket::kInvalidFD ) {
922
- StreamString fd_arg;
923
- fd_arg.Printf (" --fd=%" PRIi64, (int64_t )pass_comm_fd);
924
- debugserver_args.AppendArgument (fd_arg.GetString ());
925
- // Send "pass_comm_fd" down to the inferior so it can use it to
926
- // communicate back with this process. Ignored on Windows.
927
- launch_info.AppendDuplicateFileAction ((int64_t )pass_comm_fd,
928
- (int64_t )pass_comm_fd);
929
- }
930
-
931
916
// use native registers, not the GDB registers
932
- debugserver_args.AppendArgument (llvm::StringRef ( " --native-regs" ) );
917
+ debugserver_args.AppendArgument (" --native-regs" );
933
918
934
919
if (launch_info.GetLaunchInSeparateProcessGroup ())
935
- debugserver_args.AppendArgument (llvm::StringRef ( " --setsid" ) );
920
+ debugserver_args.AppendArgument (" --setsid" );
936
921
937
922
llvm::SmallString<128 > named_pipe_path;
938
923
// socket_pipe is used by debug server to communicate back either
939
- // TCP port or domain socket name which it listens on.
940
- // The second purpose of the pipe to serve as a synchronization point -
924
+ // TCP port or domain socket name which it listens on. However, we're not
925
+ // interested in the actualy value here.
926
+ // The only reason for using the pipe is to serve as a synchronization point -
941
927
// once data is written to the pipe, debug server is up and running.
942
928
Pipe socket_pipe;
943
929
944
- std::unique_ptr<TCPSocket> sock_up;
930
+ // If a url is supplied then use it
931
+ if (shared_fd_t *comm_fd = std::get_if<shared_fd_t >(&comm)) {
932
+ LLDB_LOG (log, " debugserver communicates over fd {0}" , comm_fd);
933
+ assert (*comm_fd != SharedSocket::kInvalidFD );
934
+ debugserver_args.AppendArgument (llvm::formatv (" --fd={0}" , *comm_fd).str ());
935
+ // Send "comm_fd" down to the inferior so it can use it to communicate back
936
+ // with this process.
937
+ launch_info.AppendDuplicateFileAction ((int64_t )*comm_fd, (int64_t )*comm_fd);
938
+ } else {
939
+ llvm::StringRef url = std::get<llvm::StringRef>(comm);
940
+ LLDB_LOG (log, " debugserver listens on: {0}" , url);
941
+ debugserver_args.AppendArgument (url);
945
942
946
- // port is null when debug server should listen on domain socket - we're
947
- // not interested in port value but rather waiting for debug server to
948
- // become available.
949
- if (pass_comm_fd == SharedSocket::kInvalidFD ) {
950
- if (url) {
951
- // Create a temporary file to get the stdout/stderr and redirect the output of
952
- // the command into this file. We will later read this file if all goes well
953
- // and fill the data into "command_output_ptr"
954
943
#if defined(__APPLE__)
955
- // Binding to port zero, we need to figure out what port it ends up
956
- // using using a named pipe...
957
- Status error = socket_pipe.CreateWithUniqueName (" debugserver-named-pipe" ,
958
- false , named_pipe_path);
959
- if (error.Fail ()) {
960
- LLDB_LOG (log, " named pipe creation failed: {0}" , error);
961
- return error;
962
- }
963
- debugserver_args.AppendArgument (llvm::StringRef (" --named-pipe" ));
964
- debugserver_args.AppendArgument (named_pipe_path);
944
+ // Using a named pipe as debugserver does not support --pipe.
945
+ Status error = socket_pipe.CreateWithUniqueName (" debugserver-named-pipe" ,
946
+ false , named_pipe_path);
947
+ if (error.Fail ()) {
948
+ LLDB_LOG (log, " named pipe creation failed: {0}" , error);
949
+ return error;
950
+ }
951
+ debugserver_args.AppendArgument (llvm::StringRef (" --named-pipe" ));
952
+ debugserver_args.AppendArgument (named_pipe_path);
965
953
#else
966
- // Binding to port zero, we need to figure out what port it ends up
967
- // using using an unnamed pipe...
968
- Status error = socket_pipe.CreateNew (true );
969
- if (error.Fail ()) {
970
- LLDB_LOG (log, " unnamed pipe creation failed: {0}" , error);
971
- return error;
972
- }
973
- pipe_t write = socket_pipe.GetWritePipe ();
974
- debugserver_args.AppendArgument (llvm::StringRef (" --pipe" ));
975
- debugserver_args.AppendArgument (llvm::to_string (write));
976
- launch_info.AppendCloseFileAction (socket_pipe.GetReadFileDescriptor ());
977
- #endif
978
- } else {
979
- // No host and port given, so lets listen on our end and make the
980
- // debugserver connect to us..
981
- if (llvm::Expected<std::unique_ptr<TCPSocket>> expected_sock =
982
- Socket::TcpListen (" 127.0.0.1:0" ))
983
- sock_up = std::move (*expected_sock);
984
- else
985
- return Status::FromError (expected_sock.takeError ());
986
-
987
- uint16_t port_ = sock_up->GetLocalPortNumber ();
988
- // Send the host and port down that debugserver and specify an option
989
- // so that it connects back to the port we are listening to in this
990
- // process
991
- debugserver_args.AppendArgument (llvm::StringRef (" --reverse-connect" ));
992
- debugserver_args.AppendArgument (
993
- llvm::formatv (" 127.0.0.1:{0}" , port_).str ());
994
- if (port)
995
- *port = port_;
954
+ // Using an unnamed pipe as it's simpler.
955
+ Status error = socket_pipe.CreateNew (true );
956
+ if (error.Fail ()) {
957
+ LLDB_LOG (log, " unnamed pipe creation failed: {0}" , error);
958
+ return error;
996
959
}
960
+ pipe_t write = socket_pipe.GetWritePipe ();
961
+ debugserver_args.AppendArgument (llvm::StringRef (" --pipe" ));
962
+ debugserver_args.AppendArgument (llvm::to_string (write));
963
+ launch_info.AppendCloseFileAction (socket_pipe.GetReadFileDescriptor ());
964
+ #endif
997
965
}
998
966
999
967
Environment host_env = Host::GetEnvironment ();
@@ -1070,7 +1038,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
1070
1038
return error;
1071
1039
}
1072
1040
1073
- if (pass_comm_fd != SharedSocket:: kInvalidFD )
1041
+ if (std::holds_alternative< shared_fd_t >(comm) )
1074
1042
return Status ();
1075
1043
1076
1044
Status error;
@@ -1084,55 +1052,30 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
1084
1052
1085
1053
if (socket_pipe.CanWrite ())
1086
1054
socket_pipe.CloseWriteFileDescriptor ();
1087
- if (socket_pipe.CanRead ()) {
1088
- // Read port from pipe with 10 second timeout.
1089
- std::string port_str;
1090
- while (error.Success ()) {
1091
- char buf[10 ];
1092
- if (llvm::Expected<size_t > num_bytes =
1093
- socket_pipe.Read (buf, std::size (buf), std::chrono::seconds (10 ))) {
1094
- if (*num_bytes == 0 )
1095
- break ;
1096
- port_str.append (buf, *num_bytes);
1097
- } else {
1098
- error = Status::FromError (num_bytes.takeError ());
1099
- }
1100
- }
1101
- if (error.Success () && (port != nullptr )) {
1102
- // NB: Deliberately using .c_str() to stop at embedded '\0's
1103
- llvm::StringRef port_ref = port_str.c_str ();
1104
- uint16_t child_port = 0 ;
1105
- // FIXME: improve error handling
1106
- llvm::to_integer (port_ref, child_port);
1107
- if (*port == 0 || *port == child_port) {
1108
- *port = child_port;
1109
- LLDB_LOG (log, " debugserver listens on port {0}" , *port);
1110
- } else {
1111
- LLDB_LOG (log,
1112
- " debugserver listening on port {0} but requested port was {1}" ,
1113
- child_port, (*port));
1114
- }
1055
+ assert (socket_pipe.CanRead ());
1056
+
1057
+ // Read data from the pipe -- and ignore it (see comment above).
1058
+ while (error.Success ()) {
1059
+ char buf[10 ];
1060
+ if (llvm::Expected<size_t > num_bytes =
1061
+ socket_pipe.Read (buf, std::size (buf), std::chrono::seconds (10 ))) {
1062
+ if (*num_bytes == 0 )
1063
+ break ;
1115
1064
} else {
1116
- LLDB_LOG (log, " failed to read a port value from pipe {0}: {1}" ,
1117
- named_pipe_path, error);
1065
+ error = Status::FromError (num_bytes.takeError ());
1118
1066
}
1119
- socket_pipe.Close ();
1120
1067
}
1068
+ if (error.Fail ()) {
1069
+ LLDB_LOG (log, " failed to synchronize on pipe {0}: {1}" , named_pipe_path,
1070
+ error);
1071
+ }
1072
+ socket_pipe.Close ();
1121
1073
1122
1074
if (named_pipe_path.size () > 0 ) {
1123
1075
if (Status err = socket_pipe.Delete (named_pipe_path); err.Fail ())
1124
1076
LLDB_LOG (log, " failed to delete pipe {0}: {1}" , named_pipe_path, err);
1125
1077
}
1126
1078
1127
- if (error.Success () && sock_up) {
1128
- Socket *accepted_socket = nullptr ;
1129
- error = sock_up->Accept (/* timeout=*/ std::nullopt, accepted_socket);
1130
- if (accepted_socket) {
1131
- SetConnection (std::make_unique<ConnectionFileDescriptor>(
1132
- std::unique_ptr<Socket>(accepted_socket)));
1133
- }
1134
- }
1135
-
1136
1079
return error;
1137
1080
}
1138
1081
0 commit comments