Skip to content

Fix NULL datagram segfault in parallel slave config FSM#155

Merged
sittner merged 2 commits intoparallel-slave-configfrom
copilot/fix-null-datagram-pointer
Mar 2, 2026
Merged

Fix NULL datagram segfault in parallel slave config FSM#155
sittner merged 2 commits intoparallel-slave-configfrom
copilot/fix-null-datagram-pointer

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 2, 2026

The parallel-slave-config branch crashes with SIGSEGV in EtherCAT-IDLE because ec_fsm_change_t (and sibling sub-FSMs) inside fsm_slave_config store their own datagram pointer, initialized to NULL and never updated before execution. When ec_fsm_change_state_start() fires, it dereferences fsm->datagram = 0x0.

Changes

  • master/fsm_slave.cec_fsm_slave_exec(): Propagate the incoming datagram to all config sub-FSMs (fsm_change, fsm_coe_config, fsm_soe_config, fsm_eoe_config) on every cycle — both at config start and during ongoing execution — since the pointer changes each cycle from the ext_ring:
if (fsm->config_running) {
    fsm->fsm_slave_config.datagram = datagram;
    fsm->fsm_change.datagram = datagram;      // was missing — root cause of crash
    fsm->fsm_coe_config.datagram = datagram;
    fsm->fsm_soe_config.datagram = datagram;
#ifdef EC_EOE
    fsm->fsm_eoe_config.datagram = datagram;
#endif
    ...
}
  • master/fsm_slave.h: Guard ec_fsm_eoe_t fsm_eoe_config with #ifdef EC_EOE to match the established pattern for EoE-conditional fields.

  • master/fsm_slave.c — init/clear: Guard ec_fsm_eoe_init/ec_fsm_eoe_clear for fsm_eoe_config with #ifdef EC_EOE; pass NULL for the eoe argument to ec_fsm_slave_config_init() when EC_EOE is disabled.

Original prompt

Bug Description

The parallel-slave-config branch crashes with a segmentation fault in the EtherCAT-IDLE thread when slaves need configuration. The crash occurs because the sub-FSMs (fsm_change, fsm_coe_config, fsm_soe_config, fsm_eoe_config) inside each slave's fsm_slave_config are initialized with a NULL datagram pointer, and this pointer is never updated before the sub-FSMs are executed.

Crash Backtrace

Thread 5 "EtherCAT-IDLE" received signal SIGSEGV, Segmentation fault.
#0  ec_datagram_prealloc (datagram=0x0, size=2) at ../datagram.c:142
#1  ec_datagram_fpwr (datagram=0x0, ...) at ../datagram.c:297
#2  ec_fsm_change_state_start (fsm=0x7ffff0001008) at ../fsm_change.c:195
#3  ec_fsm_change_exec (fsm=0x7ffff0001008) at ../fsm_change.c:159
#4  ec_fsm_slave_config_enter_init (fsm=0x7ffff0000ee0) at ../fsm_slave_config.c:241
#5  ec_fsm_slave_config_exec (fsm=0x7ffff0000ee0) at ../fsm_slave_config.c:202
#6  ec_fsm_slave_exec (fsm=0x7ffff0000d20, datagram=0x5555555758f8) at ../fsm_slave.c:178
#7  ec_master_exec_slave_fsms (master=0x555555574e30) at ../master.c:1341
#8  ec_master_idle_thread (priv_data=0x555555574e30) at ../master.c:1397

Root Cause

In master/fsm_slave.c, the ec_fsm_slave_init() function initializes the sub-FSMs with NULL datagram pointers:

ec_fsm_change_init(&fsm->fsm_change, NULL);   // NULL datagram!

When ec_fsm_slave_exec() runs, it sets fsm->fsm_slave_config.datagram = datagram but does NOT propagate the datagram pointer to the sub-FSMs (fsm_change, fsm_coe_config, fsm_soe_config, fsm_eoe_config). The ec_fsm_change_t struct stores its own separate datagram pointer, which remains NULL.

When ec_fsm_slave_config_exec() is called, it eventually calls ec_fsm_change_exec()ec_fsm_change_state_start()ec_datagram_fpwr(fsm->datagram, ...) where fsm->datagram is 0x0, causing the segfault.

Required Fix

In master/fsm_slave.c, in the ec_fsm_slave_exec() function, propagate the external datagram pointer to ALL sub-FSMs before executing ec_fsm_slave_config_exec(). This must be done both when starting configuration AND on every subsequent execution cycle (since the datagram pointer may change each cycle from the ext_ring):

if (fsm->config_requested && !fsm->config_running) {
    fsm->config_requested = 0;
    fsm->config_running = 1;
    fsm->fsm_slave_config.datagram = datagram;
    fsm->fsm_change.datagram = datagram;          // MUST SET
    fsm->fsm_coe_config.datagram = datagram;      // MUST SET  
    fsm->fsm_soe_config.datagram = datagram;      // MUST SET
    fsm->fsm_eoe_config.datagram = datagram;      // MUST SET
    ec_fsm_slave_config_start(&fsm->fsm_slave_config, fsm->slave);
}

if (fsm->config_running) {
    fsm->fsm_slave_config.datagram = datagram;
    fsm->fsm_change.datagram = datagram;          // MUST SET every cycle
    fsm->fsm_coe_config.datagram = datagram;      // MUST SET every cycle
    fsm->fsm_soe_config.datagram = datagram;      // MUST SET every cycle
    fsm->fsm_eoe_config.datagram = datagram;      // MUST SET every cycle
    // ...
}

Additionally, the fsm_eoe_config field in master/fsm_slave.h (line 82) and its init/clear calls in fsm_slave.c should be guarded with #ifdef EC_EOE to match the convention used elsewhere in the codebase. When EC_EOE is not defined, the ec_fsm_slave_config_init() call should pass NULL for the eoe parameter.

Files to Modify

  • master/fsm_slave.c — Propagate datagram to all sub-FSMs in ec_fsm_slave_exec(); guard fsm_eoe_config init/clear with #ifdef EC_EOE
  • master/fsm_slave.h — Guard ec_fsm_eoe_t fsm_eoe_config with #ifdef EC_EOE

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

- Propagate datagram to all sub-FSMs (fsm_change, fsm_coe_config,
  fsm_soe_config, fsm_eoe_config) in ec_fsm_slave_exec() to prevent
  segfault when fsm_change uses its stored NULL datagram pointer
- Guard ec_fsm_eoe_t fsm_eoe_config in fsm_slave.h with #ifdef EC_EOE
- Guard ec_fsm_eoe_init/clear calls for fsm_eoe_config with #ifdef EC_EOE
- Pass NULL for eoe parameter to ec_fsm_slave_config_init() when EC_EOE
  is not defined

Co-authored-by: sittner <1475582+sittner@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix segmentation fault in EtherCAT-IDLE thread Fix NULL datagram segfault in parallel slave config FSM Mar 2, 2026
@sittner sittner marked this pull request as ready for review March 2, 2026 10:24
@sittner sittner merged commit 0ad4d09 into parallel-slave-config Mar 2, 2026
@sittner sittner deleted the copilot/fix-null-datagram-pointer branch March 4, 2026 08:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants