v icon indicating copy to clipboard operation
v copied to clipboard

-autofree with net.len() Unknown address family ~/v/vlib/net/address.c.v:111

Open scriptmaster opened this issue 1 year ago • 7 comments

Describe the bug

v -autofree -cg run autofree.v

================ V panic ================
   module: net
 function: len()
  message: Unknown address family
     file: /Users/.../v/vlib/net/address.c.v:111
   v hash: bb9eaca
=========================================
0   autofree                            0x00000001000872b8 net__Addr_len + 360
1   autofree                            0x0000000100092e40 picoev__listen + 1336
2   autofree                            0x000000010009267c picoev__new + 84
3   autofree                            0x0000000100093f3c main__main + 152
4   autofree                            0x0000000100095a54 main + 72
5   dyld                                0x00000001a70f7e50 start + 2544

Reproduction Steps

Run this code with: v -autofree -cg run autofree.v

module main

import picoev
import picohttpparser

fn main() {
	mut server := picoev.new(family: .ip, port: 8008, cb: perf_route)
	server.serve()
}

fn perf_route(data voidptr, req picohttpparser.Request, mut res picohttpparser.Response) {
	res.http_ok()
	res.body('run with: v -autofree run autofree.v\n')
	// or with: v -autofree -cg autofree.v
	res.end()
}

Expected Behavior

Server should start similar to running without the -autofree flag

Current Behavior

Crashes:

================ V panic ================
   module: net
 function: len()
  message: Unknown address family
     file: /Users/.../v/vlib/net/address.c.v:111
   v hash: bb9eaca
=========================================
0   autofree                            0x00000001000872b8 net__Addr_len + 360
1   autofree                            0x0000000100092e40 picoev__listen + 1336
2   autofree                            0x000000010009267c picoev__new + 84
3   autofree                            0x0000000100093f3c main__main + 152
4   autofree                            0x0000000100095a54 main + 72
5   dyld                                0x00000001a70f7e50 start + 2544

Possible Solution

Tempfix: picoev fixed with detecting -autofree Permfix: check and fix how autofree does for net.c.v

Additional Information/Context

No response

V version

0.4.4

Environment details (OS name and version, etc.)

Mac (same error on linux too)

[!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.

scriptmaster avatar Jan 23 '24 00:01 scriptmaster

https://github.com/vlang/v/blob/master/vlib/picoev/socket_util.c.v#L126-L129

	// addr settings
	saddr := '${config.host}:${config.port}'
	addrs := net.resolve_addrs(saddr, config.family, .tcp) or { panic(err) }
	addr := addrs[0]
	alen := addr.len()

scriptmaster avatar Jan 23 '24 00:01 scriptmaster

Added two more test-data to explain the issue:

v -autofree run examples/net_resolve.v

import net

for addr in [
	':8080' //           this works
	'127.0.0.1:12700' // this does not 
	'vlang.io:80',
	'google.com:80',
	'steampowered.com:80',
	'api.steampowered.com:80',
] {
	println('${addr}')

	for @type in [net.SocketType.tcp, .udp] {
		family := net.AddrFamily.unspec

		addrs := net.resolve_addrs(addr, family, @type) or {
			println('> None')
			continue
		}

		for a in addrs {
			f := a.family()
			println('> ${a} ${f} ${@type}')
		}
	}
}

scriptmaster avatar Jan 23 '24 01:01 scriptmaster

v -autofree run examples/net_resolve.v                                                                                                ─╯
:8080
> 0.0.0.0:8080 ip tcp
> 0.0.0.0:8080 ip udp
127.0.0.1:12700
> <.unspec> unspec tcp
> <.unspec> unspec udp
vlang.io:80
> <.unspec> unspec tcp
> <.unspec> unspec tcp
> <.unspec> unspec tcp
> <.unspec> unspec tcp
> <.unspec> unspec udp
> <.unspec> unspec udp
> <.unspec> unspec udp
> <.unspec> unspec udp
google.com:80
> <.unspec> unspec tcp
> <.unspec> unspec tcp
> <.unspec> unspec udp
> <.unspec> unspec udp
steampowered.com:80
> <.unspec> unspec tcp
> <.unspec> unspec udp
api.steampowered.com:80
> <.unspec> unspec tcp
> <.unspec> unspec udp

Without autofree:

:8080
> 0.0.0.0:8080 ip tcp
> 0.0.0.0:8080 ip udp
127.0.0.1:12700
> 127.0.0.1:12700 ip tcp
> 127.0.0.1:12700 ip udp
vlang.io:80
> 104.21.22.45:80 ip tcp
> 172.67.202.167:80 ip tcp
> [2606:4700:3033::6815:162d]:80 ip6 tcp
> [2606:4700:3037::ac43:caa7]:80 ip6 tcp
> 104.21.22.45:80 ip udp
> 172.67.202.167:80 ip udp
> [2606:4700:3033::6815:162d]:80 ip6 udp
> [2606:4700:3037::ac43:caa7]:80 ip6 udp
google.com:80
> 142.250.193.142:80 ip tcp
> [2404:6800:4007:820::200e]:80 ip6 tcp
> 142.250.193.142:80 ip udp
> [2404:6800:4007:820::200e]:80 ip6 udp
steampowered.com:80
> 23.220.236.78:80 ip tcp
> 23.220.236.78:80 ip udp
api.steampowered.com:80
> 23.58.39.59:80 ip tcp
> 23.58.39.59:80 ip udp

scriptmaster avatar Jan 23 '24 01:01 scriptmaster

if the host is set to ":" it works, for example: picoev.new(host: ":", port: 8008, cb: perf_route)

this is because of these lines in vlib/net/address.c.v:resolve_ipaddrs:170-180

if addr[0] == `:` {
		match family {
			.ip6 {
				return [new_ip6(port, net.addr_ip6_any)]
			}
			.ip, .unspec {
				return [new_ip(port, net.addr_ip_any)]
			}
			else {}
		}
	}

scriptmaster avatar Jan 23 '24 01:01 scriptmaster

The issue comes down to something wrong when pushing an item to an array when using -autofree

addresses << new_addr

scriptmaster avatar Jan 23 '24 01:01 scriptmaster

same with println("string interpolation $myvar") with -autofree

scriptmaster avatar Jan 23 '24 01:01 scriptmaster

After simplifying:

fn foo () ![]int {
	mut arr := []int{}
	arr << 1
	return arr
}

fn main() {
	a := foo()!
	println(a)
}

v -autofree -cg run a.v:

[91]
a(69493,0x7ff8463cbb80) malloc: Double free of object 0x7f810ef05c10
a(69493,0x7ff8463cbb80) malloc: *** set a breakpoint in malloc_error_break to debug
Terminated by signal  6 (SIGABRT)

shove70 avatar Jan 24 '24 10:01 shove70