-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Strange std::begin(x)
and std::end(x)
with c-strings
#8314
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
Comments
Just as a test, I tried it on C++ shell, which does give the expected results. Is this run from a completely clean build? Edit: |
Could not reproduce with 10.2 & 11.1 x86_64. Try on current xtensa-toolchain gcc locally and run / |
Fixes esp8266#8314 and other hard-to-track bugs. GCC 10.3 had an issue with addressing constant literals which would result in crazy offsets being used and random crashes in production. Update with an upstream GCC 11 bugfix.
Small update based on the gitter discussion and a compressed example. Using and not using For the function body such as this 35 void test() {
36 addresses(EMPTY_STRING);
0x40201048 <+0>: l32r a3, 0x4020103c
0x4020104b <+3>: l32r a2, 0x40201040
0x4020104e <+6>: addi a1, a1, -16
0x40201051 <+9>: s32i a0, a1, 12
0x40201054 <+12>: call0 0x40201020 <addresses(char const*, char const*)>
37 addresses(COMMA_STRING);
0x40201057 <+15>: l32r a3, 0x40201044
0x4020105a <+18>: l32r a2, 0x4020103c
0x4020105d <+21>: call0 0x40201020 <addresses(char const*, char const*)>
0x40201060 <+24>: l32i a0, a1, 12
0x40201063 <+27>: addi a1, a1, 16
0x40201066 <+30>: ret.n The l32r address loads order & values do not change, string addresses inside of them do
(and the 3ffe86* seems to be located in core_esp8266_phy.cpp.o for some reason) This is by default, without the switch
(strings are other way around) |
A step before linking, assembly has slight differences. Without the flag, strings have diff --git a/a-defaults.s b/a-fno-constants-merge.s
index 8ada173..c8fb2c2 100644
--- a/a-defaults.s
+++ b/a-fno-constants-merge.s
@@ -1,6 +1,6 @@
.file "a.cpp"
.text
- .section .rodata._Z9addressesPKcS0_.str1.1,"aMS",@progbits,1
+ .section .rodata
.LC0:
.string "%p:%p -> (%u)\n"
.section .text._Z9addressesPKcS0_,"ax",@progbits
@@ -21,7 +21,7 @@ _Z9addressesPKcS0_:
addi sp, sp, 16
ret.n
.size _Z9addressesPKcS0_, .-_Z9addressesPKcS0_
- .section .rodata._Z4testv.str1.1,"aMS",@progbits,1
+ .section .rodata
.LC2:
.string ""
.LC5:
@@ -48,7 +48,7 @@ _Z4testv:
addi sp, sp, 16
ret.n
.size _Z4testv, .-_Z4testv
- .section .rodata.setup.str1.1,"aMS",@progbits,1
+ .section .rodata
.LC9:
.string "\n\n\n"
.section .text.setup,"ax",@progbits |
Another test, but now with some custom section that does not start with 34 #define MERGE_SECTION(NAME) __attribute__((section( "\"" NAME "\", \"aSM\", @progbits, 1 #")))
35 void test() {
36 static const char EMPTY_STRING[] MERGE_SECTION(".mystrings") = "";
37 addresses(EMPTY_STRING);
0x40201048 <+0>: l32r a3, 0x4020103c
0x4020104b <+3>: l32r a2, 0x40201040
0x4020104e <+6>: addi a1, a1, -16
0x40201051 <+9>: s32i a0, a1, 12
0x40201054 <+12>: call0 0x40201020 <addresses(char const*, char const*)>
38 static const char COMMA_STRING[] MERGE_SECTION(".mystrings") = ",";
39 addresses(COMMA_STRING);
0x40201057 <+15>: l32r a3, 0x40201040
0x4020105a <+18>: l32r a2, 0x40201044
0x4020105d <+21>: call0 0x40201020 <addresses(char const*, char const*)>
0x40201060 <+24>: l32i a0, a1, 12
0x40201063 <+27>: addi a1, a1, 16
0x40201066 <+30>: ret.n
And it does match the expected layout.
edit: probably was to hasty to blame static const char COMMA_STRING[] MERGE_SECTION(".rodata.bleh") = ",";
static const char EMPTY_STRING[] MERGE_SECTION(".rodata.bleh") = "";
When
|
(Unsurprisingly?), can also reproduce on the current arduino-esp32 2.0.1, just a matter of making strings appear in a certain order. But, can't reproduce just with the xtensa toolchain or godbolt to minimize this even more :/ This is Dump of assembler code for function test():
testme.ino:
11 void test() {
0x400d0f40 <+0>: entry a1, 32
12 addresses("");
0x400d0f43 <+3>: l32r a11, 0x400d0024 <_stext+4>
0x400d0f46 <+6>: l32r a10, 0x400d0028 <_stext+8>
0x400d0f49 <+9>: call8 0x400d0f2c <addresses(char const*, char const*)>
13 addresses(",");
0x400d0f4c <+12>: l32r a11, 0x400d002c <_stext+12>
0x400d0f4f <+15>: l32r a10, 0x400d0024 <_stext+4>
0x400d0f52 <+18>: call8 0x400d0f2c <addresses(char const*, char const*)>
0x400d0f55 <+21>: retw.n
End of assembler dump.
0x400d0024 <_stext+4>: 0x3f40264d
0x400d0028 <_stext+8>: 0x3f40264c
0x400d002c <_stext+12>: 0x3f400131
|
Basic Infos
Platform
Settings in IDE
Defaults
Problem Description
Using
std::begin
andstd::end
or the equivalent&buf[0]
and&buf[Size]
, sometimes the resulting string pointer happens to be at a different location than expected. Usingaddresses(std::begin(...), std::end(...));
outside of the template produces the same results. Referring to&buf[Size-1]
aka'\0'
does not result in the incorrect pointers though.Originally noted in the earlephilhower/newlib-xtensa#19 (comment), but it might be something different than string suffix merging / anything related to the toolchain or libc? (and not to continue an already long issue thread. plus, I hope I have not broken toolchain installation somehow)
MCVE Sketch
Debug Messages
Which is not the expected result. Inspecting the binary, "," is actually at the 0x3ffe87db as one would expect from the
end
(one past the last element of array of 2 elems)The text was updated successfully, but these errors were encountered: