-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PVStructure::getSubField() can return NULL #296
Comments
I am trying to generate an error with the existing version of the code. I'm running the ADCSimDetector which generates NDArrays without the ColorMode attribute. In fact the NDArrays have no attributes at all. I then use NDPluginPva convert these to NTNDArrays which are sent to another IOC running pvaDriver. Both IOCs seem to be running fine with no errors. So although GetColorMode() should be failing I see no errors. How do I generate errors to know when I have fixed the problem? Did you observe problems, or just notice the problem in the code? |
I also note that
My guess then is that your Structure has "attributes", but that the PVStructureArray is empty. To trigger a crash you would either have to get rid of "attributes" or change this StructureArray such that:
Really making the slightest change to the Structure definition will cause a crash.
I just noticed this. Incomplete error handling in the case of missing fields, or mis-matched types, is probably the most common gotcha of pvData. |
If you want to experiment with different structure definitions have a look at iocBoot/iocimagedemo/ in QSRV. Removing the last two records "$(N):ColorMode_" and "$(N):ColorMode" will remove the "attributes" sub-structure. https://github.com/epics-base/pva2pva/blob/master/iocBoot/iocimagedemo/image.db#L45 Similarly you can change the Field types by changing the record types. |
Isn't However, malformed attribute structures inside |
@brunoseivam I have 2 IOCs that are generating NTNDArrays. ADSimDetector is generating arrays with several attributes including ColorMode, and ADCSimDetector is generating arrays with no attributes. This is the output of pvget from ADSimDetector:
This is the output from pvget with ADCSimDetector:
So ADCSimDetector has no attributes, so there is no ColorMode attribute. But ntndArrayConverter is not generating any error. Is getColorMode() actually being called when converting NTNDArray to NDArray in pvaDriver? If so why is it not generating an error? |
If the underlying If the NTNDArray doesn't have the I think you will see an error if you purposefully generate an NTNDArray with an |
Ah, were it only so... Actually it will crash here due to an unchecked getField() call (also returns NULL). Did I mention that this is a common error? https://github.com/epics-base/normativeTypesCPP/blob/master/src/ntndarray.cpp#L352 To repeat my message. If you call a |
Also, the unchecked use of
What should be done here is something like if(!*it) continue;
PVScalarPtr field((*it)->getSubFieldT<PVUnion>("value")->get<PVScalar>());
if(!field)
continue;
colorMode = field->getAs<uint32>(); This will throw if "value" doesn't exist, or isn't a union. It will silently ignore if "value" contains a non-scalar value (array or sub-structure). It will implicitly convert if the "value" union happens to contain PVShort or PVULong. It will throw if "value" contains a PVString with a value which can't be converted to an unsigned integer by the rules of edit: Added initial test of |
FYI You should also default to using As efficient handling of array data is important to AD I will point out |
Thanks for the tips, Michael! Is there any document with recommendations like this (or a more general "how to use pvData")? If not, is one planned? |
Unfortunately no usage documentation exists yet which mentions PVScalar::getAs()/putFrom() or the void specialization of shared_vector. These are (somewhat) recent additions. It's in my mind to do this, but I don't yet have any time allocated. |
FYI.
PVStructure::getSubField()
returns shared_ptr() (aka NULL) when the requested field doesn't exist. There is another variantPVStructure::getSubFieldT()
(notice the highly obvious "T") which throws an exception instead. When chaining method calls ```getSubFieldT()`` is highly recommended.ADCore/ADApp/ntndArrayConverterSrc/ntndArrayConverter.cpp
Line 78 in acd97bd
The text was updated successfully, but these errors were encountered: