Category: Coding / Operating Systems

How to decode the exception backtrace of an ESP32


When the execution of code on an ESP32 throws an exception, the output might look like this:

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.??
Core  1 register dump:??
PC      : 0x420383b2  PS      : 0x00060c30  A0      : 0x820059ec  A1      : 0x3fcebd70  ??
A2      : 0x3fc97708  A3      : 0x3fcebdcb  A4      : 0x00000001  A5      : 0x0000ff00  ??
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x3fcecf5b  A9      : 0x0000723f  ??
A10     : 0x3fcecf5b  A11     : 0x00000001  A12     : 0x00000001  A13     : 0x3fcf06b4  ??
A14     : 0x00000001  A15     : 0x00000003  SAR     : 0x00000017  EXCCAUSE: 0x0000001c  ??
EXCVADDR: 0x0000728b  LBEG    : 0x40056f08  LEND    : 0x40056f12  LCOUNT  : 0x00000000  ??
Backtrace: 0x420383af:0x3fcebd70 0x420059e9:0x3fcebd90 0x42004e26:0x3fcebdb0 0x420035a2:0x3fcebe00 0x42003595:0x3fcebe20 0x4200542c:0x3fcebe40 0x42008891:0x3fcebe60??

The Espressif tools contain a binary called xtensa-esp32-elf-addr2line which will decode the backtrace addresses and return details about the source files, lines and function names, etc.

To run the tool, call:

/home/user/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/xtensa-esp32-elf-addr2line -fe /path/to/build/<ELFFILE>.elf <BACKTRACE>

In the command above, simply…

  • replace the path to the xtensa-esp32-elf-addr2line binary
    (in my case the binary is located in the users home directory in the folder .espressif)
  • replace the path to your elf file
    (normally, the elf file is located in the build path and generated during compilation)
  • replace the backtrace output string
    (it’s the string that is shown after Backtrace: )


How to enter ASCII control characters with your keyboard

close photo of a macbook pro keyboard

Entering ASCII control characters depends on the specific keyboard layout and operating system you are using. Here’s a general guide for Linux, Windows, and macOS:


In most Linux terminals, you can enter ASCII control characters using the keys Ctrl + Shift + u in combination with a letter or symbol. For example:

  • Ctrl + Shift + u and then 0 + 1: ASCII code 0x01 (Start of Heading)
  • Ctrl + Shift + u and then 0 + 2: ASCII code 0x02 (Start of Text)
  • Ctrl + Shift + u and then 0 + 3: ASCII code 0x03 (End of Text)
  • And so on…


In the Windows operating system, you can use the following steps:

  1. For characters with ASCII values 0 to 31, you can typically enter them using the Alt key and the numeric keypad. For example, to enter ASCII 0x01, press Alt + 0 + 0 + 1.
  2. For some characters, you can use the Windows Character Map utility. Press the Win key + R to open the Run dialog, type charmap, and press Enter. Select the desired character and copy/paste it.


On macOS, you can use the following steps:

  1. Character Viewer: Press Control + Command + Space to open the Character Viewer. Search for the desired control character and insert it into your document.

Note that you may have to go to the dots menu at top left and select Customize to add the Unicode category. The Unicode category is under Code Tables.

Note: The availability of these methods may vary depending on your keyboard layout and the specific software you are using. If you’re using a specific text editor or terminal, it might have its own way of entering control characters.

Foto von Jess Bailey auf Unsplash


macOS: how to print a test page

colorful photo of macbook pro with dark background

To print a test page on a Mac, follow these steps:

  1. Open “System Preferences”.
  2. Click on “Printers & Scanners” (or “Print & Scan” depending on your macOS version).
  3. Select the printer you want to print a test page from.
  4. Click the “Open Print Queue”.
  5. A new window will open, showing the print queue for the selected printer.
  6. Look for the “Printer” menu at the top of the window and select “Print Test Page” or “Print Test Sheet.”
  7. Your printer will now print a test page.

Please note that the specific steps may vary slightly depending on your macOS version.

Foto von Andras Vas auf Unsplash

ESP32: Stack canary watchpoint triggered (loopTask)


Recently, I stumble upon the following error on an ESP32:

Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask) 
Core 1 register dump:
PC      : 0x40083774  PS      : 0x00060b36  A0      : 0x3ffb0120  A1      : 0x3ffb0060  
A2      : 0x68efa751  A3      : 0x3ffb0938  A4      : 0x3ffb0720  A5      : 0xfb879c5c  
A6      : 0x61b36b71  A7      : 0x0006970f  A8      : 0x01709af4  A9      : 0x01709af4  
A10     : 0xfaa5dfed  A11     : 0x01a3ff3b  A12     : 0x76651dec  A13     : 0x00000001  
A14     : 0x00000000  A15     : 0x04adbe74  SAR     : 0x0000001e  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x400f1cc5  LEND    : 0x400f1cc9  LCOUNT  : 0x00000000  

ELF file SHA256: 0000000000000000

The reason for this was an infinite loop that was caused by two methods that where called from each other. So the execution of the first method never ended. The code looked something like this (extremly simplified):

