Tracing a (portion of a) Cmajor program consists of the following phases:
Tracing begins when the program being traced issues the RtBeginTracing function call and ends when the program issues the RtEndTracing function call. When the tracing ends the RtEndTracing function writes a binary trace.bin file to the trace subdirectory of the Cmajor installation directory.
To instrument the system library for tracing, compile it using the trace configration option:
C:\cmajor\system\platform\windows> cmc -u -v -c=trace System.cms
To instrument the program being traced, for example program.cmp, compile it using the trace configuration option:
cmc -u -v -c=trace program.cmp
These two commands generate a text file trace.tab to the trace subdirectory of the Cmajor installation directory. The trace.tab contains one line for each function contained by the system library and the program. The line consists of an integer identifier for the function, a colon, and the full name of the function.
When the system library and the program is compiled with the trace configration, each function in the system library and the program begin traced is instrumented by function calls RtBeginTraceFunction and RtEndTraceFunction that generate a trace entry to the trace.bin file.
Each trace entry (14 bytes) consists of
When the instrumented program is run, the RtEndTracing function generates a binary trace.bin file to the trace subdirectory of the Cmajor installation directory that contains the trace information.
Run the following command:
C:\cmajor\trace> cmtrace2txt -v trace.binThe command converts the trace.bin to trace.txt.
The trace looks like the following:
00:00:01.936.268.100 M >System.Windows.Control.ProcessMessageInternal(Message&) 00:00:01.936.268.500 M >System.Windows.Window.ProcessMessage(Message&) 00:00:01.936.268.700 M >System.Windows.ContainerControl.ProcessMessage(Message&) 00:00:01.936.269.100 M >System.Windows.Control.ProcessMessage(Message&) 00:00:01.936.269.400 M >System.Windows.Control.DoTimer(uint) 00:00:01.936.269.700 M >System.Windows.TimerEventArgs.TimerEventArgs(uint) 00:00:01.936.269.700 M <System.Windows.TimerEventArgs.TimerEventArgs(uint) duration=00:00:00.000.000.000 00:00:01.936.270.000 M >cmcode.MainWindow.OnTimer(TimerEventArgs&) 00:00:01.936.270.400 M >cmcode.MainConfiguration.Instance() 00:00:01.936.270.700 M >UniquePtr<cmcode.MainConfiguration>.operator*() 00:00:01.936.270.700 M <UniquePtr<cmcode.MainConfiguration>.operator*() duration=00:00:00.000.000.000 00:00:01.936.270.800 M <cmcode.MainConfiguration.Instance() duration=00:00:00.000.000.400 00:00:01.936.270.900 M >cmcode.MainConfiguration.Save(bool) 00:00:01.936.271.100 M <cmcode.MainConfiguration.Save(bool) duration=00:00:00.000.000.200 00:00:01.936.271.200 M <cmcode.MainWindow.OnTimer(TimerEventArgs&) duration=00:00:00.000.001.200 00:00:01.936.271.200 M <System.Windows.Control.DoTimer(uint) duration=00:00:00.000.001.800 00:00:01.936.271.500 M <System.Windows.Control.ProcessMessage(Message&) duration=00:00:00.000.002.400 00:00:01.936.271.600 M <System.Windows.ContainerControl.ProcessMessage(Message&) duration=00:00:00.000.002.900 00:00:01.936.271.700 M <System.Windows.Window.ProcessMessage(Message&) duration=00:00:00.000.003.200 00:00:01.936.271.800 M <System.Windows.Control.ProcessMessageInternal(Message&) duration=00:00:00.000.003.700 00:00:01.936.271.900 M >System.Windows.Debug.Messages() 00:00:01.936.271.900 M <System.Windows.Debug.Messages() duration=00:00:00.000.000.000 00:00:01.936.272.100 M <System.Windows.Application.ProcessMessage(void*, uint, uint, long, long&, void*&) duration=00:00:00.000.011.700
Each trace line consists of the following fields:
Usage: cmtrace2txt [options] trace.bin
Convert trace.bin to trace.txt.
Options:
Long option | Short option | Description |
---|---|---|
--help | -h | Print help and exit. |
--verbose | -v | Be verbose. |
--filter="EXPR" | -f="EXPR" | Filter the trace using given filter expression. |
Trace entries can be filtered using filter expressions. Only trace entries matching the filter expression will be included in the converted trace.
filter‑expression | → | and‑expr (or and‑expr)* |
and‑expr | → | boolean‑expr (and boolean‑expr)* |
boolean‑expr | → | match‑expr | relational‑expr |
match‑expr | → | primary‑expr match primary‑expr |
relational‑expr | → | primary‑expr (rel‑op primary‑expr)* |
rel‑op | → | == | <> | <= | >= | < | > |
primary‑expr | → | name | thread | duration | time | level | message | parent | true | false | pattern | string | integer unit? | ( filter‑expression ) |
pattern | → | ' pattern‑expression ' |
string | → | " [^"]* " |
integer | → | [0-9][0-9']* |
unit | → | ns | us | ms | s |
pattern‑expression | → | alternative |
alternative | → | catenation (| catenation)* |
catenation | → | repetition repetition* |
repetition | → | * | ? | primary |
primary | → | ( alternative ) | class | char |
class | → | [ ^? range* ] |
range | → | char (- char)? |
char | → | 'a character or an escape' |
A filter expression is a sequence of boolean‑exprs combined with and and or operators. The precedence of and is greater than the precedence of or.
A boolean‑expr is either a match‑expr or a relational‑expr
A match‑expr is a primary‑expr combined with a pattern using a match operator.
A pattern consists of character classes, characters that are not operator characters and wild cards * and ?.
Wild card * matches any string of characters including an empty string. Wild card ? matches any single character.
A character class begins with a left bracket and is followed by an optional inverse operator ^ followed by any number of character ranges followed by a right bracket. The inverse operator means "any but the following ranges".
A character range is a ordinary character or an escape optionally followed by a dash character and another ordinary character or an escape. It denotes a range of ordinary characters.
An escape begins with the backslash and is similar to an escape sequence in the C programming language.
A relational expression is a primary expresssion optionally followed by a sequence of relational operators and primary expressions.
A relational operator is:
A primary‑expr selects a field from a trace entry, is a pattern, a string, an integer, or a parenthesized filter expression.
The name keyword selects the function name field from a trace entry.
The thread keyword selects the thread name field from a trace entry.
The duration keyword selects the duration field from a trace entry.
The time keyword selects the time field from a trace entry.
The level keyword selects the level of the trace entry. Level is an integer.
The message keyword selects Windows message name from a trace entry.
The parent keyword evaluates to true if parent trace entry is selected, otherwise it evaluates to false.
A primary expression can be an unsigned integer optionally followed by a time unit.
When the left side of a relational expression is either a duration or time, the right side can be an unsigned integer followed by a time unit. The time unit can be:
If a time unit is absent the time is assumed to be in nanoseconds.
cmtrace2txt -v --filter="duration>=10ms" trace.bin
Selects only those function trace entries whose duration is equal to or greater than 10 milliseconds.
cmtrace2txt -v --filter="name match 'System.*' and duration>=10ms" trace.bin
Selects only those function trace entries whose function name starts with "System" followed by a period and duration is equal to or greater than 10 milliseconds.
cmtrace2txt -v --filter="level=0 and duration>=10ms or parent" trace.bin
Selects only those function trace entries that are either top level (level=0) and whose duration is equal to or greater than 10 milliseconds, or whose parent entry is selected. That is, the parent expression selects all child entries of included top level entries.