{"action":"created","issue":{"url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/650","repository_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c","labels_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/650/labels{/name}","comments_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/650/comments","events_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/650/events","html_url":"https://github.com/Azure/azure-iot-sdk-c/issues/650","id":363666564,"node_id":"MDU6SXNzdWUzNjM2NjY1NjQ=","number":650,"title":"Memory leak, each time my IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC is called","user":{"login":"ArmelTCHOUNKEU","id":43581272,"node_id":"MDQ6VXNlcjQzNTgxMjcy","avatar_url":"https://avatars1.githubusercontent.com/u/43581272?v=4","gravatar_id":"","url":"https://api.github.com/users/ArmelTCHOUNKEU","html_url":"https://github.com/ArmelTCHOUNKEU","followers_url":"https://api.github.com/users/ArmelTCHOUNKEU/followers","following_url":"https://api.github.com/users/ArmelTCHOUNKEU/following{/other_user}","gists_url":"https://api.github.com/users/ArmelTCHOUNKEU/gists{/gist_id}","starred_url":"https://api.github.com/users/ArmelTCHOUNKEU/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ArmelTCHOUNKEU/subscriptions","organizations_url":"https://api.github.com/users/ArmelTCHOUNKEU/orgs","repos_url":"https://api.github.com/users/ArmelTCHOUNKEU/repos","events_url":"https://api.github.com/users/ArmelTCHOUNKEU/events{/privacy}","received_events_url":"https://api.github.com/users/ArmelTCHOUNKEU/received_events","type":"User","site_admin":false},"labels":[{"id":494742749,"node_id":"MDU6TGFiZWw0OTQ3NDI3NDk=","url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/labels/investigation-required","name":"investigation-required","color":"1d76db","default":false}],"state":"open","locked":false,"assignee":{"login":"YoDaMa","id":8214060,"node_id":"MDQ6VXNlcjgyMTQwNjA=","avatar_url":"https://avatars3.githubusercontent.com/u/8214060?v=4","gravatar_id":"","url":"https://api.github.com/users/YoDaMa","html_url":"https://github.com/YoDaMa","followers_url":"https://api.github.com/users/YoDaMa/followers","following_url":"https://api.github.com/users/YoDaMa/following{/other_user}","gists_url":"https://api.github.com/users/YoDaMa/gists{/gist_id}","starred_url":"https://api.github.com/users/YoDaMa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/YoDaMa/subscriptions","organizations_url":"https://api.github.com/users/YoDaMa/orgs","repos_url":"https://api.github.com/users/YoDaMa/repos","events_url":"https://api.github.com/users/YoDaMa/events{/privacy}","received_events_url":"https://api.github.com/users/YoDaMa/received_events","type":"User","site_admin":false},"assignees":[{"login":"YoDaMa","id":8214060,"node_id":"MDQ6VXNlcjgyMTQwNjA=","avatar_url":"https://avatars3.githubusercontent.com/u/8214060?v=4","gravatar_id":"","url":"https://api.github.com/users/YoDaMa","html_url":"https://github.com/YoDaMa","followers_url":"https://api.github.com/users/YoDaMa/followers","following_url":"https://api.github.com/users/YoDaMa/following{/other_user}","gists_url":"https://api.github.com/users/YoDaMa/gists{/gist_id}","starred_url":"https://api.github.com/users/YoDaMa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/YoDaMa/subscriptions","organizations_url":"https://api.github.com/users/YoDaMa/orgs","repos_url":"https://api.github.com/users/YoDaMa/repos","events_url":"https://api.github.com/users/YoDaMa/events{/privacy}","received_events_url":"https://api.github.com/users/YoDaMa/received_events","type":"User","site_admin":false}],"milestone":null,"comments":4,"created_at":"2018-09-25T16:33:51Z","updated_at":"2018-10-05T22:46:51Z","closed_at":null,"author_association":"NONE","body":"<!--\r\nHi there! thank you for discovering and submitting an issue!\r\n\r\nPlease use your Azure subscription if you need to share any information from your Azure subscription such as connection strings, service names (IoTHub, Provisioning), etc.\r\n\r\n# Need Support?\r\n* Have a feature request for SDKs? Please post it on [User Voice](https://feedback.azure.com/forums/321918-azure-iot) to help us prioritize.\r\n* Have a technical question? Ask on [Stack Overflow](https://stackoverflow.com/questions/tagged/azure-iot-hub) with tag \"azure-iot-hub\".\r\n* Need Support? Every customer with an active Azure subscription has access to [support](https://docs.microsoft.com/en-us/azure/azure-supportability/how-to-create-azure-support-request) with guaranteed response time.  Consider submitting a ticket and get assistance from Microsoft support team\r\n* Found a bug? Please help us fix it by thoroughly documenting it and filing an issue on GitHub ([C](https://github.com/Azure/azure-iot-sdk-c), [Java](https://github.com/Azure/azure-iot-sdk-java), [.NET](https://github.com/Azure/azure-iot-sdk-csharp), [Node.js](https://github.com/Azure/azure-iot-sdk-node), [Python](https://github.com/Azure/azure-iot-sdk-python)).\r\n\r\nPlease first tell us a little bit about the environment you're running:\r\n-->\r\n\r\n\r\n- **OS and version used:** <VERSION> <!-- Windows 10, Ubuntu 15.04... --> FreeRTOS on ESP32\r\n\r\n- **SDK version used:** <VERSION> <!-- Please include the SDK version -->azure-iot-sdk\r\n\r\n\r\n# Description of the issue:\r\n<!-- Please be as detailed as possible: which feature has a problem, how often does it fail,  -->\tExactly implemented (exact same code) as described in the sample https://github.com/Azure/azure-iot-sdk-c/blob/master/iothub_client/samples/iothub_client_device_twin_and_methods_sample/iothub_client_device_twin_and_methods_sample.c\r\n\r\nEvery time the async function is called, I measure the heap remaining size which goes down.\r\n\r\nFinally I get crashed when the heap is over.\r\n\r\nThe memory is allocated within the function but not freed: my guess is that the SKD handles it by its own.\r\n\r\nPlease is my assumption above exact?\r\nIf not, who does handle it? When and Where?\r\n\r\n# Code sample exhibiting the issue:\r\n<!-- Please remove any connection string information! -->\r\n\r\nIn this function from the code link above there is an malloc without a free, and I suspect if it is because of that ?\r\n\r\nstatic int deviceMethodCallback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size, void* userContextCallback)\r\n{\r\n    (void)userContextCallback;\r\n    (void)payload;\r\n    (void)size;\r\n\r\n    int result;\r\n\r\n    if (strcmp(\"getCarVIN\", method_name) == 0)\r\n    {\r\n        const char deviceMethodResponse[] = \"{ \\\"Response\\\": \\\"1HGCM82633A004352\\\" }\";\r\n        *response_size = sizeof(deviceMethodResponse)-1;\r\n        *response = malloc(*response_size);\r\n        (void)memcpy(*response, deviceMethodResponse, *response_size);\r\n        result = 200;\r\n    }\r\n    else\r\n    {\r\n        // All other entries are ignored.\r\n        const char deviceMethodResponse[] = \"{ }\";\r\n        *response_size = sizeof(deviceMethodResponse)-1;\r\n        *response = malloc(*response_size);\r\n        (void)memcpy(*response, deviceMethodResponse, *response_size);\r\n        result = -1;\r\n    }\r\n\r\n    return result;\r\n}\r\n\r\n# Console log of the issue:\r\n<!-- Please share as much logs as posible, that will help debugging -->\r\n<!-- Don't forget to remove any connection string information! -->\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/comments/427518327","html_url":"https://github.com/Azure/azure-iot-sdk-c/issues/650#issuecomment-427518327","issue_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/650","id":427518327,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNzUxODMyNw==","user":{"login":"YoDaMa","id":8214060,"node_id":"MDQ6VXNlcjgyMTQwNjA=","avatar_url":"https://avatars3.githubusercontent.com/u/8214060?v=4","gravatar_id":"","url":"https://api.github.com/users/YoDaMa","html_url":"https://github.com/YoDaMa","followers_url":"https://api.github.com/users/YoDaMa/followers","following_url":"https://api.github.com/users/YoDaMa/following{/other_user}","gists_url":"https://api.github.com/users/YoDaMa/gists{/gist_id}","starred_url":"https://api.github.com/users/YoDaMa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/YoDaMa/subscriptions","organizations_url":"https://api.github.com/users/YoDaMa/orgs","repos_url":"https://api.github.com/users/YoDaMa/repos","events_url":"https://api.github.com/users/YoDaMa/events{/privacy}","received_events_url":"https://api.github.com/users/YoDaMa/received_events","type":"User","site_admin":false},"created_at":"2018-10-05T22:46:51Z","updated_at":"2018-10-05T22:46:51Z","author_association":"MEMBER","body":"Hi @ArmelTCHOUNKEU, for the bug in the sample, a new commit has been pushed that includes a patch for the memory leak. If you don't want to pull down the new commits, here are instructions for patching the sample code: \r\n\r\n- The memory leak is in `deviceTwinCallback`. Here is a snippet of that code (just for reference, you don't have to read through it):\r\n\r\n```\r\nstatic void deviceTwinCallback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)\r\n{\r\n    (void)update_state;\r\n    (void)size;\r\n\r\n    Car* oldCar = (Car*)userContextCallback;\r\n    Car* newCar = parseFromJson((const char*)payLoad, update_state);\r\n\r\n    if (newCar->changeOilReminder != NULL)\r\n    {\r\n        if (oldCar->changeOilReminder == NULL ||\r\n            strcmp(oldCar->changeOilReminder, newCar->changeOilReminder) != 0)\r\n        {\r\n            printf(\"Received a new changeOilReminder = %s\\n\", newCar->changeOilReminder);\r\n\r\n            if (oldCar->changeOilReminder != NULL)\r\n            {\r\n                free(oldCar->changeOilReminder);\r\n            }\r\n\r\n            oldCar->changeOilReminder = malloc(strlen(newCar->changeOilReminder) + 1);\r\n            (void)strcpy(oldCar->changeOilReminder, newCar->changeOilReminder);\r\n        }\r\n    }\r\n\r\n    if (newCar->settings.desired_maxSpeed != 0)\r\n    {\r\n        if (newCar->settings.desired_maxSpeed != oldCar->settings.desired_maxSpeed)\r\n        {\r\n            printf(\"Received a new desired_maxSpeed = %\" PRIu8 \"\\n\", newCar->settings.desired_maxSpeed);\r\n            oldCar->settings.desired_maxSpeed = newCar->settings.desired_maxSpeed;\r\n        }\r\n    }\r\n\r\n    if (newCar->settings.location.latitude != 0)\r\n    {\r\n        if (newCar->settings.location.latitude != oldCar->settings.location.latitude)\r\n        {\r\n            printf(\"Received a new latitude = %f\\n\", newCar->settings.location.latitude);\r\n            oldCar->settings.location.latitude = newCar->settings.location.latitude;\r\n        }\r\n    }\r\n\r\n    if (newCar->settings.location.longitude != 0)\r\n    {\r\n        if (newCar->settings.location.longitude != oldCar->settings.location.longitude)\r\n        {\r\n            printf(\"Received a new longitude = %f\\n\", newCar->settings.location.longitude);\r\n            oldCar->settings.location.longitude = newCar->settings.location.longitude;\r\n        }\r\n    }\r\n\r\n    free(newCar);\r\n}\r\n```\r\nIn that code, a newCar is malloc'd and freed, but it's parameter `newCar->changeOilReminder` is not. To patch the leak then, add a free:\r\n\r\n```\r\n    if (newCar->changeOilReminder != NULL)\r\n    {\r\n        if (oldCar->changeOilReminder == NULL ||\r\n            strcmp(oldCar->changeOilReminder, newCar->changeOilReminder) != 0)\r\n        {\r\n            printf(\"Received a new changeOilReminder = %s\\n\", newCar->changeOilReminder);\r\n\r\n            if (oldCar->changeOilReminder != NULL)\r\n            {\r\n                free(oldCar->changeOilReminder);\r\n            }\r\n\r\n            oldCar->changeOilReminder = malloc(strlen(newCar->changeOilReminder) + 1);\r\n            (void)strcpy(oldCar->changeOilReminder, newCar->changeOilReminder);\r\n            // ADD FREE HERE \r\n\t    free(newCar->changeOilReminder);\r\n            // ADD FREE HERE\r\n        }\r\n    }\r\n```\r\n\r\nAdding that free should patch the leak and you should be able to send direct messages through the Device Explorer and receive direct responses from the device."}}
{"actor":{"display_login":"YoDaMa"}}