Skip to content

Commit d3f73ce

Browse files
committed
Forward port changes from v0.6 release branch
Merge a number of fixes from release-0.6 into main. Most importantly: fix refcount calculation when copying data to heaps #1498.
2 parents 2c82f47 + 18f961b commit d3f73ce

30 files changed

+443
-155
lines changed

.github/workflows/build-and-test-macos.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ jobs:
109109
run: |
110110
./tests/test-enif
111111
112+
- name: "Test: test-heap"
113+
working-directory: build
114+
run: |
115+
./tests/test-heap
116+
112117
- name: "Test: test-mailbox"
113118
working-directory: build
114119
run: |

.github/workflows/build-and-test-on-freebsd.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ jobs:
104104
echo "%%"
105105
./tests/test-enif
106106
107+
echo "%%"
108+
echo "%% Running test-heap ..."
109+
echo "%%"
110+
./tests/test-heap
111+
107112
echo "%%"
108113
echo "%% Running test-mailbox ..."
109114
echo "%%"

.github/workflows/build-and-test-other.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,15 @@ jobs:
170170
make AtomVM &&
171171
make test-erlang &&
172172
make test-enif &&
173+
make test-heap &&
173174
make test-mailbox &&
174175
make test-structs &&
175176
file ./tests/test-erlang &&
176177
./tests/test-erlang -s prime_smp &&
177178
file ./tests/test-enif &&
178179
./tests/test-enif &&
180+
file ./tests/test-heap &&
181+
./tests/test-heap &&
179182
file ./tests/test-mailbox &&
180183
./tests/test-mailbox &&
181184
file ./tests/test-structs &&

.github/workflows/build-and-test.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@ jobs:
375375
./tests/test-enif
376376
valgrind ./tests/test-enif
377377
378+
- name: "Test: test-heap"
379+
working-directory: build
380+
run: |
381+
ulimit -c unlimited
382+
./tests/test-heap
383+
valgrind ./tests/test-heap
384+
378385
- name: "Test: test-mailbox"
379386
working-directory: build
380387
run: |

.github/workflows/build-linux-artifacts.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,15 @@ jobs:
227227
VERBOSE=1 make AtomVM &&
228228
make test-erlang &&
229229
make test-enif &&
230+
make test-heap &&
230231
make test-mailbox &&
231232
make test-structs &&
232233
file ./tests/test-erlang &&
233234
./tests/test-erlang -s prime_smp &&
234235
file ./tests/test-enif &&
235236
./tests/test-enif &&
237+
file ./tests/test-heap &&
238+
./tests/test-heap &&
236239
file ./tests/test-mailbox &&
237240
./tests/test-mailbox &&
238241
file ./tests/test-structs &&

CHANGELOG.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
- Added `net:gethostname/0` on platforms with gethostname(3).
1616
- Added `socket:getopt/2`
1717
- Added `supervisor:terminate_child/2`, `supervisor:restart_child/2` and `supervisor:delete_child/2`
18+
- Added support for 'erlang:--/2'.
1819
- Added `esp:partition_read/3`, and documentation for `esp:partition_erase_range/2/3` and `esp:partition_write/3`
1920
- Added support for list insertion in 'ets:insert/2'.
2021
- Support to OTP-28
@@ -27,9 +28,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2728

2829
### Added
2930

30-
- Added the ability to run beams from the CLI for Generic Unix platform (it was already possible with nodejs and emscripten).
31-
- Added support for 'erlang:--/2'.
31+
- Added the ability to run beams from the CLI for Generic Unix platform (it was already possible
32+
with nodejs and emscripten)
3233
- Added preliminary support for ESP32P4 (no networking support yet).
34+
- Added memory info in `out_of_memory` crash logs to help developers fix memory issues.
3335

3436
### Fixed
3537

