The repo of rust crate 'releasetag'. Releasetags can be extracted from application crash-files postmortem
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
test
.gitignore
Cargo.toml
LICENSE
README.md

README.md

releasetag

The crate 'releasetag' provides tooling for post-mortem analysis of rust-apps.

Releasetags are placed in context of main() function or on stack of any other thread. These tags will placed on stack. In case of an application crash the tag can be extracted from core dump file.

Use case

Imagine multiple releases/devdrops of your software have been shipped to your customer. Now the customer is filing multiple crash-reports with attached core-file(s), but customer is providing unreliable information regarding the corresponding release in question.

Now, extracting the releasetag from each core-file the developers will be able to tell the correspondig software revision and knows which debug symbols should be used from archive for further investigation of backtraces.

Example Cargo.toml

...
[dependencies]
releasetag = "0.8.0"

Example: file main.rs

#![feature(asm)] 
#[macro_use(releasetag)]
extern crate releasetag;

fn main() {
    // The releasetag macro must be used within main-routine
    // and the arguments must be byte-strings of the form b".."
    releasetag!(b"BUILD_TAG=MAIN_2016-wk16-05-AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-GGGG-HHHH-IIII-JJJJ-KKKK");
    releasetag!(b"BUILD_HOST=host1");
    // or as byte array
    releasetag!(&[0x42u8, 0x55u8, 0x49u8, 0x4cu8, 0x44u8, 0x5fu8]); // "BUILD_"
 
    // your application logic here
}

In case the application did coredump to file 'core', the following command can be used to extract the tags from core-file:

cat core | strings | grep BUILD_

The argument of releasetag!() must be a byte-string (array) of 8bit elements, with unlimited length. Regular UTF-Strings are not supported due to non-printable chars.

The releasetag is a compile-time feature, without any processing during runtime. Boundary checks of the array are performed during compile time.

The overhead depends on the underlying architecture and default integer-size. For 32bit architecture the overhead is 5 bytes, for 64bit architectures the overhead is 9bytes (sum of byte-size of primitive 'usize' and byte-size of u8). For example on 32bit arch, if the releasetag! defines a byte string of 50 characters, the occupied stack-size would be 55 bytes, adding leading and trailing null-characters.

Byte strings of the form b"Hallo" is length encoded without trailing '\0' and this specific string has static size of 5 unsigned octets 'u8', with Rust-notation '&[u8; 5]'

Demonstrator

Execute the following script to verify the releasetag feature is working:

./test/run_test.sh

On success, the output should show:

BUILD_HOST=host1
BUILD_TAG=MAIN_2016-wk16-05-AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-GGGG-HHHH-IIII-JJJJ-KKKK
Success: releasetags found in file 'core'

###Explained: The script test/run_test.sh is compiling the application 'test-tag' with release mode, verifying the optimizer is not eliminating the 'unused' stacktag variables. The application test-tag contains two releasetags BUILD_HOST=.. and BUILD_TAG=..

After a few seconds he script continues sending signal 6 (ABORT) to the process to cause the application to core-dump with signal 6. The location of the core file will be 'test/core'.

The resulting core-file is scanned for the releasetag strings 'BUILD_'.

On success the script will return with return value 0, otherwise the feature is broken and return value will be 1.

The feature requires that the optimizer of compiler rustc is not eliminating the 'unused' stacktag variables. This is achieved by declaring a structure FixedType and corresponding Drop destructor.

The script ./test/run_test.sh is evaluating correct functionality of the feature.