aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristiano Haesbaert <haesbaert@haesbaert.org>2025-01-11 21:46:28 +0100
committerChristiano Haesbaert <haesbaert@haesbaert.org>2025-01-11 21:55:09 +0100
commitc51df72f1a8a21dd0064086dfc1186a3dd79e2ef (patch)
tree01c5e2a0a0cf60c202382d49651a1ec39002901d
parentcd93e2f6f8bb971e1d33bfc783ce4ab4e7568a5b (diff)
Make sure we don't leak os.args. Fixes #1633.
os.args is never freed, while this is an insignificant leak, it is a bit annoying as it makes valgrind complain: ==234270== Memcheck, a memory error detector ==234270== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al. ==234270== Using Valgrind-3.24.0 and LibVEX; rerun with -h for copyright info ==234270== Command: ./wc /tmp/mulumulu ==234270== 1 8 58 /tmp/mulumulu ==234270== ==234270== HEAP SUMMARY: ==234270== in use at exit: 47 bytes in 1 blocks ==234270== total heap usage: 5 allocs, 4 frees, 4,195,875 bytes allocated ==234270== ==234270== 47 bytes in 1 blocks are possibly lost in loss record 1 of 1 ==234270== at 0x484BC13: calloc (vg_replace_malloc.c:1675) ==234270== by 0x402E49: runtime._heap_alloc-769 (in /d/learn-odin/wc/wc) ==234270== by 0x40A8D7: runtime.heap_alloc (in /d/learn-odin/wc/wc) ==234270== by 0x436E9D: runtime.heap_allocator_proc.aligned_alloc-0 (in /d/learn-odin/wc/wc) ==234270== by 0x4022DC: runtime.heap_allocator_proc (in /d/learn-odin/wc/wc) ==234270== by 0x4165E0: runtime.make_aligned-22560 (in /d/learn-odin/wc/wc) ==234270== by 0x41F6D0: runtime.make_slice-22340 (in /d/learn-odin/wc/wc) ==234270== by 0x40156B: os._alloc_command_line_arguments-4679 (in /d/learn-odin/wc/wc) ==234270== by 0x4011AF: __$startup_runtime (in /d/learn-odin/wc/wc) ==234270== by 0x406F17: main (in /d/learn-odin/wc/wc) ==234270== ==234270== LEAK SUMMARY: ==234270== definitely lost: 0 bytes in 0 blocks ==234270== indirectly lost: 0 bytes in 0 blocks ==234270== possibly lost: 47 bytes in 1 blocks ==234270== still reachable: 0 bytes in 0 blocks ==234270== suppressed: 0 bytes in 0 blocks ==234270== ==234270== For lists of detected and suppressed errors, rerun with: -s ==234270== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) With the fix the leak is gone, tested on linux only. While here, also make _alloc_command_line_arguments() private.
-rw-r--r--core/os/os_darwin.odin7
-rw-r--r--core/os/os_freebsd.odin7
-rw-r--r--core/os/os_haiku.odin7
-rw-r--r--core/os/os_linux.odin7
-rw-r--r--core/os/os_netbsd.odin7
-rw-r--r--core/os/os_openbsd.odin7
-rw-r--r--core/os/os_wasi.odin7
-rw-r--r--core/os/os_windows.odin10
8 files changed, 51 insertions, 8 deletions
diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin
index d4435ec63..3247eeeee 100644
--- a/core/os/os_darwin.odin
+++ b/core/os/os_darwin.odin
@@ -1196,7 +1196,7 @@ _processor_core_count :: proc() -> int {
return 1
}
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__))
for _, i in res {
@@ -1205,6 +1205,11 @@ _alloc_command_line_arguments :: proc() -> []string {
return res
}
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
+
socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) {
result := _unix_socket(c.int(domain), c.int(type), c.int(protocol))
if result < 0 {
diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin
index 87a56b057..7eafb4993 100644
--- a/core/os/os_freebsd.odin
+++ b/core/os/os_freebsd.odin
@@ -936,7 +936,7 @@ _processor_core_count :: proc() -> int {
}
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ {
@@ -944,3 +944,8 @@ _alloc_command_line_arguments :: proc() -> []string {
}
return res
}
+
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin
index 4a57afb87..24d68d341 100644
--- a/core/os/os_haiku.odin
+++ b/core/os/os_haiku.odin
@@ -316,7 +316,7 @@ file_size :: proc(fd: Handle) -> (i64, Error) {
// "Argv" arguments converted to Odin strings
args := _alloc_command_line_arguments()
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ {
@@ -325,6 +325,11 @@ _alloc_command_line_arguments :: proc() -> []string {
return res
}
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
+
@(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin
index e023ce7cb..47b321f95 100644
--- a/core/os/os_linux.odin
+++ b/core/os/os_linux.odin
@@ -1069,7 +1069,7 @@ _processor_core_count :: proc() -> int {
return int(_unix_get_nprocs())
}
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ {
@@ -1078,6 +1078,11 @@ _alloc_command_line_arguments :: proc() -> []string {
return res
}
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
+
@(require_results)
socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) {
result := unix.sys_socket(domain, type, protocol)
diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin
index e3ba760a4..7bef85bed 100644
--- a/core/os/os_netbsd.odin
+++ b/core/os/os_netbsd.odin
@@ -986,7 +986,7 @@ _processor_core_count :: proc() -> int {
return 1
}
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ {
@@ -994,3 +994,8 @@ _alloc_command_line_arguments :: proc() -> []string {
}
return res
}
+
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin
index 3c377968c..c013fbc91 100644
--- a/core/os/os_openbsd.odin
+++ b/core/os/os_openbsd.odin
@@ -885,7 +885,7 @@ _processor_core_count :: proc() -> int {
return int(_sysconf(_SC_NPROCESSORS_ONLN))
}
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ {
@@ -893,3 +893,8 @@ _alloc_command_line_arguments :: proc() -> []string {
}
return res
}
+
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin
index 28f470357..0edc08415 100644
--- a/core/os/os_wasi.odin
+++ b/core/os/os_wasi.odin
@@ -27,7 +27,7 @@ stderr: Handle = 2
args := _alloc_command_line_arguments()
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> (args: []string) {
args = make([]string, len(runtime.args__))
for &arg, i in args {
@@ -36,6 +36,11 @@ _alloc_command_line_arguments :: proc() -> (args: []string) {
return
}
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ delete(args)
+}
+
// WASI works with "preopened" directories, the environment retrieves directories
// (for example with `wasmtime --dir=. module.wasm`) and those given directories
// are the only ones accessible by the application.
diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin
index 0c532bf14..3c1725cc5 100644
--- a/core/os/os_windows.odin
+++ b/core/os/os_windows.odin
@@ -193,7 +193,7 @@ current_thread_id :: proc "contextless" () -> int {
-@(require_results)
+@(private, require_results)
_alloc_command_line_arguments :: proc() -> []string {
arg_count: i32
arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), &arg_count)
@@ -215,6 +215,14 @@ _alloc_command_line_arguments :: proc() -> []string {
return arg_list
}
+@(private, fini)
+_delete_command_line_arguments :: proc() {
+ for s in args {
+ delete(s)
+ }
+ delete(args)
+}
+
/*
Windows 11 (preview) has the same major and minor version numbers
as Windows 10: 10 and 0 respectively.