Skip to content
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

Assembler errors while compiling on esphome with framework version >=3.0.0 #8672

Closed
6 tasks done
Chupaka opened this issue Sep 11, 2022 · 13 comments
Closed
6 tasks done

Comments

@Chupaka
Copy link

Chupaka commented Sep 11, 2022

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: d1_mini
  • Core Version: starting from 3.0.0
  • Development Env: esphome
  • Operating System: MacOS, Debian

Problem Description

Hello. I came from ESPHome world, going deeper and deeper (ESPHome -> PlatformIO -> ESP8266 core for Arduino) trying to debug this problem.

This initially was published as ESPHome issue esphome/issues#3311

When the code below is being built with framework version 3.0.0 or higher, the process fails with errors like this:

/tmp/ccHYx8E4.s: Assembler messages:
/tmp/ccHYx8E4.s: Warning: end of file in string; '"' inserted
/tmp/ccHYx8E4.s:31: Error: bad register name:   a2
/tmp/ccHYx8E4.s:31: Error: junk at end of line, first unrecognized character valued 0x9
/tmp/ccHYx8E4.s:32: Error: bad register name:   sp
/tmp/ccHYx8E4.s:32: Error: junk at end of line, first unrecognized character valued 0x9
/tmp/ccHYx8E4.s:33: Error: bad register name:   a2
/tmp/ccHYx8E4.s:33: Error: junk at end of line, first unrecognized character valued 0x9
/tmp/ccHYx8E4.s:34: Error: bad register name:   a0
/tmp/ccHYx8E4.s:34: Error: junk at end of line, first unrecognized character valued 0x9
/tmp/ccHYx8E4.s:35: Error: bad register name:   a3
<<< many lines of similar errors here >>>

If I switch back to version 2.7.4 (well, looks like for some reason PlatformIO uses 2.6.3 in that case), everything is fine, it builds successfully and works as expected.

MCVE Sketch

Minimal code for reproduction in ESPHome is https://gist.github.com/Chupaka/6679f559a29aa513bc4e8120762b2cdc (2 small files)

To get back to framework 2.7.4, edit t.yaml:

esp8266:
  board: d1_mini
  framework:
    version: 2.7.4
@mcspr
Copy link
Collaborator

mcspr commented Sep 11, 2022

What happens in command line? i.e. esphome equivalent of pio run --environment $env --jobs 1 --verbose
Where does t.h go in the resulting source file?
Are there any intermediate files, generated by esphome, which could be compiled manually to reproduce the issue?
Does removing IRAM_ATTR help?

@Chupaka
Copy link
Author

Chupaka commented Sep 11, 2022

ESPHome successfully generates this build dir:

.
├── platformio.ini
├── post_build.py
└── src
    ├── esphome
    │   ├── components
    │   │   ├── custom_component
    │   │   │   └── custom_component.h
    │   │   ├── esp8266
    │   │   │   ├── core.cpp
    │   │   │   ├── core.h
    │   │   │   ├── gpio.cpp
    │   │   │   ├── gpio.h
    │   │   │   ├── preferences.cpp
    │   │   │   └── preferences.h
    │   │   └── preferences
    │   │       └── syncer.h
    │   └── core
    │       ├── application.cpp
    │       ├── application.h
    │       ├── automation.h
    │       ├── base_automation.h
    │       ├── color.cpp
    │       ├── color.h
    │       ├── component.cpp
    │       ├── component.h
    │       ├── component_iterator.cpp
    │       ├── component_iterator.h
    │       ├── controller.cpp
    │       ├── controller.h
    │       ├── datatypes.h
    │       ├── defines.h
    │       ├── entity_base.cpp
    │       ├── entity_base.h
    │       ├── gpio.h
    │       ├── hal.h
    │       ├── helpers.cpp
    │       ├── helpers.h
    │       ├── log.cpp
    │       ├── log.h
    │       ├── macros.h
    │       ├── optional.h
    │       ├── preferences.h
    │       ├── scheduler.cpp
    │       ├── scheduler.h
    │       ├── util.cpp
    │       ├── util.h
    │       └── version.h
    ├── esphome.h
    ├── main.cpp
    └── t.h

