Skip to content
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

iot_data_map_get: Assertion `map && key && (map->type == IOT_DATA_MAP)' failed #504

Closed
hechuanju opened this issue Dec 27, 2023 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@hechuanju
Copy link

hechuanju commented Dec 27, 2023

🐞 Bug Report

A segment fault occurs in the associated String data of devicecommands obtained through the Device Service API.

Affected Services [REQUIRED]

Device Service

Is this a regression?

Only available in version 3.1.0.

Description and Minimal Reproduction [REQUIRED]

When attempting to develop a device service based on version 3.1.0 of the device-sdk-c (csdk), I encountered the following issue. The reproduction steps are as follows:

  1. Manually compile the iotech-c-utils (version 1.5.0) dependencies of the csdk from source and use the debug version of the final compiled artifacts.
  2. Associate a command in the deviceCommands section of the device profile, linking it to a String-type device resource.
  3. Run the EdgeX 3.1.0 core services and then start the device service. When attempting to retrieve the aforementioned command through the device service API, you may encounter an assertion error occurring in the iot_data_map_get function:
    assertion failed: map && key && (map->type == IOT_DATA_MAP).

Note: You must use your own compiled debug version of the iot library to reproduce this bug, the release version is normal

🔥 Exception or Error

Compile and install the debug version of iotech-c-utils manually.


1. scripts/linux.sh -root ~/work/iotech-c-utils -barch x86_64
2. cd x86_64/debug && sudo make install

device profile:


{
  "name": "TemplateSensor",
  "manufacturer": "IoTechSystems",
  "model": "IoT0",
  "description": "Template Sensor",
  "labels": ["sensor"],
  "apiVersion": "v3",

  "deviceResources":
  [
    {
      "name": "SensorOne",
      "description": "A Sensor generating unsigned integer values",
      "attributes": { "SensorID": "Sen1" , "SensorType": "UInt64" },
      "properties": { "valueType": "Uint64", "readWrite": "R", "units": "things" }
    },
    {
      "name": "manufacturerId",
      "description": "manufacturerId",
      "attributes": { "parameter": "mId"},
      "properties": { "valueType": "String", "readWrite": "RW", "units": "text" }
    }
  ],
  "deviceCommands":
  [
    {
      "name": "MId",
      "readWrite": "R",
      "resourceOperations":
      [
        { "deviceResource": "manufacturerId"}
      ]
    }
  ]
}

Notice: The "manufacturerId" is a resource of type String.

When all services are running, get the manufacturerId resource associated with the MId command from devicecommand


curl 0:59999/api/v3/device/name/Device1/MId

result:


level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="iot_threadpool_alloc (threads: 8 max_jobs: 0 default_priority: -1 affinity: -1)"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="iot_scheduler_alloc (priority: -1 affinity: -1)"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Setting LogLevel to DEBUG"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Starting device-template device service, version 1.0"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="EdgeX device SDK for C, version 3.0.2"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service configuration follows:"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/DataTransform=true"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/DevicesDir="./res/devices""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/Discovery/Enabled=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/Discovery/Interval=0"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/EventQLength=0"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/Labels=["Template"]"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/MaxCmdOps=128"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/ProfilesDir="./res/profiles""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Device/UpdateLastConnected=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Driver/TestParam1="Hello""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MaxEventSize=0"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/AuthMode="usernamepassword""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/BaseTopicPrefix="edgex""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Disabled=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Host="localhost""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/CertFile="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/ClientId="device-template""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/KeepAlive=60"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/KeyFile="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/Qos=0"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/Retained=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Optional/SkipCertVerify=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Port=6379"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Protocol="redis""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/SecretName="redisdb""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="MessageBus/Type="redis""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/Authentication/AuthType="X-Vault-Token""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/DisableScrubSecretsFile=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/Host="localhost""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/Path="device-template/""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/Port=8200"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/Protocol="http""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/RootCaCertPath="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/SecretsFile="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/ServerName="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/TokenFile="/tmp/edgex/secrets/device-template/secrets-token.json""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="SecretStore/Type="vault""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/CORSAllowCredentials=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/CORSAllowedHeaders="Authorization, Accept, Accept-Language, Content-Language, Content-Type, X-Correlation-ID""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/CORSAllowedMethods="GET, POST, PUT, PATCH, DELETE""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/CORSAllowedOrigin="https://localhost""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/CORSExposeHeaders="Cache-Control, Content-Language, Content-Length, Content-Type, Expires, Last-Modified, Pragma, X-Correlation-ID""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/CORSMaxAge=3600"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/CORSConfiguration/EnableCORS=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/HealthCheckInterval="10s""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/Host="localhost""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/MaxRequestSize=0"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/Port=59999"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/RequestTimeout="5s""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/ServerBindAddr="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Service/StartupMsg="Template device started""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Driver/TestParam2="World""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Driver/TestParam3="Goodbye""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/InsecureSecrets/DB/SecretData/password="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/InsecureSecrets/DB/SecretData/username="""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/InsecureSecrets/DB/SecretName="redisdb""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/LogLevel="DEBUG""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/Interval="30s""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/Metrics/EventsSent=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/Metrics/ReadCommandsExecuted=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/Metrics/ReadingsSent=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/Metrics/SecuritySecretsRequested=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/Metrics/SecuritySecretsStored=false"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Writable/Telemetry/PublishTopicPrefix="edgex/telemetry""
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="iot_threadpool_alloc (threads: 1 max_jobs: 0 default_priority: -1 affinity: -1)"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Thread iot-1-0 #0 starting"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Message Bus is set to Redis streams at localhost:6379"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Found core-metadata service at localhost:59881"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Processing Device Profiles from ./res/profiles"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Checking existence of DeviceProfile TemplateSensor"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="DeviceProfile TemplateSensor already exists: skipped"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Starting HTTP server on interface localhost, port 59999"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Resolved interface is 127.0.0.1"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Processing Devices from ./res/devices"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Device Device1 already exists: skipped"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Template Init. Driver Config follows:"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="    TestParam1 = Hello"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="    Writable/TestParam2 = World"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="    Writable/TestParam3 = Goodbye"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Template Init done"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Template device started"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Service started in: 15ms"
level=INFO ts=2023-12-27T07:32:56Z app=device-template msg="Listening on port: 59999"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template msg="Publishing metrics"
level=INFO ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg="AutoEvent: Device1/SensorOne"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg="GET on device:"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg=" [Other] protocol:"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg="    Address = someSensorEndpoint"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg="  Requested reading 0:"
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg="    SensorID = "Sen1""
level=DEBUG ts=2023-12-27T07:32:56Z app=device-template correlation-id=67503cf2-96b1-4c12-9b2c-aa858fc0bf67 msg="    SensorType = "UInt64""
level=DEBUG ts=2023-12-27T07:33:01Z app=device-template correlation-id=e8063ebe-cee5-4ca0-b34c-4da89cc854d0 msg="Incoming GET command for device name Device1"
level=DEBUG ts=2023-12-27T07:33:01Z app=device-template correlation-id=e8063ebe-cee5-4ca0-b34c-4da89cc854d0 msg="GET on device:"
level=DEBUG ts=2023-12-27T07:33:01Z app=device-template correlation-id=e8063ebe-cee5-4ca0-b34c-4da89cc854d0 msg=" [Other] protocol:"
level=DEBUG ts=2023-12-27T07:33:01Z app=device-template correlation-id=e8063ebe-cee5-4ca0-b34c-4da89cc854d0 msg="    Address = someSensorEndpoint"
level=DEBUG ts=2023-12-27T07:33:01Z app=device-template correlation-id=e8063ebe-cee5-4ca0-b34c-4da89cc854d0 msg="  Requested reading 0:"
level=DEBUG ts=2023-12-27T07:33:01Z app=device-template correlation-id=e8063ebe-cee5-4ca0-b34c-4da89cc854d0 msg="    parameter = "mId""
device-example: /home/chuanju/learning/iotech-c-utils/src/c/data.c:1894: iot_data_map_get: Assertion `map && key && (map->type == IOT_DATA_MAP)' failed.
Aborted

