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
| Option | Long form | Behavior |
|---|---|---|
| (none) | (none) | Start an interactive IOC from st.cmd |
-n | --show | Print the generated startup and exit without starting the IOC |
-S | --non-interactive | Disable the interactive iocsh prompt |
-v | --verbose | Also display the built-in startup commands of softIocPVX |
-e "$TREE" | --environment "$TREE" | Source "$TREE/setEpicsEnv.bash" inside the loader process |
-h | --help | Print 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 condition | Stage | Corrective action |
|---|---|---|
| Module or requested version absent | iocsh.bash preflight | Select a module name and version present under $EPICS_MODULES |
| Transitive and explicit versions conflict | iocsh.bash preflight | Keep one compatible version per module across the IOC |
module placed inside iocshLoad fragment | softIocPVX runtime | Move all module directives to the top-level st.cmd |
Unknown command or syntax error in st.cmd | softIocPVX runtime (/dev/fd/4) | Fix the reported line number in st.cmd |
| Database or protocol path missing | softIocPVX runtime | Start 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"