v
v copied to clipboard
net: net.listen_tcp fail in -prod mode
Describe the bug
when compile a simple net app, it will fail in prod mode
Reproduction Steps
test.v
module main
import net
fn main() {
net.listen_tcp(.ip6, ':8081') or {
ecode := err.code()
panic('failed to listen ${ecode} ${err}')
}
println('hello world')
}
Compile in prod mode
v test.v -prod
Then run ./test
Expected Behavior
should run without panic
hello world
Current Behavior
V panic: failed to listen 0 net: socket error: 88; code: 88; binding to :8081 failed v hash: 298a2a2 | 0x7f3953c29d90 | /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) | 0x7f3953c29e40 | /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) | 0x560c9ac42745 | ./test(+0x3745)
Possible Solution
compile with tcc, will OK
v test.v
Additional Information/Context
No response
V version
V 0.4.4 298a2a2
Environment details (OS name and version, etc.)
V full version: V 0.4.4 349741d.298a2a2 OS: linux, Ubuntu 22.04.4 LTS Processor: 8 cpus, 64bit, little endian, Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
getwd: /home/mars/v/wrk vexe: /HD/github/kbkpbot/v/v vexe mtime: 2024-02-17 11:53:11
vroot: OK, value: /HD/github/kbkpbot/v VMODULES: OK, value: /home/mars/.vmodules VTMP: OK, value: /tmp/v_1000
Git version: git version 2.34.1 Git vroot status: weekly.2024.06-92-g298a2a2d .git/config present: true
CC version: cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 thirdparty/tcc status: thirdparty-linux-amd64 99683af0
[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.
change
net.listen_tcp(.ip6, ':8081')
to
net.listen_tcp(.ip, ':8081')
The same panic.
If comment out s.set_dualstack(options.dualstack) or {}
in vlib/net/tcp.c.v pub fn listen_tcp
,
then has no this bug.
v test.v -cc clang -prod
this is ok (Ubuntu clang version 14.0.0-1ubuntu1.1)
v test.v -cc gcc -prod
this will panic(gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)) .
gcc -fwrapv -O2 -flto -DNDEBUG "/home/mars/.vmodules/cache/76/769009b5e03b3475e2b1f9c2b837a8b2.module.builtin.o" -o "/home/mars/v/wrk/test" -D GC_BUILTIN_ATOMIC=1 -D GC_THREADS=1 -I "/HD/github/kbkpbot/v/thirdparty/libgc/include" "/tmp/v_1000/test.tmp.c" -std=gnu99 -D_DEFAULT_SOURCE -ldl -lpthread
compile will show warning, and the test is OK
lto-wrapper: warning: using serial compilation of 3 LTRANS jobs
But if compile with -O3
, compile will show warnings , and the test if panic
gcc -fwrapv -O3 -flto -DNDEBUG "/home/mars/.vmodules/cache/76/769009b5e03b3475e2b1f9c2b837a8b2.module.builtin.o" -o "/home/mars/v/wrk/test" -D GC_BUILTIN_ATOMIC=1 -D GC_THREADS=1 -I "/HD/github/kbkpbot/v/thirdparty/libgc/include" "/tmp/v_1000/test.tmp.c" -std=gnu99 -D_DEFAULT_SOURCE -ldl -lpthread
lto-wrapper: warning: using serial compilation of 3 LTRANS jobs
In function ‘memcpy’,
inlined from ‘vmemcpy’ at /tmp/v_1000/test.tmp.c:10128:10,
inlined from ‘string_clone’ at /tmp/v_1000/test.tmp.c:12341:3,
inlined from ‘string_trim’ at /tmp/v_1000/test.tmp.c:13617:10,
inlined from ‘string_trim_space’ at /tmp/v_1000/test.tmp.c:13612:9,
inlined from ‘print_backtrace_skipping_top_frames_linux.isra’ at /tmp/v_1000/test.tmp.c:9323:15:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10: warning: ‘__builtin_memcpy’ specified bound between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]
29 | return __builtin___memcpy_chk (__dest, __src, __len,
| ^
In function ‘memcpy’,
inlined from ‘vmemcpy’ at /tmp/v_1000/test.tmp.c:10128:10,
inlined from ‘string_clone’ at /tmp/v_1000/test.tmp.c:12341:3,
inlined from ‘string_all_before’ at /tmp/v_1000/test.tmp.c:13989:10,
inlined from ‘print_backtrace_skipping_top_frames_linux.isra’ at /tmp/v_1000/test.tmp.c:9305:26:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10: warning: ‘__builtin_memcpy’ specified bound between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]
29 | return __builtin___memcpy_chk (__dest, __src, __len,
| ^
Search found that a open issue has same problem: #18738
For me, it fails with gcc, but succeeds with clang.
It's only on linux for me, have no issues on windows
After some tests, I found that in -prod
mode, after s := new_tcp_socket()
in fn listen_tcp()
, s.handle
will become ZERO.
This will cause following operations on socket s
fail.
Not sure what cause this bug. Maybe gcc -O3 -flto
flag? (compile without -flto
or just -O2 -flto
will remove this bug)
https://github.com/vlang/v/blob/fa7af809fcd36b20d7609df98bcf835e02a11521/vlib/net/tcp.c.v#L334
pub fn listen_tcp(family AddrFamily, saddr string, options ListenOptions) !&TcpListener {
if family != .ip && family != .ip6 {
return error('listen_tcp only supports ip and ip6')
}
mut s := new_tcp_socket(family) or { return error('${err.msg()}; could not create new socket') }
// -prod mode, will make s.handle = 0 here, this is not correct!
s.set_dualstack(options.dualstack) or {}
addrs := resolve_addrs(saddr, family, .tcp) or {
return error('${err.msg()}; could not resolve address ${saddr}')
}
By disassemble the ./test
file, it shows that gcc -O3 -flto
generate wrong instruction sequence.
At 0000564A60BA76FC , it read handle
into ebx (which is ZERO), then use rep movsd
update the handle
to its correct value.
.text:0000564A60BA76E0 loc_564A60BA76E0: ; CODE XREF: main__main+8FC↓j
.text:0000564A60BA76E0 movdqa xmm7, cs:_const_none__
.text:0000564A60BA76E8 mov eax, dword ptr [rsp+578h+src]
.text:0000564A60BA76EC mov byte ptr [rsp+578h+var_338], 0
.text:0000564A60BA76F4 lea rdi, [rsp+578h+var_4C8]
.text:0000564A60BA76FC mov ebx, [rsp+578h+fd] ; <================Read `handle`
.text:0000564A60BA7703 mov ecx, 0Ch
.text:0000564A60BA7708 mov rsi, rbp
.text:0000564A60BA770B movups [rsp+578h+var_330], xmm7
.text:0000564A60BA7713 movdqa xmm7, cs:xmmword_564A60BF8910
.text:0000564A60BA771B mov dword ptr [rsp+578h+var_310], eax
.text:0000564A60BA7722 rep movsd ; <==============Update `handle`
.text:0000564A60BA7724 xor esi, esi
.text:0000564A60BA7726 mov edi, ebx ; <=================Use `handle`
.text:0000564A60BA7728 movups [rsp+578h+var_320], xmm7
.text:0000564A60BA7730 call indent_net__TcpSocket_str
.text:0000564A60BA7735 mov rdi, rax ; ptr
.text:0000564A60BA7738 mov esi, edx
.text:0000564A60BA773A test rax, rax
.text:0000564A60BA773D jz loc_564A60BA7E90
.text:0000564A60BA7743 call _writeln_to_fd_constprop_0_isra_0