This example is modified from device-sdk-c example/template.c.

🌍 Your Environment

Deployment Environment:
Ubuntu:22.04
EdgeX Version [REQUIRED]:

  1. Edgex core and device-sdk-c: v3.1.0
  2. iotech-c-utils: v1.5.0
    Anything else relevant?
@hechuanju hechuanju added the bug Something isn't working label Dec 27, 2023
@hechuanju
Copy link
Author

hechuanju commented Jan 5, 2024

I finally figured out this problem.

Reason:
image
When you first start the device service, the csdk will upload the profile to the metadata service, and then retrieve the configuration of the profile through the metadata's API. However, even if you haven't added the mappings field locally, it still returns a null mappings object. The current code does not handle this special case, leading to the issue.

Solution:

diff --git a/src/c/transform.c b/src/c/transform.c
index a10bebf..4093fb6 100644
--- a/src/c/transform.c
+++ b/src/c/transform.c
@@ -147,7 +147,7 @@ void edgex_transform_outgoing (devsdk_commandresult *cres, edgex_propertyvalue *
     break;
     case IOT_DATA_STRING:
     {
-      if (mappings)
+      if (mappings && (iot_data_type (mappings) == IOT_DATA_MAP))
       {
         const iot_data_t *remap = iot_data_map_get (mappings, cres->value);
         if (remap)

or, add an empty mappings:

"deviceCommands":
  [
    {
      "name": "MId",
      "readWrite": "R",
      "resourceOperations":
      [
        { "deviceResource": "manufacturerId",
          "mappings": {} // add an empty mappings
        }
      ]
    }
  ]

@eaton-coreymutter
Copy link
Contributor

We saw this a while back at Eaton and did your first-case solution - wrapped all the calls to iot_data_map_iter() with a null and type check. I will post a PR with those changes. @lindseysimple IOTech may want to consider removing those assertions, in the meantime we can avoid them.

eaton-coreymutter added a commit to eaton-coreymutter/device-sdk-c that referenced this issue Jan 29, 2024
Sometimes objects intended to be maps are null, or initialized but
type IOT_DATA_NULL, causing map get/iterate functions to assert.
Bypass these cases, treating it as an empty map.

Signed-off-by: Corey Mutter <[email protected]>
@eaton-coreymutter
Copy link
Contributor

Posted IOTechSystems/iotech-c-utils#331 as an alternative fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants