-2

I am using Ardunio/ESP32 and I am very new to FreeRTOS. I am trying to convert an int value to std::string, since I don't have to_string, so I used sprintf to do so.

I noticed that when I call sprintf in the task function as follows ESP32 crashes and I can't find the reason.

bool PushMessageToSerial(const std::string &source, const std::string &message, log_t log)

void SensorActions(void *parameters)
{
    PushMessageToSerial("Setup", "Sensors Monitor task is initialized", LOG_INFO);

    while (1)
    {
        while (xQueueReceive(queue_sensors, (void *)&action, 10) == pdTRUE)
        {
            switch (action)
            {
            case actions_t::ACTION_SENSOR_VERSION:
            {
                uint8_t version[4] = {0};
                sensor.GetVersions(version);

                uint8_t length = sprintf(NULL, 0, "%d.%d.%d.%d", version[0], version[1], version[2], version[3]);
                assert(length >= 0);
                char *buf = new char[length + 1];
                sprintf(buf, length + 1, "%d.%d.%d.%d", version[0], version[1], version[2], version[3]);
                std::string text(buf);
                free(buf);
                PushMessageToSerial("Sensors", text, LOG_INFO);
            }
            break;

            default:
                break;
            }
        }
        vTaskSuspend(NULL); // Auto suspend the task to not blocking the other lower priority tasks
    }
}

can you please give me a hint to understand what is wrong?

Reza
  • 43
  • 7
  • The parameters to `sprintf()` are wrong, `sprintf()` does not have a buffer size parameter. This code should not even compile. Use `sprintf_s()` or `snprintf()` if you want to specify the buffer's size. – Remy Lebeau May 09 '21 at 20:22
  • Thanks Remy for your reply. But have the same issue with `snprintf()` as well. – Reza May 09 '21 at 21:21
  • Why vTaskSuspend at all and why a timed xQueueReceive ? What’s the benefit of the std::string copy of the message ? – HS2 May 10 '21 at 06:04
  • Well, this task has high priority and suspends itself when there is nothing in the queue so, doesn't bother the lower-prio tasks. I don't quite follow your question on timed xQueueReceive! timed part of Queue part? the same with your last question! – Reza May 11 '21 at 19:07

1 Answers1

1

This line is problematic:

uint8_t length = sprintf(NULL, 0, "%d.%d.%d.%d", version[0], version[1], version[2], version[3]);

You can't pass in NULL as the first argument to sprintf(); rather you have to pass in a pointer to a buffer that is big enough to hold the text you want sprintf() to write. As shown above, the code is telling sprintf() to write its output via a NULL pointer, which causes the segmentation fault. Also the second argument (0) is erroneous and should be removed; the second argument to sprintf() should be the format-string ("%d.%d.%d.%d").

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234