`sofia_process_dispatch_event_in_thread` allocated `td` from a memory pool,
then `sofia_msg_thread_run_once` destroyed that same pool after processing
the event — leaving `td` dangling when the thread pool worker accessed it.
Allocate `td` with `switch_zmalloc` (`td->alloc = 1`) so the worker frees it
safely after the function returns. Remove the now-unused `pool` field from
`sofia_dispatch_event_t`.
`switch_core_session_thread_pool_launch()` allocated the thread data (`td`)
from the session pool. However, `switch_core_session_thread()` destroys
the session pool before returning, leaving td as a dangling pointer.
The worker then accesses `td->running` and `td->pool` — a use-after-free
that crashes under memory pressure when the freed pool is reused.
Allocate `td` with `switch_zmalloc()` and set `td->alloc = 1` so the worker frees it
after the task completes. This ensures `td` outlives the session pool
destruction.
Changes:
- Snapshot `erl_errno` after `ei_xreceive_msg_tmo()` — outbound `ei_*` calls in the same loop iteration clobber the thread-local errno before the listener checks it, causing wrong exit decisions and misleading logs.
- Fix `switch_size_t ` cast of `int` in `ei_link`* — `(switch_size_t *)&index` reads/writes 8 bytes through a 4-byte `int` on LP64. Use a real `switch_size_t` local.
- Dispatch `ERL_NEWER_REFERENCE_EXT` — newer OTP encodes refs with this tag; spawn replies from modern nodes were silently dropped to the default branch.
- Handle `ERL_EXIT2` — processes killed via `erlang:exit/2` arrive with this tag, not `ERL_EXIT`. Without it, sessions stayed attached to dead Erlang pids.
- Modernize `-spec` syntax in `freeswitch.erl` — old `-spec(F/N :: (...))` form was removed in OTP 21+; module no longer compiled.
- Fix multiple memory issues:
- `ei_hash_ref()`: replace unbounded `sprintf` with `snprintf` + shared `EI_HASH_REF_LEN`.
- `handle_msg_sendevent` / `handle_msg_sendmsg`: free the heap `value` on `ei_decode_string` failure; remove dead `if (!fail)` branches.
- `listener_main_loop`: free `buf`/`rbuf` on the two `handle_msg` early-exit paths.
- `erlang_sendmsg_function` app: move `ei_x_new_with_version` past arg validation and add `ei_x_free` at the end.