unload(n)

✨ NAME ✨

unload β€” bestie, this is how you unload machine code. Like, yeet a shared library back out of your process. It's giving reverse-load. πŸ’…

Oh and hey β€” this page is unload(n), from the Tcl Built-In Commands manual, so you know it's official. πŸ‘‘


πŸŽ€ SYNOPSIS πŸŽ€

unload ?switches? fileName
unload ?switches? fileName prefix
unload ?switches? fileName prefix interp

πŸ’– DESCRIPTION πŸ’–

Okay so, unload is the main character that tries to unload shared libraries that you previously loaded with load, pulling them out of the application's address space. Iconic.

  • fileName is the name of the file containing the library you wanna unload. Important: it has to be the exact same filename you gave to load when you loaded it. No improvising, bestie. 😀
  • prefix is the prefix (as determined by, or passed to, load), and it gets used to compute the name of the unload procedure. If you don't supply it, Tcl computes it from fileName the same way load does.
  • interp is the path name of the interpreter to unload the package from (peep the interp manual entry for the deets). If interp is omitted, it defaults to the interpreter where you invoked the unload command in the first place. 🫢

If the initial arguments to unload start with -, they're treated as switches. Here's what we've got rn:

  • -nocomplain β€” suppresses all error messages. If you pass this, unload will literally never report an error. Never ever.
  • -keeplibrary β€” stops unload from making the operating system call that would unload the library from the process. Like, keep it around, don't @ me.
  • -- β€” marks the end of switches. The argument after this one is treated as a fileName even if it starts with a -. Sneaky little hyphen? Not today. 🚫

🧚 UNLOAD OPERATION 🧚

So when a file with a shared library gets loaded through load, Tcl keeps two reference counts on that library file:

  1. The first counter = how many times it's been loaded into normal (trusted) interpreters.
  2. The second counter = how many times it's been loaded into safe interpreters.

A shared library file can only be loaded once by Tcl (that's the first load call on the file), so these counters basically track how many interpreters are using the library. Every load after the first one just bumps the proper reference count. Simple math, slay. ✨

unload works in the opposite direction. Step one: it checks whether the library is even unloadable. An unloadable library exports a special unload procedure, and its name depends on prefix and whether the target interpreter is a safe one:

  • For normal interpreters, the name of the initialization procedure has the form pfx_Unload, where pfx is the same as prefix except the first letter is converted to upper case and all the other letters get converted to lower case. So if prefix is foo or FOo, the initialization procedure's name will be Foo_Unload.
  • If the target interpreter is a safe interpreter, then the initialization procedure's name will be pkg_SafeUnload instead of pkg_Unload.

If unload figures out the library is not unloadable (or if unload functionality was disabled during compilation), you get an error. If it is unloadable, unload calls the unload procedure. If that procedure returns TCL_OK, unload proceeds and decreases the proper reference count (depending on the target interpreter type). And when both reference counts hit 0, the library gets detached from the process. πŸ¦‹


πŸ¦‹ UNLOAD HOOK PROTOTYPE πŸ¦‹

The unload procedure has to match this prototype exactly, no cap:

typedef int Tcl_LibraryUnloadProc(
        Tcl_Interp *interp,
        int flags);
  • The interp argument identifies the interpreter the library is being unloaded from.
  • The unload procedure must return TCL_OK or TCL_ERROR to show whether it completed successfully. If there's an error, it should set the interpreter's result to point to an error message. In that case, the result of the unload command will be whatever result the unload procedure returned.

The flags argument can be either TCL_UNLOAD_DETACH_FROM_INTERPRETER or TCL_UNLOAD_DETACH_FROM_PROCESS:

  • If the library will remain attached to the process after the unload procedure returns (like, because other interpreters are using it), TCL_UNLOAD_DETACH_FROM_INTERPRETER will be defined.
  • But if the library is used only by the target interpreter and it'll be detached from the application as soon as the unload procedure returns, then flags gets set to TCL_UNLOAD_DETACH_FROM_PROCESS.

🌸 NOTES 🌸

  • unload cannot unload libraries that are statically linked with the application. It's just not that girl. 😭
  • If fileName is an empty string, then the prefix argument must be specified.

If prefix is omitted or specified as an empty string, Tcl tries to guess it. This can happen differently on different platforms. The default guess β€” used on most UNIX platforms β€” is:

  • take the last element of fileName,
  • strip off the first three characters if they are lib,
  • then strip off the next three characters if they are tcl9,
  • and use any following wordchars but not digits, converted to titlecase, as the prefix.

For example: the command unload libxyz4.2.so uses the prefix Xyz, and the command unload bin/last.so {} uses the prefix Last. See? Told you. πŸ”₯


πŸ’… PORTABILITY ISSUES πŸ’…

Unix

Not all unix operating systems support library unloading. On such an operating system, unload returns an error β€” unless -nocomplain has been specified. So yeah, check before you wreck. πŸ™ˆ


πŸ’€ BUGS πŸ’€

Okay bestie, listen up, this part is serious. πŸ‘‡
  • If the same file is loaded under different fileNames, it will be loaded into the process's address space multiple times. The behavior of this varies from system to system (some systems may detect the redundant loads, others may not).
  • In case a library has been silently detached by the operating system (and as a result Tcl thinks the library is still loaded), it may be dangerous to use unload on such a library β€” because the library will be completely detached from the application while some interpreters will continue to use it. That's a whole mess. Don't do it.

🌈 EXAMPLE 🌈

Say you've got an unloadable module in the file foobar.dll that was loaded with the load command like this (on Windows):

load c:/some/dir/foobar.dll

Then it would be unloaded like this:

unload c:/some/dir/foobar.dll

This lets a C code module get installed temporarily into a long-running Tcl program and then removed again β€” either because it's no longer needed or because it's being updated with a new version β€” without having to shut down the whole Tcl process. Temporary glow-up, permanent vibes. 🌟


πŸ”₯ SEE ALSO πŸ”₯


πŸ‘‘ KEYWORDS πŸ‘‘

  • binary code
  • unloading
  • safe interpreter
  • shared library

Okay that's the whole page, you ate it, you're a shared-library-unloading icon now πŸ’–βœ¨

This was Tcl 8.5's unload(n) β€” mwah, go forth and detach responsibly. πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from