The way you describe a scope is similar to the way you specify a file. The scopes in a program form a tree, with the outermost scope, which is your program, as the root. At the next level are executable files and dynamic libraries; further down are compilation units (source files), procedures, modules, and other scoping units (for example, blocks) supported by the programming language. Qualifying a symbol is equivalent to describing the path to a file in UNIX file systems.
A symbol is fully scoped when you name all levels of its tree. The following example shows how this is done. It also indicates parts that are optional.
[#executable-or-lib#][file#][procedure-or-line#]symbol
The pound sign (#) separates elements of the fully qualified name.
Note: Because of the number of different kinds of things that can appear in your program, a formal specification of what can appear and the order in which things can appear complicated, and, unreadable. After you see the name, in the Stack Frame Pane, you'll know a variable's scoped name.
TotalView interprets the components as follows:
- Just as file names need not be qualified with a full path, you do not need to use all levels in a symbol's scoping tree.
- If a qualified symbol begins with #, the name that follows indicates the name of the executable or shared library (just as an absolute file path begins with a directory immediately within the root directory). If you omit the executable or library component, the qualified symbol doesn't begin with #.
- The source file's name may appear after the (possibly omitted) executable or shared library.
- Because programming languages typically do not let you name blocks, that portion of the qualifier is specified using the letter b followed by a number indicating which block. For example, the first unnamed block is named #b1, the second as #b2, and so on.
You can omit any part of the scope specification that TotalView doesn't need to uniquely identify the symbol. Thus, foo#x identifies the symbol x in the procedure foo. In contrast, #foo#x identifies either procedure x in executable foo or variable x in a scope from that executable.
Similarly, #foo#bar#x could identify variable x in procedure bar in executable foo. If bar were not unique within that executable, the name would be ambiguous unless you further qualified it by providing a file name. Ambiguities can also occur if a file-level variable (common in C programs) has the same name as variables declared within functions in that file. For instance, bar.c#x refers to a file-level variable, but the name can be ambiguous when there are different definitions of x embedded in functions occurring in the same file. In this case, you would need to say bar.c#b1#x to identify the scope that corresponds to the "outer level" of the file (that is, the scope containing line 1 of the file).