Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

6.5 Module selection and loader errors

Inspect Input/Output Controller (IOC) startup generation, pin installed module versions, check exported module macros, and diagnose the four main error patterns reported by iocsh.bash and softIocPVX.

Loader command options

OptionLong formBehavior
(none)(none)Start an interactive IOC from st.cmd
-n--showPrint the generated startup and exit without starting the IOC
-S--non-interactiveDisable the interactive iocsh prompt
-v--verboseAlso display the built-in startup commands of softIocPVX
-e "$TREE"--environment "$TREE"Source "$TREE/setEpicsEnv.bash" inside the loader process
-h--helpPrint usage information and exit

Run iocsh.bash from the directory containing st.cmd and its relative database files. When using -e "$TREE", pass an absolute installation path; -e sets environment variables only inside the loader process, not in your interactive client shell.

Module directive syntax

Place one module directive per line in the top-level startup file passed to iocsh.bash to follow the default symlink:

module StreamDevice

Append an explicit version token to pin one installed build:

module StreamDevice 2.8.26

iocsh.bash also accepts the function-style syntax:

module("StreamDevice", "2.8.26")

mod and m work as short aliases for module. Directives placed inside an iocshLoad fragment or typed at the interactive iocsh prompt fail because module is parsed by iocsh.bash before softIocPVX starts.

Installed module metadata and macro exports

In an activated shell (set TREE as in lesson 1.1 and run source "$TREE/setEpicsEnv.bash" if opening a fresh terminal), inspect StreamDevice’s default symlink target and its loader metadata file:

readlink -f "$EPICS_MODULES/StreamDevice"
cat "$EPICS_MODULES/StreamDevice/cfg/iocsh.conf"

cfg/iocsh.conf records the build’s EPICS Base version, target architecture, exported environment macro, transitive module dependencies, shared libraries, and database definition (DBD) files:

/home/jeonglee/epics/1.5.0/debian-13/7.0.10/modules/StreamDevice-2.8.26
format=1
name=StreamDevice
version=2.8.26
base=7.0.10
arch=linux-x86_64
macro=STREAM
dep=asyn 4.46.0
dep=calc 3.8.0
lib=lib/linux-x86_64/libstream.so
dbd=dbd/stream.dbd

For every resolved module, iocsh.bash reads macro= from cfg/iocsh.conf and emits epicsEnvSet("<MACRO>", "<module_dir>") before running your startup. Loading StreamDevice exports STREAM, ASYN, CALC, SSCAN, and SNCSEQ; loading linStat, autosave, and retools exports LINSTAT, AUTOSAVE, and RETOOLS. Shared fragments under $(EPICS_MODULES)/commonIocsh/iocsh/ use these macros to locate installed databases without hardcoded version paths.

Startup errors to recognize

Error conditionStageCorrective action
Module or requested version absentiocsh.bash preflightSelect a module name and version present under $EPICS_MODULES
Transitive and explicit versions conflictiocsh.bash preflightKeep one compatible version per module across the IOC
module placed inside iocshLoad fragmentsoftIocPVX runtimeMove all module directives to the top-level st.cmd
Unknown command or syntax error in st.cmdsoftIocPVX runtime (/dev/fd/4)Fix the reported line number in st.cmd
Database or protocol path missingsoftIocPVX runtimeStart from the expected directory or correct the path macro

A clean iocsh.bash -n preview proves module resolution and shared-library linkage. Run the IOC and read its process variables (PVs) to confirm database loading, record initialization, and device communication.

Reproduce four loader diagnostic checks

Run these checks in an activated shell (set TREE as in lesson 1.1 and run source "$TREE/setEpicsEnv.bash" if opening a fresh terminal). Create a temporary directory outside the distribution to test four failure modes without affecting earlier workspaces:

DIAG_WORK="$(mktemp -d)"
cd "$DIAG_WORK"

Check a missing module

Save a startup referencing a nonexistent module as st_missing.cmd:

module missing_training_module
iocInit()

Run a dry-run preview against st_missing.cmd:

iocsh.bash -n st_missing.cmd

iocsh.bash exits with status 1 before starting softIocPVX and names the file and line number:

iocsh.bash: Module missing_training_module has no installed default link: /home/jeonglee/epics/1.5.0/debian-13/7.0.10/modules/missing_training_module (st_missing.cmd:1)

Check a dependency version conflict

Save a startup requesting both StreamDevice (built against asyn 4.46.0) and an incompatible asyn version as st_conflict.cmd:

module StreamDevice
module asyn 4.44.0
iocInit()

Preview st_conflict.cmd to trigger dependency resolution:

iocsh.bash -n st_conflict.cmd

iocsh.bash exits with status 1 and identifies both conflicting requests:

iocsh.bash: Module version conflict: asyn
Requested: 4.44.0 at st_conflict.cmd:2
Selected:  4.46.0 at StreamDevice 2.8.26 (st_conflict.cmd:1)
Use one version of asyn in this IOC.

Check a module directive inside a fragment

Save a module directive inside frag.iocsh:

module busy

Save a top-level startup that loads frag.iocsh as st_frag.cmd:

on error break
iocshLoad("frag.iocsh")
iocInit()

Run st_frag.cmd with standard input closed so softIocPVX exits after processing the startup:

iocsh.bash st_frag.cmd < /dev/null

Because iocsh.bash scans only st_frag.cmd, softIocPVX reads frag.iocsh directly and rejects module as an unregistered IOC shell command:

ERROR frag.iocsh line 1: Command 'module' not registered.

Check line-number mapping on /dev/fd/4

Save a five-line startup with an invalid command on line 4 as st_fd4.cmd:

on error break
module busy
# line 3 comment
unknownStartupCommand()
iocInit()

Run st_fd4.cmd non-interactively with -S:

iocsh.bash -S st_fd4.cmd

iocsh.bash replaces line 2 (module busy) with a comment rather than deleting lines, so ERROR 4 line 4 points directly to line 4 of st_fd4.cmd and on error break exits with status 2:

iocsh.bash: /tmp/tmp.CeRIUTG9uM/st_fd4.cmd runs as /dev/fd/4; generated startup runs as /dev/fd/3
ERROR 4 line 4: Command 'unknownStartupCommand' not registered.
iocsh Error: Break
iocsh Error: Break
ERROR: Error in /dev/fd/3

When finished inspecting the four checks, leave and remove the temporary directory:

cd ~
rm -rf "$DIAG_WORK"