dotnet/runtime · critical

icall symbol maps not enabled, pass --enable-icall-symbol-ma

Error message

icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n

What it means

mono_lookup_icall_symbol_internal resolves a native function pointer to the name of its Mono internal call (icall), used for backtraces, profiling, and AOT metadata. Its real body is compiled only when ENABLE_ICALL_SYMBOL_MAP (set by configure --enable-icall-symbol-map) or TEST_ICALL_SYMBOL_MAP is defined; in any other build the function compiles to a stub that prints this message and calls g_assert_not_reached() (SIGABRT). The stub is registered as the runtime's icall-table callback in mono_icall_table_init, so any consumer that invokes symbol resolution triggers the abort.

Source

Thrown at src/mono/mono/metadata/icall-table.c:322

		T *functions_sorted = g_new (T, N);

		// Initialize with identity mapping. One line is easier to step over.
		for (T i = 0; i < N; ++i) functions_sorted [i] = i;

		mono_qsort (functions_sorted, N, sizeof (T), mono_qsort_icall_function_compare_indirect);

		gpointer old = mono_atomic_cas_ptr ((gpointer*)&static_functions_sorted, functions_sorted, NULL);
		if (old)
			g_free (functions_sorted);
	}

	T const * const slot = (const T*)bsearch (func, static_functions_sorted, N, sizeof (T), mono_bsearch_icall_function_compare_indirect);
	if (!slot)
		return NULL;
	return icall_functions [*slot].name;
#else
	fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
	g_assert_not_reached ();
	return NULL;
#endif
}

void
mono_icall_table_init (void)
{
	int i = 0;

	/* check that tables are sorted: disable in release */
	if (TRUE) {
		int j;
		const char *prev_class = NULL;
		const char *prev_method;

		for (i = 0; i < Icall_type_num; ++i) {
			const IcallTypeDesc *desc;

View on GitHub (pinned to 60108ba66e)

Solutions

  1. Rebuild Mono enabling the feature: ./configure --enable-icall-symbol-map (pass the same flag to autogen.sh/cmake as appropriate)
  2. If you cannot rebuild, disable the consumer that triggers the lookup (e.g. turn off the profiler/debugger)
  3. Use a runtime build documented to ship icall symbol maps (many release/desktop builds do; minimal/embedded ones often do not)

Example fix

# before
./configure --prefix=/opt/mono

# after
./configure --prefix=/opt/mono --enable-icall-symbol-map
Defensive patterns

Strategy: validation

Validate before calling

# Build-time / install-time check: confirm the runtime was built with icall symbol maps.
# After configure, grep config.h for the feature flag.
grep -q '#define ENABLE_ICALL_SYMBOL_MAP 1' "${MONO_BUILD_DIR:-.}/config.h" \
  && echo "ok: icall symbol map enabled" \
  || echo "missing: reconfigure with --enable-icall-symbol-map before relying on symbolication"

Prevention

When it happens

Trigger: Running a Mono runtime that was configured without --enable-icall-symbol-map while a component calls the icall symbol-lookup callback: native-stack symbolication in a profiler/debugger, AOT tooling that records icall names, or direct calls to mono_lookup_icall_symbol / mono_lookup_icall_symbol_internal.

Common situations: Distro-packaged or embedded/minimal Mono builds that disable icall symbol maps to reduce binary size; attaching a profiler or debugger that expects symbol resolution on such a build; upgrading to a runtime that no longer ships the symbol map.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/d4bb096ef0050e02. Report an issue: GitHub.