Here are the actual files: thermik.tar.gz

If I run platformio run -j1 -v in that dir - I get the error near here:

xtensa-lx106-elf-g++ -o .pio/build/thermik/src/main.cpp.o -c -fno-rtti -std=gnu++17 -fno-exceptions -Wno-nonnull-compare -Wno-sign-compare -Wno-unused-but-set-variable -Wno-unused-variable -fno-exceptions -Os -mlongcalls -mtext-section-literals -falign-functions=4 -U__STRICT_ANSI__ -D_GNU_SOURCE -ffunction-sections -fdata-sections -Wall -Werror=return-type -free -fipa-pta -DPLATFORMIO=60002 -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_WEMOS_D1MINI -DNEW_OOM_ABORT -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH -DUSE_ARDUINO -DUSE_ESP8266 -DUSE_ESP8266_FRAMEWORK_ARDUINO -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DARDUINO=10805 -DARDUINO_BOARD=\"PLATFORMIO_D1_MINI\" -DFLASHMODE_DOUT -DLWIP_OPEN_SRC -DNONOSDK22x_190703=1 -DTCP_MSS=1460 -DLWIP_FEATURES=0 -DLWIP_IPV6=0 -DVTABLES_IN_FLASH -DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x8000 -Isrc -I/Users/pavel.skuratovich/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include -I/Users/pavel.skuratovich/.platformio/packages/framework-arduinoespressif8266/cores/esp8266 -I/Users/pavel.skuratovich/.platformio/packages/toolchain-xtensa/include -I/Users/pavel.skuratovich/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include -I/Users/pavel.skuratovich/.platformio/packages/framework-arduinoespressif8266/variants/d1_mini src/main.cpp
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s: Assembler messages:
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s: Warning: end of file in string; '"' inserted
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s:31: Error: bad register name: 	a2
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s:31: Error: junk at end of line, first unrecognized character valued 0x9
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s:32: Error: bad register name: 	sp
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s:32: Error: junk at end of line, first unrecognized character valued 0x9
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s:33: Error: bad register name: 	a2
/var/folders/rx/t2c84qxj26xb4xcz964dhx3m0000gp/T//ccSbHKSK.s:33: Error: junk at end of line, first unrecognized character valued 0x9

But if I editplatformio.ini to change

platform = platformio/espressif8266 @ 3.2.0
platform_packages =
    platformio/framework-arduinoespressif8266 @ ~3.30002.0

to

platform = platformio/espressif8266 @ 2.6.3
platform_packages =
    platformio/framework-arduinoespressif8266 @ ~3.20704.0

then platformio run succeeds.

@Chupaka
Copy link
Author

Chupaka commented Sep 11, 2022

Does removing IRAM_ATTR help?

Yes

@mcspr
Copy link
Collaborator

mcspr commented Sep 11, 2022

--- src/t.h     2022-09-11 22:32:42.000000000 +0300
+++ src/t.h.mod 2022-09-11 23:05:37.294064517 +0300
@@ -15,10 +15,12 @@
     ((MyComponent*)OTC)->process();
   }

-  IRAM_ATTR void process() {
+  void process();
+};
+
+IRAM_ATTR void process() {
     const char* Peow[] = {
       "A",
       "B"
     };
-  }
-};
+}

(if someone more familiar with section <-> asm <-> inline decl and def interaction could explain this, please do :)

@Chupaka
Copy link
Author

Chupaka commented Sep 12, 2022

Wow, good job! And it even works with the same definition but external implementation (not sure if those terms are correct). Wonder if I should leave the first IRAM_ATTR in place...


  IRAM_ATTR void process();
};

IRAM_ATTR void MyComponent::process() {
  const char* Peow[] = {
    "A",
    "B"
  };
}

