The crate 'releasetag' provides tooling to identify from crash-files the release-tag post-mortem.
Releasetags are placed in context of main() function or on stack of any other thread. In case the application crashes, such tags can be extracted from core-dump file.
Releasetags can be formed from one or multiple byte-strings, byte-arrays or includes from files. Those must not contain any whitespace as new-lines or line-breaks.
Imagine multiple releases/devdrops of your software have been shipped to your customer. Now the customer is filing multiple crash-reports with attached core-dumps, just the customer is providing unreliable information regarding the corresponding release in question and you would have to guess the software-release.
Now, extracting the releasetag from each core-file it is possible to tell the correspondig software-release and choosing the correct debug symbols from archive for further investigation of backtraces.
Example Cargo.toml
...
[dependencies]
releasetag = "^1.1"
Example: file test/src/main.rs
#[macro_use(releasetag)]
extern crate releasetag;
fn main() {
releasetag!(b"BUILD_TAG=pre");
releasetag!(b"BUILD_TAG=", b"MAIN_2016-wk16-05-AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-GGGG-HHHH-IIII-JJJJ-KKKK");
// Including data from one or multiple files or compile time env params.
// Note: the content mustn't contain any newline or linebreak as those would interfer with zero terminated strings!!
let mut version: [u8; 5] = [0; 5];
version.copy_from_slice(env!("CARGO_PKG_VERSION").as_bytes());
releasetag!(b"BUILD_VERSION=", &version);
releasetag!(b"BUILD_TAG=", &version, b"/", include_bytes!("../../AUTHOR"));
// or as byte array
releasetag!(b"BUILD_HOST=", &[0x30u8, 0x31u8, 0x33u8]);
// your application logic here
}
In case the application does crash its state is dumped to a core-file 'core', and for example the following system command 'strings' can be used to extract the tags from core-file:
cat core | strings | grep BUILD_
Releasetags can be formed from one or multiple byte-strings, byte-arrays or includes from files. Those must not contain any whitespace as new-lines or line-breaks. Regular Rust-strings are not supported as they may contain zero-characters.
The releasetag is a compile-time feature, without any processing during runtime.
The overhead of each releasetag depends on the underlying architecture and default integer-size. For 32bit architecture the overhead will be 5 bytes, for 64bit architectures the overhead will be 9bytes, caused by leading and trailing zero paddings.
For example on 32bit arch, a releasetag! of 50 characters, will the occupy 55 bytes on memory stack.
Execute the following script to verify the releasetag feature is working:
./test/run_test.sh
On success, the output should show:
aiting until being aborted
...../run_test.sh: line 14: 25494 Aborted (core dumped) ./target/release/test-tag
BUILD_HOST=013
BUILD_VERSION=1.1.0
BUILD_TAG=pre
BUILD_TAG=1.1.0/frehberg@gmail.com
BUILD_TAG=MAIN_2016-wk16-05-AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-GGGG-HHHH-IIII-JJJJ-KKKK
Success: releasetags found in file 'core'
The script test/run_test.sh is compiling the application 'test-tag' with 'release' flag. Intention of this test is to verify that the releasetag elements do survive the 'release' optimizer-pass during compilation. The script ./test/run_test.sh is evaluating correct functionality of the releasetag-feature.
The application test-tag contains a number of 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 exit with return value 0, otherwise the feature is broken and return value will be 1.