-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Sketch halts when using std::string and map #8575
New issue
Have a question about this project? No Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “No 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? No Sign in to your account
Comments
Does it work after adding |
Yes it works! I didn't hear about this function! |
I see that Is it related to the linked issue? May you tell me which is the cause of this issue? |
cc @mhightower83 may have a better explanation it is a pretty old api, not something new to the 3.x.x release. only fact I am sure of atm, we grab |
Yes, I was wrong, there where few modifications since v3.0.2 around this function but it is pretty old, sorry. However, this piece of code is part of a library, I don't like to oblige the user to add this function to their
I know, but it works fine enough, but if it leads to this behavior I will change for the better. |
Adding it to setup() simply references it for the linker, which is enough to trigger the no-extra4k mode. Your library might as well do that somewhere in it's code, setup() is not requirement for this workaround. |
Just consider that you execute a lot of useless initialization code doing it that way. Be it a desktop app, perhaps that would 've been fine :) e.g. compare building this unordered_map example with a local Keeping the existing strings + u16, at least one way is to do this #include <string_view>
#include <array>
using Note = std::pair<std::string_view, unsigned short>;
static constexpr std::array<Note, 92> noteMapping {{
...
}}; Just 92 entries with a linear search instead of hashing should be a reasonable trade-off? |
The origin of Arduino/cores/esp8266/core_esp8266_main.cpp Lines 321 to 356 in 8f71d2c
It is not apparent how reducing the heap and increasing the system stack would help this problem. WPS and WiFi Enterprise are the only features I know of, so far, that need Edit: To be clear, I do see the problem occurring. |
I have not tried anything originally, just a guess about the nature of the used structure and how much memory it grabs from the get-go. Perhaps it is nothing, and totally unrelated to the SYS stack grab. The question is mainly, what happens on initialization? However, using a separate const-array and passing begin(), end() to map ctor still works just fine. |
Thanks both for the detailed answers and suggestions. @mcspr about string_view, I would preserve the compatibility with esp8266 <v3.0.0, which use an old version of gcc and it to not support c++17, so no support to string_view. I will use std::array, and maybe, arduino String instead of std::string. Are there any performance advantages between using Arduino String vs std::string? |
@fabianoriccardi probably not. Same problem as before, though. It allocates some structure, somewhere, and it there for the duration of the program copied from char data already loaded in RAM. Simple const char* might suffice. btw even gcc4.8.2 (from our previous version 2.7.4) will still support a simple wrapper around string literal or, using the same approach as in the linked issue with a template based on size. pretty common as well |
just curious, quick n' dirty trial... the threshold is between "B7" and "C8" (binary-search by hand), and including "C8" goes WDT timeout. |
My current understanding of stacks sys and cont and neighborsETS system data RAM starts at The Boot ROM functions that support WPS and To use WPS, the user stack needs to be moved out of this 8K space, allowing the system stack to move up closer to When the system stack grows down below When WPS is used without Using the 8K system stack model to take stack painting and check measurements without crashingAssuming a 4K system stack, it looks like when Edited: add clarification |
interesting information... it feels initializations via global ctors imply potentially dangerous. |
Or, if not that, could we implement something similar to stack protection check from gcc applied to global ctors function? At least for error reporting in more apparent manner than just triggering hwdt. |
I think it would be super-useful for any other unlucky guy hitting this sneaky issue!
Thanks for the suggestion, I tested it and it works perfectly on older and newer versions. I will go for it! |
seems to resolve the problem. |
I think there are a few bumps. At It is a little strange. When Unfortunately, nothing will print. All the GPIO pins were reset during One workaround would be to add a replacement extern "C" void resetPins() {
for (int pin = 0; pin <= 16; ++pin) {
if (1 == pin) {
continue;
}
if (!isFlashInterfacePin(pin))
pinMode(pin, INPUT);
}
} to the sketch to keep the TX pin alive. Note, that the UART speed will default to 115200bps. As long as the overflow doesn't exceed 8K, a configuration could be defined to detect that initializing global ctors overflowed the stack. Edited to supply an alternative to get printf working and apply suggested changes (edited again to correct void init_done() {
system_set_os_print(1);
gdb_init();
std::set_terminate(__unhandled_exception_cpp);
cont_run(g_pcont, &do_global_ctors);
if (cont_check(g_pcont) != 0) {
pinMode(1, SPECIAL);
panic();
}
esp_schedule();
ESP.setDramHeap();
} I am not sure about the adverse side effects either. It is not clear to me how to create a proper solution. I assume it is inappropriate Arduino behavior to force serial on when that is not part of the sketch. Pin 1 could be wired up for some other function. |
Basic Infos
Platform
Description
I was migrating a project to esp8266-core 3.0.x when I started to hit weird execution issues (i.e. the execution suddenly halts until the watchdog triggers to restart the esp8266).
After very frustrating moments, I isolated the issue to the following MCVE, which basically it doesn't print the message
ciao
on the serial port. The same behavior can be observed on all the versions 3.0.x and on the latest git version (8f71d2c).After looking at possible related issues, I found #8314, but I don't know if they have a solution for that issue...
This code works with v2.7.4 and previous versions.
If you reduce the size of the hashmap by removing, for example, 15 pairs, the Serial.print() works.
The text was updated successfully, but these errors were encountered: