Resolving WinCC 6.0 VBScript Access Violation on PLC Tag Property Change
1. Problem Overview
WinCC 6.0 SP3 (build 6.0.3.0) Runtime crashes with an unhandled exception when VBScript (VBS) actions modify the properties (color, visibility, position) of grouped graphical objects whose trigger is bound to an external PLC tag. The same script works correctly when the trigger references an internal WinCC tag. The behavior is reproducible when two or more VBS actions are attached to the same group or when a single action manipulates multiple objects inside a group.
The runtime fault surfaces as a modal dialog Unhandled exception raised. See WinCC Diagnose Directory followed by a WinCC Runtime termination. The associated WinCC_Sys_ records Access violation with a stack that points into CCWriteSTDOSet.exe or PDMrt.exe. The fault is consistently tied to the OPC/DP channel read path combined with rapid tag polling against grouped PDL objects.
2. Affected Environment
| Component | Verified Version |
|---|---|
| WinCC Runtime | V6.0 SP3 (6.0.3.0) base install |
| Operating System | Windows XP SP2, Windows XP SP3 |
| Virtualization | VMware Workstation 5.5.1 (host any) |
| Trigger mechanism | VBS or C action with event-based tag trigger |
| Trigger tags | External (S7-MPI/DP, S7-OPC, PROFIBUS, PROFINET) |
| Object model | Group object with two or more graphical primitives |
| Runtime modes | Graphics Runtime, Tag Logging Runtime co-resident |
The fault is not present on internal tags because the internal tag manager re-uses a locked buffer; external tags traverse a channel DLL and an OPC stack that releases the calling thread before the property set completes, exposing a race condition inside the property writer of the grouped object.
3. Error Symptoms and Diagnostic Artifacts
When the trigger fires against a PLC tag, the following diagnostic artifacts are produced:
- Modal message box: Unhandled exception raised. See WinCC Diagnose Directory.
- Runtime closes without graceful deactivation; project
*.RTis left inSTOPPEDstate. - Log file
<WinCC_install>\diagnose\WinCC_Sys_<hostname>.logcontains:<date> <time> PDMrt.exe Access violation (0xC0000005) at address 0xXXXXXX reading 0xXXXXXXXX <date> <time> GfxRt.exe Runtime aborted by exception handler <date> <time> CCWriteSTDOSet.exe Read of uncommitted tag value buffer
- Dr. Watson /
drwtsn32.logrecords a stack frame insideCCWriteSTDOSet!SetObjectProperty. - Performance monitor shows OPC channel thread CPU pinned at 100% during the second preceding the crash.
4. Root Cause Analysis
Three compounding defects cause the crash:
4.1 Property-set re-entrancy on grouped objects
WinCC V6.0 SP3 base ships a property writer (CCWriteSTDOSet.dll) that iterates a group synchronously and writes each child property while holding a non-re-entrant critical section. When a second action on the same group is dispatched by the tag manager, the second thread blocks on the same section; if the OPC channel completes the tag read between the iteration and the commit, the second thread enters the section before the buffer is invalidated, dereferencing a freed pointer.
4.2 Trigger-rate mismatch for external tags
The default recommended trigger cycle of 250 ms is intended for internal tags whose value changes are CPU-local. External tags traverse the channel DLL, the OPC server, and the S7 driver; a 250 ms cycle on a slow DP- or MPI-attached PLC saturates the channel and causes read completions to overlap. Each overlapped completion is dispatched on the same GUI thread that owns the property writer, re-arming the defect in 4.1.
4.3 Missing SP3 Hotfix 2 patch
Siemens published Hotfix 2 for V6.0 SP3 to address VBS runtime stability issues, including the Access Violation when scripting against grouped objects and external tags. The patch reroutes the property writer through a marshaled call and adds a per-group guard that serializes re-entrant access. Without Hotfix 2, the conditions in 4.1 and 4.2 reproduce on virtually every installation.
5. Resolution Procedure
Apply the following three fixes in order. Each step is independently necessary; skipping step 5.1 leaves the defect reproducible.
5.1 Install WinCC V6.0 SP3 Hotfix 2
- Close WinCC Explorer and stop all WinCC services:
net stop "CCAgent" /y net stop "S7DOS" /y net stop "SyNIEtch" /y
- Locate the hotfix package referenced in the Siemens support entry ID 21480479 (Hotfix 2 for WinCC V6.0 SP3). Verify the downloaded file is signed by Siemens AG and matches the build date listed in the entry.
- Run the installer with administrative rights and follow the wizard until Setup completed successfully is displayed.
- Reboot the engineering station and the Runtime station.
- Confirm the installed version with Start → Programs → SIMATIC → WinCC → Information. The version string must read
6.0.3.0 HF2or higher.
5.2 Optimize VBS to cache tag reads
Replace every HMIRuntime.Tags(...).Read call with a single local variable assignment at the top of the trigger function. Each .Read call enters the channel DLL, allocates an OLE variant, and is released; doing this twice in a 250 ms cycle from a single trigger doubles the load on the OPC stack and amplifies the race condition.
Reference pattern (WinCC VBS, Runtime API):
Function BorderColor_Trigger(Byval Item)
Dim tag1, tag2
' Read each external tag ONCE per trigger cycle
tag1 = HMIRuntime.Tags("opc_bitprueba").Read
tag2 = HMIRuntime.Tags("opc_bitprueba1").Read
If (tag1 = 0) And (tag2 = 1) Then
BorderColor_Trigger = vbGreen
ElseIf (tag1 = 1) And (tag2 = 0) Then
BorderColor_Trigger = vbRed
Else
BorderColor_Trigger = vbYellow
End If
End Function
Best-practice constraints derived from the WinCC scripting reference:
- Declare all local variables with
Dim; implicit variables in VBS force late binding and consume additional stack frames. - Never call
.Readmore than once for the same tag inside a trigger function. - Never use
Wait,Sleep, or blocking COM calls inside a trigger function; the GUI thread will stall and the property writer critical section cannot be released. - Prefer
Select Caseover nestedIf/ElseIfwhen more than three branches are required.
5.3 Adjust trigger cycles for external tags
| Tag Class | Recommended Cycle | Minimum Cycle | Comment |
|---|---|---|---|
| Internal tag | 250 ms (or upon change) | 100 ms | Value buffer is in-process; low overhead. |
| External tag (S7-MPI/DP/PN) | 1000 ms | 500 ms | Channel round-trip and OPC marshalling dominate. |
| External tag via slow link (Modem, OPC tunnel) | 2000 ms | 1000 ms | Match the PLC update rate; faster cycles add no value. |
Set the trigger cycle in the WinCC Explorer under Graphics Designer → Properties → Events → Mouse-Click or Variable. Use the dropdown Update and select Upon change where the PLC tag update rate exceeds 1 second; otherwise use 500 ms or 1000 ms.
6. Alternate Implementation with Dynamic Dialog
If the property mapping is purely a value-to-color or value-to-visibility translation with no business logic, replace the VBS with a Dynamic Dialog. Dynamic Dialogs are compiled into C actions, not VBS, and bypass the VBS property-writer path entirely. This is the most resilient fix for simple group property changes.
- Open the object properties of the grouped element.
- Select the target property (e.g., BorderColor, Visible).
- Right-click → Dynamic Dialog.
- Define the source PLC tag as the trigger.
- Map each tag value to the desired output (e.g.,
0 = vbGreen,1 = vbRed). - Set the evaluation cycle to Upon change if the tag only toggles state, or to 1000 ms for continuous monitoring.
7. Multi-Action Strategy for Grouped Objects
When business logic prevents consolidation into a single function, attach one VBS per grouped object, not per child property. Inside that single VBS, set every required child property in sequence:
Function GroupVis_Trigger(Byval Item)
Dim st
st = HMIRuntime.Tags("PLC_DB100_DBW0").Read
If st = 1 Then
Item.SubItems("Rect_Body").Visible = True
Item.SubItems("Line_Border").Visible = True
Item.SubItems("Text_Label").Visible = True
Else
Item.SubItems("Rect_Body").Visible = False
Item.SubItems("Line_Border").Visible = False
Item.SubItems("Text_Label").Visible = False
End If
GroupVis_Trigger = 0 ' 0 = no error code returned
End Function
This pattern keeps the property writer critical section acquisition count at one per trigger cycle, eliminating the re-entrancy that drives the Access Violation.
8. Error Handling Inside VBS Triggers
The VBS Err object is reset to zero on every trigger entry. Use On Error Resume Next combined with an explicit Err.Clear at the top of the function to suppress spurious channel errors that would otherwise propagate to the Runtime:
Function SafeGroupTrigger(Byval Item)
On Error Resume Next
Err.Clear
Dim v
v = HMIRuntime.Tags("PLC_DB100_DBW0").Read
If Err.Number <> 0 Then
' Channel temporarily unavailable - keep last state
SafeGroupTrigger = 0
Exit Function
End If
Item.SubItems("Rect_Body").BorderColor = vbRed
SafeGroupTrigger = 0
End Function
The semantics of Err.Number, Err.Description, Err.Source, and the Raise method are documented in the Microsoft Learn VBScript reference for the Err object; always consult it before implementing production-grade error handling.
9. Object-Property Enumeration
When porting scripts between PDL files or migrating to WinCC TIA Portal RT Professional, the property names accepted by HMIRuntime.Tags and the screen object model differ. Use the WinCC scripting reference to enumerate valid properties on grouped objects:
- Open Graphics Designer → Tools → Cross Reference to list every property used by the project.
- Compare against the TIA Portal RT Professional example of writing object properties for TIA V20 compatibility.
- Replace deprecated property names (e.g.,
BorderColor→BorderBackColor) before recompiling.
10. Verification Checklist
Execute the following tests on the patched and optimized Runtime. Each item must pass before the fix is considered complete.
- Open the PDL containing the grouped objects and start Graphics Runtime.
- Confirm WinCC version is
6.0.3.0 HF2via Start → SIMATIC → WinCC → Information. - Force the PLC tag through Tag Logging Simulation or directly from the PLC; cycle through every value mapping at least ten times.
- Verify the property (color, visibility) updates on every cycle with no exception dialog.
- Inspect
diagnose\WinCC_Sys_<host>.logfor new entries;Access violationmust be absent. - Measure CPU on the OPC channel thread during sustained triggering; it should remain below 30% on a 1 s cycle.
- Repeat the test with the WinCC service
CCPDISstopped and restarted to validate cold-start recovery. - Export the Runtime project to a clean VM and confirm the patch persists; VMware snapshots taken before Hotfix 2 must be invalidated.
11. Fallback Procedure When Hotfix 2 Is Unavailable
If the engineering environment cannot receive Hotfix 2 (offline air-gapped site, locked-down OT network), apply the following mitigations in order of priority:
- Convert every grouping of more than one child into a flat structure (ungroup) so each child carries its own action. This removes the re-entrancy path entirely.
- Replace VBS with Dynamic Dialog for all color/visibility mappings.
- Set all external tag triggers to Upon change and add a debounce PLC block to guarantee at least 500 ms between changes.
- Disable Tag Logging Runtime co-residency if it is not actively used; the logging thread competes for the same critical section.
- Schedule Hotfix 2 deployment at the next maintenance window.
12. Troubleshooting Matrix
| Symptom | Likely Cause | Remediation |
|---|---|---|
| Crash on first PLC tag change | Hotfix 2 not installed | Install Hotfix 2; confirm build string |
| Crash after several minutes of operation | Trigger cycle too short (250 ms) for external tags | Increase cycle to 1000 ms or Upon change |
| Crash only when two actions are attached to one group | Re-entrant property writer | Consolidate into one VBS per group |
| No crash with internal tags but crash with PLC tags | Channel race condition | Cache .Read in local variables |
| Crash disappears in development but returns on Runtime PC | Different patch level on Runtime PC | Apply Hotfix 2 to Runtime PC, not only development PC |
| Crash after VMware snapshot revert | Snapshot predates Hotfix 2 | Reinstall Hotfix 2; update snapshot |
Crash with Access violation in CCWriteSTDOSet
|
Group property writer | Ungroup children or use Dynamic Dialog |
Why does my WinCC 6.0 VBS crash only on PLC tags and not on internal tags?
Internal tags read from an in-process memory buffer that does not block the GUI thread. PLC tags traverse the OPC channel DLL and complete asynchronously; rapid 250 ms triggers against grouped objects expose a re-entrancy defect in CCWriteSTDOSet.dll that is fixed by SP3 Hotfix 2.
Is WinCC 6.0 SP3 Hotfix 2 mandatory for this fault?
Yes. Siemens support entry ID 21480479 documents Hotfix 2 as the corrective patch for VBS runtime Access Violations against external tags and grouped objects. Without it the conditions reproduce on every clean installation.
What trigger cycle should I use for external tags?
Use 1000 ms for S7 PLC tags and 2000 ms for slow links (modem, OPC tunnel). Never use 250 ms for external tags; the channel round-trip cannot complete in that interval and overlapping completions trigger the crash.
Can I use Dynamic Dialog instead of VBS for grouped object properties?
Yes. Dynamic Dialogs are compiled to C actions, bypass the VBS property writer, and are the most stable option for simple value-to-property mappings such as color or visibility on grouped objects.
Why does the fix work in development but fail on the Runtime station?
Hotfix 2 must be installed on every Runtime station. VMware snapshots taken before the hotfix do not inherit the patch; restore from a snapshot taken after Hotfix 2 deployment or reinstall the hotfix on every cloned image.