My main project works with the recommended framework now using this workaround. Thank you, @mcspr!

@mcspr
Copy link
Collaborator

mcspr commented Sep 12, 2022

Oops, sorry, that is what I meant. You could totally could use either standalone func or a class method, the point is just to move both section attribute and function body out of the class body aka make it not inline.

It does seem like a workaround, true, just not sure which part of the build takes the blame
Closing this as the immediate issue is solved, perhaps we could come back to this later

@mcspr mcspr closed this as completed Sep 12, 2022
@jjsuwa-sys3175
Copy link
Contributor

The true MCVE is here: It doesn't require any external environment, reproduces only with the toolchain.
(cmdline: "xtensa-lx106-elf-g++ -std=gnu++17 -Os -fno-inline-functions -fno-exceptions -mlongcalls -mtext-section-literals -c")

struct foo {
  __attribute__((section ("\"bar.42\"")))
  void init() {
    const char* astr[] = { "A", "B" };
  }
  foo() {
    init();
  }
} x;

You might want to change "-c" to "-S" and see the assemble listing :) (imho this is a bug of GCC, not others)

@mcspr
Copy link
Collaborator

mcspr commented Sep 12, 2022

Something in optimization, then?

~/d/arduino8672> xtensa-lx106-elf-g++ -c -O0 mcve.cpp
~/d/arduino8672> xtensa-lx106-elf-g++ -c -O1 mcve.cpp
/tmp/cc90CD6F.s: Assembler messages:
/tmp/cc90CD6F.s: Warning: end of file in string; '"' inserted
/tmp/cc90CD6F.s:18: Warning: missing closing '"'
/tmp/cc90CD6F.s:18: Error: unknown opcode or format name ''

edit: ref. -S, this does not seem right

    .section    .rodata.42".str1.4,"aMS",@progbits,1 

@mcspr
Copy link
Collaborator

mcspr commented Sep 12, 2022

Looking a second time

-   __attribute__((section ("\"bar.42\"")))
+   __attribute__((section ("bar.42"))) 

This generates

    .section    .rodata.42.str1.4,"aMS",@progbits,1

Versus the faulty

    .section    .rodata.42".str1.4,"aMS",@progbits,1

@jjsuwa-sys3175
Copy link
Contributor

Looking a second time

-   __attribute__((section ("\"bar.42\"")))
+   __attribute__((section ("bar.42"))) 

This generates

    .section    .rodata.42.str1.4,"aMS",@progbits,1

Versus the faulty

    .section    .rodata.42".str1.4,"aMS",@progbits,1

One more thing: What does that ".section" qualify?

@mcspr
Copy link
Collaborator

mcspr commented Sep 13, 2022

One more thing: What does that ".section" qualify?

const char* array inside of the method

    .file   "mcve.cpp"
    .section    .rodata.42".str1.1,"aMS",@progbits,1 ; <<<
.LC0:
    .string "A"
.LC1:
    .string "B"
    .text
    .global x
    .section    .bss
    .type   x, @object
    .size   x, 1
x:
    .zero   1
    .ident  "GCC: (GNU) 10.3.0"

@jjsuwa-sys3175
Copy link
Contributor

One more thing: What does that ".section" qualify?

const char* array inside of the method

But we should have expected foo::init() rather than an array of const char*. How strange!

@mcspr
Copy link
Collaborator

mcspr commented Sep 13, 2022

One more thing: What does that ".section" qualify?

const char* array inside of the method

But we should have expected foo::init() rather than an array of const char*. How strange!

Which is inlined here, so supposedly it is generated at some point and then discarded?

My bet is off-by-one error, somewhere dealing with these section strings (if / when they are in nearby memory) :)
BTW latest gcc8.4 xtensa build from espressif - https://github.com/espressif/crosstool-NG/releases - this does not seem to do this kind of thing. Maybe something broken in-between the versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants