Skip to content

Create or document way to clear all global memory #21403

@PMunch

Description

@PMunch

Summary

This came about when working with dynamic libraries. If you write a dynamic library in Nim and then load it into a separate program there is no (documented) way to free all the memory if the loader program unloads the dynamic library. This means that if a system loads and unloads a dynamic library it will keep increasing in memory.

Description

What I propose is to create a procedure NimQuit opposite of NimMain which will destroy all memory. Calling any other code using GC after that will be undefined behaviour. This would then be called automatically in .fini by attaching __attribute((destructor))__ or hooking in DllMain, similar to how NimMain is called today. And analogous to how --noMain disables this behaviour --noQuit should prevent it from being called and NimQuit must be called exlicitly.

Alternatives

No response

Examples

As a simple example/testing ground I wrote this:

loader.nim:

import std/dynlib
type
  InitFunction = proc () {.cdecl.}
  DeinitFunction = proc () {.cdecl.}

proc loadDynamic() =
  let lib = loadLib("./liblibrary.so")
  assert lib != nil, "Error loading library"

  let init = cast[InitFunction](lib.symAddr("dynlib_init"))
  assert init != nil, "Error loading 'init' function from library"
  let deinit = cast[DeinitFunction](lib.symAddr("dynlib_deinit"))
  assert deinit != nil, "Error loading 'deinit' function from library"

  init()
  deinit()

  unloadLib(lib)

while true:
  loadDynamic()

library.nim:

var x = newSeq[byte](uint16.high)

proc NimMain() {.cdecl, importc.}

proc dynlib_init() {.cdecl, exportc, dynlib.} =
  NimMain()
  echo "Loaded dynamic library"

proc dynlib_deinit() {.cdecl, exportc, dynlib.} =
  GC_FullCollect()

Compiled with:

nim c --gc:orc loader.nim

and

nim c --app:lib --noMain --gc:orc library.nim

Backwards Compatibility

No response

Links

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions