Skip to content

Intermittent SIGSEGV in ld.so during agent shutdown (dlsym on unloaded content downloader) #908

Description

@JanZachmann

Summary

AducIotAgent intermittently crashes with SIGSEGV inside the dynamic loader
(ld-linux.so) during shutdown. Exit-only — the agent restarts fine, but
systemd records the stop as core-dump. Seen on aarch64, 1.4.0.

Root cause

ExtensionManager::Uninit() runs twice during shutdown:

  • via AzureDeviceUpdateCoreInterface_Destroy (linux_adu_core_impl.cpp, from
    ADUC_PnP_Components_Destroy), and
  • via ExtensionManager_Uninit() in the agent's ShutdownAgent (main.c).

ExtensionManager::UnloadAllExtensions() dlcloses the content-downloader
library (in _libs) and clears _libs, but never resets the static
_contentDownloader handle or _contentDownloaderContractVersion. So the second
call still sees _contentDownloader != nullptr and a V2 contract, and runs
dlsym(_contentDownloader, "Cleanup") on the freed handle. glibc's
do_lookup_x then walks a freed link_map → intermittent SEGV_MAPERR
(intermittent because the freed memory is sometimes still mapped).

Symbolized crashing stack (from a device core):

do_lookup_x (undef_name="Cleanup", undef_map=<freed link_map>)   ld.so
_dl_lookup_symbol_x -> do_sym -> _dl_sym -> ___dlsym
ExtensionManager::UnloadAllExtensions()  extension_manager.cpp:418
ShutdownAgent -> ExtensionManager_Uninit

Reproduces when

A V2-contract content downloader is loaded (curl is the default in 1.4.0) and
the agent is stopped (SIGTERM) — e.g. during an OS update. Intermittent.

Fix

Reset _contentDownloader and _contentDownloaderContractVersion after the
dlclose loop in UnloadAllExtensions() so a repeat Uninit is a no-op. PR
attached.

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