[Lldb-commits] [lldb] 86e7900 - [lldb] Fix lldb-server host and port address parsing (#191414)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Apr 13 07:36:33 PDT 2026
Author: Georgiy Samoylov
Date: 2026-04-13T17:36:28+03:00
New Revision: 86e790076ab022573705aafae552ec3a3e2032a7
URL: https://github.com/llvm/llvm-project/commit/86e790076ab022573705aafae552ec3a3e2032a7
DIFF: https://github.com/llvm/llvm-project/commit/86e790076ab022573705aafae552ec3a3e2032a7.diff
LOG: [lldb] Fix lldb-server host and port address parsing (#191414)
This patch fixes 2 problems in lldb-server argument parser:
1. Let's try to start lldb-server with incorrect arguments
```
./lldb-server platform --listen *:1111--server
```
Current behavior
* lldb-server run in gdbserver mode with port 1111
Expected behavior
* fail, as `1111–server` is not a number
2. And try to start lldb-server with host:port specification without
colon
```
./lldb-server gdbserver 1111 ./test
Launched './test' as process 186...
lldb-server-local_build
lldb-server: llvm-project/lldb/source/Host/common/TCPSocket.cpp:245: virtual Status lldb_private::TCPSocket::Listen(llvm::StringRef, int): Assertion `error.Fail()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: ./lldb-server gdbserver 1111 ./test
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 lldb-server 0x0000002ab86d0ca2
1 lldb-server 0x0000002ab86ced06
2 lldb-server 0x0000002ab86d1428
3 linux-vdso.so.1 0x0000003f8e7fd800 __vdso_rt_sigreturn + 0
4 libc.so.6 0x0000003f8e2b264a
5 libc.so.6 0x0000003f8e27b1ac gsignal + 18
6 libc.so.6 0x0000003f8e26c14c abort + 180
7 libc.so.6 0x0000003f8e2760cc
8 libc.so.6 0x0000003f8e27610e __assert_perror_fail + 0
9 lldb-server 0x0000002ab86eb628
10 lldb-server 0x0000002ab86f1010
11 lldb-server 0x0000002ab86eeee0
12 lldb-server 0x0000002ab86eee5c
13 lldb-server 0x0000002ab863ef3a
14 lldb-server 0x0000002ab864067c
15 lldb-server 0x0000002ab86438da
16 libc.so.6 0x0000003f8e26c476
17 libc.so.6 0x0000003f8e26c51e __libc_start_main + 116
18 lldb-server 0x0000002ab863ce64
Aborted
```
We expect to see an error instead of lldb-server crash in this case
Added:
Modified:
lldb/source/Host/common/Socket.cpp
lldb/unittests/Host/SocketTest.cpp
lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerLLGSTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index 041dfbda0c21d..134591ebf9929 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -290,7 +290,12 @@ Socket::UdpConnect(llvm::StringRef host_and_port) {
llvm::Expected<Socket::HostAndPort>
Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
- static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)");
+ // This regex parses host:port combinations, supporting:
+ // - IPv4 sockets (e.g., "127.0.0.1:8080")
+ // - IPv6 sockets with host part in square brackets (e.g., "[::1]:80")
+ // Group 1: Address (IPv4, hostname, or IPv6 in [])
+ // Group 2: Port number (digits only)
+ static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+$)");
HostAndPort ret;
llvm::SmallVector<llvm::StringRef, 3> matches;
if (g_regex.match(host_and_port, &matches)) {
@@ -300,16 +305,13 @@ Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
ret.hostname = ret.hostname.substr(1, ret.hostname.size() - 2);
if (to_integer(matches[2], ret.port, 10))
return ret;
- } else {
- // If this was unsuccessful, then check if it's simply an unsigned 16-bit
- // integer, representing a port with an empty host.
- if (to_integer(host_and_port, ret.port, 10))
- return ret;
}
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "invalid host:port specification: '%s'",
- host_and_port.str().c_str());
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "invalid host:port specification: '%s', both IPv4 (e.g., localhost:8080) "
+ "or IPv6 (e.g, [2001:db8::1]:8080) formats are supported",
+ host_and_port.str().c_str());
}
IOObject::WaitableHandle Socket::GetWaitableHandle() {
diff --git a/lldb/unittests/Host/SocketTest.cpp b/lldb/unittests/Host/SocketTest.cpp
index 4ce436ec0214d..46be02e2de470 100644
--- a/lldb/unittests/Host/SocketTest.cpp
+++ b/lldb/unittests/Host/SocketTest.cpp
@@ -45,20 +45,23 @@ TEST_F(SocketTest, DecodeHostAndPort) {
EXPECT_THAT_EXPECTED(
Socket::DecodeHostAndPort("google.com:65536"),
llvm::FailedWithMessage(
- "invalid host:port specification: 'google.com:65536'"));
+ "invalid host:port specification: 'google.com:65536', both IPv4 "
+ "(e.g., localhost:8080) or IPv6 (e.g, [2001:db8::1]:8080) formats "
+ "are supported"));
EXPECT_THAT_EXPECTED(
Socket::DecodeHostAndPort("google.com:-1138"),
llvm::FailedWithMessage(
- "invalid host:port specification: 'google.com:-1138'"));
+ "invalid host:port specification: 'google.com:-1138', both IPv4 "
+ "(e.g., localhost:8080) or IPv6 (e.g, [2001:db8::1]:8080) formats "
+ "are supported"));
EXPECT_THAT_EXPECTED(
Socket::DecodeHostAndPort("google.com:65536"),
llvm::FailedWithMessage(
- "invalid host:port specification: 'google.com:65536'"));
-
- EXPECT_THAT_EXPECTED(Socket::DecodeHostAndPort("12345"),
- llvm::HasValue(Socket::HostAndPort{"", 12345}));
+ "invalid host:port specification: 'google.com:65536', both IPv4 "
+ "(e.g., localhost:8080) or IPv6 (e.g, [2001:db8::1]:8080) formats "
+ "are supported"));
EXPECT_THAT_EXPECTED(Socket::DecodeHostAndPort("*:0"),
llvm::HasValue(Socket::HostAndPort{"*", 0}));
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerLLGSTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerLLGSTest.cpp
index 23ab9a1b09dca..b4704606e8692 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerLLGSTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerLLGSTest.cpp
@@ -34,7 +34,6 @@ TEST(GDBRemoteCommunicationServerLLGSTest, LLGSArgToURL) {
// LLGS listen host:port pairs should be converted to listen://
EXPECT_EQ(LLGSArgToURL("127.0.0.1:1234", false), "listen://127.0.0.1:1234");
EXPECT_EQ(LLGSArgToURL("[::1]:1234", false), "listen://[::1]:1234");
- EXPECT_EQ(LLGSArgToURL("[[::1]:1234]", false), "listen://[[::1]:1234]");
EXPECT_EQ(LLGSArgToURL("localhost:1234", false), "listen://localhost:1234");
EXPECT_EQ(LLGSArgToURL("*:1234", false), "listen://*:1234");
@@ -45,19 +44,20 @@ TEST(GDBRemoteCommunicationServerLLGSTest, LLGSArgToURL) {
EXPECT_EQ(LLGSArgToURL("/tmp/foo", false), "unix-accept:///tmp/foo");
EXPECT_EQ(LLGSArgToURL("127.0.0.1", false), "unix-accept://127.0.0.1");
EXPECT_EQ(LLGSArgToURL("[::1]", false), "unix-accept://[::1]");
+ EXPECT_EQ(LLGSArgToURL("[[::1]:1234]", false), "unix-accept://[[::1]:1234]");
EXPECT_EQ(LLGSArgToURL("localhost", false), "unix-accept://localhost");
EXPECT_EQ(LLGSArgToURL(":frobnicate", false), "unix-accept://:frobnicate");
// LLGS reverse connect host:port pairs should be converted to connect://
EXPECT_EQ(LLGSArgToURL("127.0.0.1:1234", true), "connect://127.0.0.1:1234");
EXPECT_EQ(LLGSArgToURL("[::1]:1234", true), "connect://[::1]:1234");
- EXPECT_EQ(LLGSArgToURL("[[::1]:1234]", true), "connect://[[::1]:1234]");
EXPECT_EQ(LLGSArgToURL("localhost:1234", true), "connect://localhost:1234");
// with LLGS reverse connect, anything else goes as unix-connect://
EXPECT_EQ(LLGSArgToURL("/tmp/foo", true), "unix-connect:///tmp/foo");
EXPECT_EQ(LLGSArgToURL("127.0.0.1", true), "unix-connect://127.0.0.1");
EXPECT_EQ(LLGSArgToURL("[::1]", true), "unix-connect://[::1]");
+ EXPECT_EQ(LLGSArgToURL("[[::1]:1234]", true), "unix-connect://[[::1]:1234]");
EXPECT_EQ(LLGSArgToURL("localhost", true), "unix-connect://localhost");
EXPECT_EQ(LLGSArgToURL(":frobnicate", true), "unix-connect://:frobnicate");
}
More information about the lldb-commits
mailing list