Hi!
I am using a custom "vprintf_like_t" function with "esp_log_set_vprintf" to log to SPIFFS, similar to this:
https://github.com/pantaluna/esp32-mjd- ... main.c#L40
I am however seeing a behaviour consistent with data races as I am logging from several tasks, and I was wondering whether the "vprintf_like_t" function needed to be reentrant.
Thank you.
vprintf_like_t reentrancy
Re: vprintf_like_t reentrancy
This is correct — the assumptions are the same as for vprintf function. In IDF, vprintf is reentrant because the I/O streams have locks, so only one task can vprintf to a given stream at any point in time. Also keep in mind the situation when your custom vprintf implementation causes esp_log_write to be called. For example, this may happen if SPIFFS driver emits some warning or error message. So you also need to consider how to handle recursive entry into your custom vprintf function in a given thread.
Re: vprintf_like_t reentrancy
Thank you.
May I suggest adding something in the documentation regarding this?
The example I linked above is not reentrant, and it may wrongly suggest there is some write serialisation happening somewhere before this.
May I suggest adding something in the documentation regarding this?
The example I linked above is not reentrant, and it may wrongly suggest there is some write serialisation happening somewhere before this.
-
- Posts: 40
- Joined: Mon Mar 18, 2019 12:34 pm
Re: vprintf_like_t reentrancy
I have also got in a mess with this before. I found a simple solution was to do nothing in the vprintf_like_function except print the log and put the formatted string into a queue and do the meat of the work in another task:
You then end up with less problems to do with recursion and system processes running out of stack because of your my_vprintf, and an added benefit is you can store logs before you've initialised network/flash or whatever you're writing logs to.
I've also seen a my_vprintf function somewhere with a kind of TAG blacklist to make sure it's not inside my_vprintf itself or some system functions.
Disclaimer: I don't know what I'm doing.
Code: Select all
// all a bit simplified but you get the idea:
int my_vprintf(const char *format, va_list args) {
char *log_buffer;
size_t len = vasprintf(&log_buffer, format, args);
fputs(log_buffer, stdout);
xQueueSend(mqtt_queue, &log_buffer, 0)
return len;
}
I've also seen a my_vprintf function somewhere with a kind of TAG blacklist to make sure it's not inside my_vprintf itself or some system functions.
Disclaimer: I don't know what I'm doing.
Who is online
Users browsing this forum: Corand and 125 guests