Skip to content

Conversation

@fadushin
Copy link
Collaborator

@fadushin fadushin commented Nov 19, 2022

This PR adds support for stacktraces, both in the display of crash reports, as well as programmatic access to stacktrace data as terms in catch clauses.

Stacktrace data is represented as a list of tuples, each of which represents a stack “frame”. Each tuple is of the form:

[{Module :: module(), Function :: atom(), Arity :: non_neg_integer(), AuxData :: aux_data()}]

where aux_data() is a (possibly empty) properties list containing the following elements:

[{file, File :: string(), line, Line :: pos_integer()}]

Stack frames are ordered from the frame “closest“ to the point of failure (the “top” of the stack) to the frame furthest from the point of failure (the “bottom” of the stack).

Stack frames will contain file and line information in the AuxData list if the BEAM files (typically embedded in AVM files) include <<“Line”>> chunks generated by the compiler. Otherwise, the AuxData will be empty.

Note that adding line information to BEAM files not only increases the size of BEAM files in storage, but calculation of file and line information can have a non-negligible impact on memory usage. Memory-sensitive applications should consider not including line information in BEAM files.

Addresses issue #254.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

@fadushin fadushin force-pushed the stacktrace branch 5 times, most recently from 024d332 to 2d1ee66 Compare November 22, 2022 00:22
@fadushin fadushin force-pushed the stacktrace branch 8 times, most recently from d2f0095 to 0723f1c Compare December 1, 2022 03:50
@fadushin fadushin marked this pull request as ready for review December 7, 2022 02:43
@fadushin fadushin requested a review from bettio December 7, 2022 02:43
@fadushin fadushin force-pushed the stacktrace branch 3 times, most recently from 8f7a114 to c3a508f Compare December 9, 2022 03:32
Copy link
Collaborator

@pguyot pguyot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed elsewhere, another approach would be to modify the code loading function (or create a new one) and call it when a stack trace is needed, so that the data structures are not kept with the modules but are only generated on stack trace creation.

@fadushin fadushin force-pushed the stacktrace branch 2 times, most recently from 726edb8 to 6263486 Compare December 11, 2022 18:02
@fadushin
Copy link
Collaborator Author

As discussed elsewhere, another approach would be to modify the code loading function (or create a new one) and call it when a stack trace is needed, so that the data structures are not kept with the modules but are only generated on stack trace creation.

Wow, that would be a challenge! I think I would like to treat that as an optimization (future tense) and maybe give this some soak time to flush out any bugs. What do you think?

@pguyot
Copy link
Collaborator

pguyot commented Dec 11, 2022

As discussed elsewhere, another approach would be to modify the code loading function (or create a new one) and call it when a stack trace is needed, so that the data structures are not kept with the modules but are only generated on stack trace creation.

Wow, that would be a challenge! I think I would like to treat that as an optimization (future tense) and maybe give this some soak time to flush out any bugs. What do you think?

Let's choose the memory optimizations we want. Personally, I'm perfectly fine with the additional memory impact, and I believe larger memory gains can be obtained elsewhere (especially with gc / heaps) and the actual optimization target (or memory constraint) should be known. I'm also pointing that possible optimization as opposed to have strings in binaries vs lists. Let's move forward with stack traces which are a huge benefit, but also let's try to stick to OTP specifications. As a recent user of AtomVM, I found it difficult to not find usual Erlang stuff.

@fadushin fadushin force-pushed the stacktrace branch 3 times, most recently from f29b690 to d672cae Compare December 12, 2022 03:54
@bettio bettio added this to the v0.6 milestone Dec 18, 2022
@fadushin fadushin requested a review from bettio December 21, 2022 12:28
@fadushin fadushin force-pushed the stacktrace branch 2 times, most recently from c60db00 to b121049 Compare December 26, 2022 02:33
fadushin and others added 14 commits January 2, 2023 11:16
…M files, and CMake (AVM_RELEASE) variable to disable line information (enabled by default on development builds)

Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
…dule in a stacktrace.

Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
Signed-off-by: Fred Dushin <fred@dushin.net>
bettio pushed a commit that referenced this pull request Jan 2, 2023
Implement stack traces

This PR adds support for stacktraces, both in the display of crash reports, as
well as programmatic access to stacktrace data as terms in catch clauses.

Stacktrace data is represented as a list of tuples, each of which represents a
stack “frame”.  Each tuple is of the form:
```
[{Module :: module(), Function :: atom(), Arity :: non_neg_integer(), AuxData :: aux_data()}]
```
where `aux_data()` is a (possibly empty) properties list containing the following elements:
```
[{file, File :: string(), line, Line :: pos_integer()}]
```
Stack frames are ordered from the frame “closest“ to the point of failure
(the “top” of the stack) to the frame furthest from the point of failure
(the “bottom” of the stack).

Stack frames will contain file and line information in the `AuxData` list if the
BEAM files (typically embedded in AVM files) include `<<“Line”>>` chunks
generated by the compiler.  Otherwise, the `AuxData` will be empty.

Note that adding line information to BEAM files not only increases the size of
BEAM files in storage, but calculation of file and line information can have a
non-negligible impact on memory usage.  Memory-sensitive applications should
consider not including line information in BEAM files.

Addresses issue #254.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
@bettio
Copy link
Collaborator

bettio commented Jan 2, 2023

Merged.

@bettio bettio closed this Jan 2, 2023
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

Successfully merging this pull request may close these issues.

3 participants