void loop() {

void methodOne() {
  // ... some other code and conditions
void methodTwo() {
  // ... some other code and conditions

Foto von Vishnu Mohanan auf Unsplash

ESP32: how to read and write the partition table of an ESP device?


To communicate with an ESP32 the ESP-IDF (Espressif IoT Development Framework) can be used. This framework provides a collection of useful scripts to communicate with your ESP device. The framework is supported on Windows, Linux and macOS.

You can download the ESP-IDF repository and extract the contents into a folder.

Note that you need to have python 3 installed. For example by using brew install python on macOS. In addition, the esptool library is required by running pip install esptool in your terminal.

Reading the Partition Table

The partition table is located at 0x8000 (32768) on older, and on 0x9000 (36384) on newer systems. Its length is always 0xc00 (3072) bytes.

With the, this can be read out, for example by the command

python $(IDF_PATH)/components/esptool_py/esptool/ read_flash 0x9000 0xc00 partitions.img

To create a “human” readable csv file, you can use the tool:

python $(IDF_PATH)/components/partition_table/ partitions.img > partitions.csv

In my case, the partition table looks as follows:

Writing the Partition Table

When using an IDE like PlatformIO, the flashing of the partition table is part of the build process. For this, just add the following line to your platformio.ini:

board_build.partitions = partitions.csv

The Manual Way

First, you have to generate the partition table binaries. This can be done with

python $(IDF_PATH)/components/partition_table/ partitions.csv partitions.bin

Then you can use (which we already used for reading) for writing:

python $(IDF_PATH)/components/esptool_py/esptool/ write_flash -z 0x9000 partitions.bin

More details about Partition Tables, how to create custom tables, handle different partition types and the flashing precedure are listed on the official Espressif documentation.

Foto von Vishnu Mohanan auf Unsplash

How to use your Mac for time-lapse like webcam shots

long exposure photo of a street in a city a night

When searching for a script that captures images from my Macs internal camera, I found a small tool called ImageSnap. This small tool is very simple in its usage, but it’s one of the key tools when you want to use your Mac as a webcam.

ImageSnap is a Public Domain command-line tool that lets you capture still images from an iSight or other video source.


ImageSnap can be conveniently installed through package managers like Homebrew and MacPorts. One of the simplest methods to install ImageSnap is by executing the following command:

brew install imagesnap


To use ImageSnap, open the macOS terminal and navigate to the folder where all your images should be stored. In my case, I used a folder located in iCloud Drive so that I can access those files from any other device that uses the same iCloud account.

Then I just provided the time interval between the images by using the -t parameter:

imagesnap -t 60

A value of 60 will result in a picture every minute (= 60 seconds).

There are several other options for ImageSnap to fine tune your image capturing. The help output gives you all the details:

imagesnap -h
USAGE: imagesnap [options] [filename-or-dir]
Version: 0.2.16
Captures an image from a video device and saves it in a file.
If no device is specified, the system default will be used.
If no filename is specfied, snapshot.jpg will be used.
If timelapse is used, the filename argument can be a directory where files will be saved.
JPEG is the only supported output type.
  -h          This help message
  -v          Verbose mode
  -l          List available video devices
  -t x.xx     Take a picture every x.xx seconds
  -n num      Limit to <num> snapshots in -t timelapse mode
  -q          Quiet mode. Do not output any text
  -w x.xx     Warmup. Delay snapshot x.xx seconds after turning on camera (default 3sec)
  -d device   Use named video device

Foto von Adrian Schwarz auf Unsplash.

Why does the iOS App Store show more languages than my app supports?

By default, the languages of an app are listed in info.plist by setting the values for the properties list key CFBundleLocalizations. A definition as shown below should result in supported languages English and German.


But when looking at the AppStore, the languages shown there do not always correlated with this setting. The reason is that the languages shown on the AppStore are generated automatically based on the localized *.lproj folders found in your app.

Normally those folders should be in sync with your properties list setting. But when you use third party libraries (e.g. with CocoaPods) additional localizations might be loaded into your app. In this case, all *.lproj folders found in your app and in the pods are used for language determination.

How to correct the languages?

There is a plugin for that: cocoapods-prune-localizations, which can be simply added to your Podfile. When running pod install, this script will remove all localized files from pods or just keep the specified languages. To install the script, run:

gem install cocoapods-prune-localizations

Then add the following lines to your Podfile:

plugin 'cocoapods-prune-localizations'

Localizations will be inferred from your project.

or if you would prefer to specify the localizations:

plugin 'cocoapods-prune-localizations', {:localizations => ["en", "es"]}

This will keep the English and Spanish localizations in the Pods. Modify the localizations to your needs.

Photo by Etienne Girardet on Unsplash

Build and Release a Flutter App

Updating the app’s version number

To update the version number, navigate to the pubspec.yaml file and update the following line with the current version string:

version: 1.0.0+1

After the change, run:

flutter pub get

Build and release the iOS app

A detailled description of the whole process is described at

To release the iOS app, you use Flutter to build a xcarchive file. This build archive can be published the same way you would do it with Xcode by using the archive manager and one of the different Distribution options.

Build the iOS app:

flutter build ipa

The generated xcarchive file is saved to your app directory under:


Build and release the Android app

A detailled description of the whole process is described at

To release the Android app, you use Flutter to build a app bundle aab file. This file can be distributed by using Google Play Console or any other store.

Build the Android app:

flutter build appbundle

The generated aab app bundle file is saved to your app directory under:


Photo by Artur Shamsutdinov on Unsplash