SECS/GEM troubleshooting
Use this page when the PDComm SECS/GEM SDK or simulator doesn’t do what you expect. It helps you find the stage that fails and points you to the details. For the meaning of each code, see Status codes and errors. For connection and timer problems, see Connections and timeouts.
Find where it stops
Section titled “Find where it stops”A SECS/GEM session moves through these stages in order. Each stage must finish before the next one starts.
Program start ─> TCP connection ─> HSMS Select ─> GEM communication ─> Requests and replies(library load) tcp=1,2,5 tcp=3 → 4 gem=1 → 3 RESULT ...In the tutorial peers (pdcomm-tutorial and PDComm.Tutorial), type state to see the current stage:
STATE tcp=4 gem=1tcpis the HSMS connection state: 0 Stopped, 1 Connecting, 2 Listening, 3 NotSelected, 4 Selected, 5 RetryWait.gemis the GEM communication state: 0 Disconnected, 1 NotCommunicating, 2 WaitingAck, 3 Communicating.
The C# peer prints the names instead, for example STATE tcp=Selected gem=NotCommunicating. In the simulator GUI, the TCP TRANSPORT, HSMS SELECTION, and GEM COMMUNICATION cards on the Overview workspace show the same information.
When you need a record of what happened, turn on the diagnostics log. Diagnose failures and send feedback shows how.
Symptoms and checks
Section titled “Symptoms and checks”| Symptom | Check first | Check next |
|---|---|---|
| The program can’t load the library at startup. | Make sure the operating system and CPU architecture match the SDK bundle, and that the loader can find the native library: PATH on Windows, LD_LIBRARY_PATH on Linux, or an rpath to sdk/lib that you add with -Wl,-rpath when you build on macOS. |
Windows C++ programs also need the x64 Visual C++ runtime. On macOS, dyld: Library not loaded: @rpath/libpdcomm_ffi.dylib means the rpath is missing. |
A C# program fails in PdcommRuntime.Initialize. |
Pass the absolute path of the native library. A wrong path raises System.DllNotFoundException. |
NotSupportedException means that PDComm.dll and the native library have incompatible ABI versions. Use both files from the same SDK bundle. |
| The simulator can’t find the Qt platform plugin. | Copy the whole simulator folder, including its plugins and notice files. |
Clear QT_PLUGIN_PATH or QTDIR if they point to another Qt installation. On a Linux server without a display, use the headless simulator. |
The passive side stays at tcp=2 (Listening). |
Check that the active program runs and uses the same IP address and port. | Check that both sides aren’t passive and that no firewall blocks the port. |
The active side keeps returning to tcp=5 (RetryWait). |
Check that something listens on that port. If nothing does, the connection is refused. | See Connection refused. |
TCP connects, but the state stays at tcp=3 (NotSelected). |
Check the log for a T6 timeout: the peer didn’t answer Select.req. | Check whether another host already uses the equipment. See TCP connects but never becomes Selected. |
The state is tcp=4 (Selected) but gem=1 (NotCommunicating). |
Make sure the host requested S1F13: establish in the tutorial, Establish communication in the GUI. |
If S1F13 fails after T3, check that both sides use the same session ID. PDComm doesn’t resend S1F13 by itself. |
values returns nothing or unexpected values. |
Make sure the IDs exist on the peer. The simulator’s built-in equipment has SVIDs 1001 and 1002; the tutorial equipment has SVIDs 1 and 2. | An unknown ID comes back as a zero-length item. For example, the reply to values 9 is SECS-II 01 01 01 00. |
You see COMMAND ERROR ... InvalidState. |
The request isn’t allowed in the current state, for example values before communication is established, or a second establish. |
Check the role, and check that you don’t call a setup function that’s only allowed before start. |
You see COMMAND ERROR ... Backpressure. |
The endpoint already waits for replies to 32 requests, or an event queue is full. | Keep draining events, and send again after the replies or failures arrive. Don’t retry in a tight loop. |
You see StaleToken. |
You used a token or event from a generation before a reconnect. | After a reconnect, start the flow again with new requests. |
A request ends with RESULT kind=3 (Failed). |
Find out whether T3 expired, the peer aborted the transaction with F0, or the connection dropped. | See GEM results and T3 reply timeout. |
| One request always fails after T3, and later every request fails. | Check whether the peer application leaves W1 messages it doesn’t handle without a reply. | Every W1 message needs a reply, at least an F0 abort. See Unhandled messages and S9. |
Every call returns Poisoned. |
The endpoint caught an unexpected internal failure and can’t be used anymore. | Destroy the endpoint and create a new one. Send the reproduction steps and the log to support. |
| A SECS-I endpoint reports a Fault event. | Make sure the read and write callbacks return immediately and never report more bytes than the buffer holds. | Don’t call endpoint functions from inside a callback, and use the endpoint only on the thread that created it. See SECS-I virtual pair. |
| The log shows that a request was accepted but nothing after that. | Acceptance only means the request was queued. Look for a reply (RESULT kind=2) or a failure (kind=3). |
Confirm that the equipment actually finished the work through its own events or values. ACK 0 means the request was accepted, not that the work is done. |
When a GUI button is disabled, read its tooltip and the feedback text at the bottom of the workspace first. If you repeat an action before the state is right, you can end up with several queued requests.
Reproduce with the smallest setup
Section titled “Reproduce with the smallest setup”Change one thing at a time:
- Use the examples and simulator from the same SDK bundle. Don’t mix
PDComm.dllor native libraries from different bundles. - Close every earlier session and process, and start on a new port.
- With the default settings (Transport fault set to Normal), run only communication setup,
identity, andvalues. - If that works, add the one feature you want to check. Write down the first failing input, the time, and the state.
- Run the same area again with a headless simulator scenario or an example program. Keep the record of the first failure even if another setup succeeds.
- Clean up with
quit, Stop, orDisposeAsync, and check each process’s exit code.
Steps 3–5 are easier to explain with the diagnostics log turned on. See Diagnose failures and send feedback.
What to send with a support request
Section titled “What to send with a support request”Collect the following:
- The console output, error messages, and exit codes of the programs you ran.
- The trace JSON file you exported from the GUI or the MCP server.
- The diagnostics log (JSONL) and its
written,dropped, andwrite_errorscounters. - The SHA-256 hash of the native library you used.
Get the hash and the environment details with these commands:
# Linuxsha256sum "$PDCOMM_SDK/lib/libpdcomm_ffi.so"# macOSshasum -a 256 "$PDCOMM_SDK/lib/libpdcomm_ffi.dylib"dotnet --infouname -aGet-FileHash "$Sdk\lib\pdcomm_ffi.dll" -Algorithm SHA256dotnet --infoLogs and traces never contain message bodies. If they still show private details such as equipment names, lot IDs, or recipe names, mask them before you send the files, and say what you masked. Keep the originals.
Copy this form and fill it in:
SDK bundle version and native library SHA-256:Operating system and CPU architecture:Language and compiler or dotnet version:Page and step you followed:Your program's role and mode / the peer's role and mode:Address (IP:port) and HSMS session ID:MCP session_id, generation, and revision (if you used MCP):State, catalog, or profile before you started:Commands, buttons, or minimal code:Expected reply or value:Actual reply, error message, and exit code:How often it happens and when it first happened:Log and trace file names and their SHA-256:Results from another path (headless scenario, example program):What you need:Related pages
Section titled “Related pages”- Status codes and errors: status codes for C, C++, and .NET, GEM results, and HSMS event codes.
- Connections and timeouts: refused connections, port conflicts, and T3, T5, T6, T7, and T8, with real logs.
- Diagnose failures and send feedback: the
PDCOMM_LOGdiagnostics log andpdcomm_logging_configure. - Headless simulator: reproduce problems with scenarios and no display.