@@ -38,11 +40,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3840
- Adding missing check, passing a non numeric argument to a function expecting a floating point
3941
might lead to a crash in certain situations.
4042
- Fixed several bugs in `http_server` (#1366)
41-
- Fixed generic\_unix `socket_driver` to return `{gen_tcp, closed}` when socket is closed on Linux instead of `{gen_tcp, {recv, 104}}`
43+
- Fixed generic\_unix `socket_driver` to return `{gen_tcp, closed}` when socket is closed on Linux
44+
instead of `{gen_tcp, {recv, 104}}`
4245
- Fixed a memory leak where modules were not properly destroyed when the global context is destroyd
4346
- alisp: fix support to variables that are not binaries or integers.
4447
- Fixed destruction of ssl-related resources
45-
- Fix corruption when dealing with specific situations that involve more than 16 x registers when
48+
- Fixed corruption when dealing with specific situations that involve more than 16 x registers when
4649
certain VM instructions are used.
4750
- Fixed ESP32 GPIO interrupt trigger `none`
4851
- Fixed an issue where a timeout would occur immediately in a race condition
@@ -51,19 +54,22 @@ certain VM instructions are used.
5154
- Fixed a race condition affecting multi-core MCUs where a timeout would not be properly cleared
5255
- Fixed a double free when esp32 uart driver was closed, yielding an assert abort
5356
- Fixed compilation with latest debian gcc-arm-none-eabi
54-
- Fix `network:stop/0` on ESP32 so the network can be started again
55-
- Fix matching of binaries on unaligned boundaries for code compiled with older versions of OTP
56-
- Fix a memory corruption caused by `binary:split/2,3`
57-
- Fix deadlock in socket code
58-
- Fix bug in opcode implementation (`select_val`): when selecting a value among many others a
57+
- Fixed `network:stop/0` on ESP32 so the network can be started again
58+
- Fixed a memory corruption caused by `binary:split/2,3`
59+
- Fixed deadlock in socket code
60+
- Fixed bug in opcode implementation (`select_val`): when selecting a value among many others a
5961
shallow comparison was performed, so it was working just for plain values such as atoms and small
6062
integers
6163
- Fixed support for setting esp32 boot_path in NVS.
6264
- Fixed race conditions in network:start/stop.
6365
- Fixed crash calling network:sta_rssi(), when network not up.
64-
- Fix error handling when calling `min` and `max` with code compiled before OTP-26: there was a
65-
bug when handling errors from BIFs used as NIFs (when called with `CALL_EXT` and similar opcodes)`
66-
- Fix matching of binaries on unaligned boundaries for code compiled with older versions of OTP
66+
- Fixed error handling when calling `min` and `max` with code compiled before OTP-26: there was a
67+
bug when handling errors from BIFs used as NIFs (when called with `CALL_EXT` and similar opcodes)
68+
- Fixed matching of binaries on unaligned boundaries for code compiled with older versions of OTP
69+
- Added missing out of memory handling in binary_to_atom
70+
- Fixed call to funs such as fun erlang:'not'/1, that make use of BIFs
71+
- Fixed potential crashes or memory leaks caused by a mistake in calculation of reference counts
72+
and a race condition in otp_socket code
6773

6874
## [0.6.5] - 2024-10-15
6975

doc/release-notes.md.in

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ AtomVM will run BEAM files that have been compiled using the following Erlang an
3333
| ✅ OTP 24 | ✅ 1.14 |
3434
| ✅ OTP 25 | ✅ 1.14 |
3535
| ✅ OTP 26 | ✅ 1.15 |
36+
| ✅ OTP 27 | ✅ 1.17 |
3637
| ✅ OTP 28 | ✅ 1.17 |
3738

3839
```{note}
@@ -63,6 +64,7 @@ AtomVM currently supports the following [Espressif ESP SoCs](https://www.espress
6364
| [ESP32h2](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) | ✅ |
6465
| [ESP32s2](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) | ✅ |
6566
| [ESP32s3](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) | ✅ |
67+
| [ESP32p4](https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf) Datasheet Pending | ✅ |
6668

6769
AtomVM currently supports the following versions of ESP-IDF:
6870

@@ -97,13 +99,13 @@ AtomVM tests this build on the latest Ubuntu github runner.
9799

98100
### Raspberry Pi Pico Support
99101

100-
AtomVM supports deployment on the [Raspberry Pico RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html) architecture.
102+
AtomVM supports deployment on the [Raspberry Pico RP2040](https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#pico-1-family) architecture.
101103

102104
AtomVM currently supports the following Raspberry Pico development boards:
103105

104106
| Development Board | AtomVM support |
105107
|------------------------------|----------------|
106-
| [Raspberry Pico and Pico H](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#raspberry-pi-pico-and-pico-h) | ✅ |
107-
| [Raspberry Pico W and Pico WH](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#raspberry-pi-pico-w-and-pico-wh) | ✅ |
108+
| [Raspberry Pico and Pico H](https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#pico-1-technical-specification) | ✅ |
109+
| [Raspberry Pico W and Pico WH](https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#picow-technical-specification) | ✅ |
108110

109111
Building the AtomVM virtual machine for Raspberry Pico is optional. In most cases, you can simply download a release image from the AtomVM [release](https://github.com/atomvm/AtomVM/releases) repository. If you wish to work on development of the VM or use one on the additional drivers that are available in the [AtomVM repositories](https://github.com/atomvm) you will to build AtomVM from source. See the [Build Instructions](build-instructions.md) for information about how to build AtomVM from source code.

doc/src/atomvm-tooling.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,6 @@ For instructions about how to install AtomVM on the `generic_unix` platform, see
347347

348348
The [`ExAtomVM`](https://github.com/atomvm/ExAtomVM) plugin supports flash targets for various device types. These targets are described in more detail below.
349349

350-
```{attention}
351-
Currently, the [`ExAtomVM`](https://github.com/atomvm/ExAtomVM) tool only supports flash targets for the ESP32 and
352-
STM32 platforms.
353-
```
354-
355350
#### ESP32 flash task
356351

357352
To flash AtomVM packbeam file to an ESP32 device, use the `mix.esp32.flash` target. Users will typically specify the device port and baud rate as command-line options to this target.
@@ -401,7 +396,7 @@ You can now use a serial console program such as [minicom](https://en.wikipedia.
401396
I (922) AtomVM: Starting esp32init.beam...
402397
---
403398
AtomVM init.
404-
I (932) sys: Loaded BEAM partition main.avm at address 0x210000 (size=1048576 bytes)
399+
I (932) sys: Loaded BEAM partition main.avm at address 0x250000 (size=1048576 bytes)
405400
Starting application...
406401
Hello World
407402
AtomVM finished with return value: ok

doc/src/build-instructions.md

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ $ cd <atomvm-source-tree-root>
231231
$ cd src/platforms/esp32
232232
```
233233

234+
If you want to build an image with Elixir modules included you must first have a version of Elixir installed that is compatible with your OTP version, then add the following line to sdkconfig.defaults:
235+
```shell
236+
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-elixir.csv"
237+
```
238+
234239
Start by updating the default build configuration of local `sdkconfig` file via the `idf.py reconfigure` command:
235240

236241
```shell
@@ -378,11 +383,7 @@ The AtomVM Flash memory is partitioned to include areas for the above binary art
378383

379384
The flash layout is roughly as follows (not to scale):
380385

381-
+-----------------+ ------------- 0x0000
382-
| secure |
383-
| boot | 4KB
384-
| |
385-
+-----------------+ ------------- 0x1000
386+
+-----------------+ ------------- 0x0 | 0x1000 | 0x2000
386387
| | ^
387388
| boot loader | 28KB |
388389
| | |
@@ -404,9 +405,9 @@ The flash layout is roughly as follows (not to scale):
404405
| | |
405406
| | |
406407
+-----------------+ |
407-
| boot.avm | 256KB v
408-
+-----------------+ ------------- 0x210000
409-
| | ^
408+
| boot.avm | 256-512KB v
409+
+-----------------+ ------------- 0x210000 for Erlang only images or
410+
| | ^ 0x250000 for images with Elixir modules
410411
| | |
411412
| main.avm | 1MB+ | Erlang/Elixir
412413
| | | Application
@@ -418,22 +419,25 @@ The following table summarizes the partitions created on the ESP32 when deployin
418419

419420
| Partition | Offset | Length | Description |
420421
|:----------|:-------|:-------|:------------|
421-
| Secure Boot | 0x00 | 4kB | Initialization vectors and other data needed for ESP32 secure boot. |
422-
| Bootloader | 0x1000 | 28kB | The ESP32 bootloader, as built from the IDF-SDK. AtomVM does not define its own bootloader. |
422+
| Bootloader | 0x0 \| 0x1000 \| 0x2000 | 28kB | The ESP32 bootloader, as built from the IDF-SDK. AtomVM does not define its own bootloader. The offset of the bootloader varies by chip.|
423423
| Partition Table | 0x8000 | 3kB | The AtomVM-defined partition table. |
424424
| NVS | 0x9000 | 24kB | Space for non-volatile storage. |
425425
| PHY_INIT | 0xF000 | 4kB | Initialization data for physical layer radio signal data. |
426426
| AtomVM virtual machine | 0x10000 | 1.75mB | The AtomVM virtual machine (compiled from C code). |
427427
| boot.avm | 0x1D0000 | 256k | The AtomVM BEAM library, compiled from Erlang and Elixir files in the AtomVM source tree. |
428-
| main.avm | 0x210000 | 1mB | The user application. This is where users flash their compiled Erlang/Elixir code |
428+
| main.avm | `0x210000` \| `0x250000` | 1mB | The user application. This is where users flash their compiled Erlang/Elixir code |
429+
430+
```{warning}
431+
There is an important difference in the partition layout between the minimal images and those build with Elixir support. To accommodate the extra Elixir modules the boot.avm partition on these images is larger, and the application offset is moved accordingly. When working with Elixir supported images it is important to always use the offset `0x250000` whether using `mix` or the `atomvm_rebar3_plugin` (possibly to test an Erlang app), otherwise part of the boot.avm partition (specifically the area where many Elixir modules are located) will be overwritten with the application, but the VM will still be trying to load from the later `0x250000` offset. This should be kept in mind reading the rest of build instructions, and [AtomVM Tooling](./atomvm-tooling.md) sections of the docs that cover the use of rebar3, for these sections an Erlang only image is assumed.
432+
```
429433

430434
### The `boot.avm` and `main.avm` partitions
431435

432436
The `boot.avm` and `main.avm` partitions are intended to store Erlang/Elixir libraries (compiled down to BEAM files, and assembled as AVM files).
433437

434438
The `boot.avm` partition is intended for core Erlang/Elixir libraries that are built as part of the AtomVM build. The release image of AtomVM (see below) includes both the AtomVM virtual machine and the `boot.avm` partition, which includes the BEAM files from the `estdlib` and `eavmlib` libraries.
435439

436-
In contrast, the `main.avm` partition is intended for user applications. Currently, the `main.avm` partition starts at address `0x210000`, and it is to that location to which application developers should flash their application AVM files.
440+
In contrast, the `main.avm` partition is intended for user applications. Currently, the `main.avm` partition starts at address `0x210000` for thin images or `0x250000` for images with Elixir modules, and it is to that location to which application developers should flash their application AVM files.
437441

438442
The AtomVM search path for BEAM modules starts in the `main.avm` partition and falls back to `boot.avm`. Users should not have a need to override any functionality in the `boot.avm` partition, but if necessary, a BEAM module of the same name in the `main.avm` partition will be loaded instead of the version in the `boot.avm` partition.
439443

@@ -456,20 +460,31 @@ you target a different build directory when running CMake.
456460

457461
Running this script will generate a single `atomvm-<sha>.img` file in the `build` directory of the esp32 source tree, where `<sha>` is the git hash of the current checkout. This image contains the ESP32 bootloader, AtomVM executable, and the `eavmlib` and `estdlib` Erlang libraries in one file, which can then be flashed to address `0x1000` for the esp32. The bootloader address varies for other chip variants. See the [flashing a binary image to ESP32](./getting-started-guide.md#flashing-a-binary-image-to-esp32) section of the [Getting Started Guide](./getting-started-guide.md) for a chart with the bootloader offset address of each model.
458462

459-
The `mkimage.sh` script is run from the `src/platform/esp32` directory as follows:
463+
To build a thin image with only Erlang libraries `mkimage.sh` script is run from the `src/platform/esp32` directory as follows:
460464

461465
```shell
462466
$ ./build/mkimage.sh
463-
Writing output to /home/joe/AtomVM/src/platforms/esp32/build/atomvm-esp32-0.6.0
464-
-dev+git.602e6bc.img
467+
Writing output to /home/joe/AtomVM/src/platforms/esp32/build/atomvm-esp32.img
468+
=============================================
469+
Wrote bootloader at offset 0x1000 (4096)
470+
Wrote partition-table at offset 0x8000 (32768)
471+
Wrote AtomVM Virtual Machine at offset 0x10000 (65536)
472+
Wrote AtomVM Core BEAM Library at offset 0x1D0000 (1114112)
473+
```
474+
475+
To build a full image with Erlang and Elixir libraries the path to the previously (during the generic_unix build) built `elixir_esp32boot.avm` must be passed to the `mkimage.sh` script as follows (Note: this is still run from the AtomVM/src/platforms/esp32 directory for the relative path to work - feel free to use the absolute path to this file):
476+
477+
```shell
478+
$ ./build/mkimage.sh --boot ../../../build/libs/esp32boot/elixir_esp32boot.avm
479+
Writing output to /home/joe/AtomVM/src/platforms/esp32/build/atomvm-esp32.img
465480
=============================================
466481
Wrote bootloader at offset 0x1000 (4096)
467482
Wrote partition-table at offset 0x8000 (32768)
468483
Wrote AtomVM Virtual Machine at offset 0x10000 (65536)
469-
Wrote AtomVM Core BEAM Library at offset 0x110000 (1114112)
484+
Wrote AtomVM Core BEAM Library at offset 0x1D0000 (1114112)
470485
```
471486

472-
Users can then use the `esptool.py` directly to flash the entire image to the ESP32 device, and then flash their applications to the `main.app` partition at address `0x210000`,
487+
Users can then use the `esptool.py` directly to flash the entire image to the ESP32 device, and then flash their applications to the `main.app` partition at address `0x210000`, (or `0x250000` for Elixir images)
473488

474489
But first, it is a good idea to erase the flash, e.g.,
475490

@@ -488,7 +503,7 @@ Hard resetting...
488503

489504
#### Flashing Release Images
490505

491-
After preparing a release image you can use the `flashimage.sh`, which is generated with each build that will flash the full image using the correct flash offset for the chip the build was configured for.
506+
After preparing a release image you can use the `flashimage.sh`, which is generated with each build that will flash the full image using the correct flash offset for the chip the build was configured for using the either the default Erlang only `partitions.cvs` table, or the `partitions-elixir.cvs` table if that was used during the configuration.
492507

493508
```shell
494509
$ ./build/flashimage.sh
@@ -497,7 +512,7 @@ $ ./build/flashimage.sh
497512
To perform this action manually you can use the `./build/flash.sh` tool (or `esptool.py` directly, if you prefer):
498513

499514
```shell
500-
$ FLASH_OFFSET=0x1000 ./build/flash.sh ./build/atomvm-esp32-0.6.0-beta-0.img
515+
$ FLASH_OFFSET=0x1000 ./build/flash.sh ./build/atomvm-esp32-0.6.6.img
501516
esptool.py v2.8-dev
502517
Serial port /dev/tty.SLAB_USBtoUART
503518
Connecting........_
@@ -525,7 +540,8 @@ have a way to recover and re-write any such data, if you need to retain it.
525540

526541
### Flashing Applications
527542

528-
Applications can be flashed using the `flash.sh` script in the esp32 build directory:
543+
Applications can be flashed using the `flash.sh` script in the esp32 build directory (the application offset is set
544+
correctly depending on the build configuration):
529545

530546
```shell
531547
$ ./build/flash.sh ../../../build/examples/erlang/esp32/blink.avm
@@ -562,12 +578,12 @@ applications for the AtomVM platform.
562578

563579
#### Flashing the core libraries
564580

565-
If you are doing development work on the core Erlang/Elixir libraries and wish to test changes that do not involve the `C` code in the core VM you may flash `atomvmlib.avm` to the avm.lib partition (offset 0x1D0000) by using the `flash.sh` script in the esp32 build directory as follows:
581+
If you are doing development work on the core Erlang/Elixir libraries and wish to test changes that do not involve the `C` code in the core VM you may flash `esp32boot.avm` (or `elixir_esp32boot.avm` when using an Elixir partition table) to the boot.avm partition (offset 0x1D0000) by using the `flash.sh` script in the esp32 build directory as follows:
566582

567583
```shell
568-
$ build/flash.sh -l ../../../build/libs/atomvmlib.avm
584+
$ build/flash.sh -l ../../../build/libs/esp32boot.avm
569585
%%
570-
%% Flashing ../../../build/libs/atomvmlib.avm (size=116k)
586+
%% Flashing ../../../build/libs/esp32boot.avm (size=116k)
571587
%%
572588
esptool.py v4.5.1
573589
Serial port /dev/ttyUSB0

0 commit comments

Comments
 (0)