Using glastpack for Code Development

Preliminaries

Need to be able to find glastpack. If you're using a SLAC public Linux machine it's at /afs/slac.stanford.edu/g/glast/ground/scripts/glastpack.pl so, e.g., run the group cshrc which

Otherwise, you'll need to pick up your own copy of glastpack.pl and put it in a directory included in your PATH. One way or another you'll have to also get CVS, CMT and external libraries properly set up.

Creating a development area

Make the playpen
bash$ cd /somewhere/writable
bash$ glastpack.pl create myDir
What this does for you is to make a file called CMTPATH in this directory. This way you can switch from one working area to another, using the glastpack.pl login and glastpack.pl logout commands to point to the correct one of these files at any given time.
Start using it
bash$ cd myDir; glastpack.pl login
(In more detail, glastpack.pl makes a soft link in your home directory, .cmtrc, to the correct CMTPATH file.)
Modify CMTPATH if necessary (otherwise only thing in CMTPATH will be the new playpen).
bash$ glastpack.pl add /path/to/somewhere
bash$ glastpack.pl remove /path/unwanted
Check out a package and everything it depends on
bash$ glastpack.pl rco topPackage version
For development one may specify HEAD for the version. As always, the latest matching tagged version of subsidiary packages will be checked. If any of these packages are also to be developed, you'll want the HEAD. You can get it by issuing the right type of cvs update, one that says to forget about sticky tags:
bash$ cd devPack/version
bash$ cvs update -A
Stop using an area
bash$ glastpack.pl logout

Caution

The logout command breaks the connection between .cmtrc in your home directory and the CMTPATH for the area. By default CMT uses .cmtrc in your home directory, if there is one, for the CMTPATH definition. If you don't issue a logout, future CMT commands will continue to use the area's CMTPATH, even if you logged off the computer and then logged back in.

Getting ready to use a previously-created area

Typically you only need to go through the above steps once for each tree of packages you want to work with. (One exception is the cvs update command to replace a tagged version of a package with the HEAD, something you might want to do at any time.) If you have already gone through the above steps in some previous login (i.e., computer login), all you need to do to pick up in a new session is issue the glastpack login again:

bash$ cd /somewhere/writable/myDir; glastpack.pl login

Using the area

Typical things to do will be to build a package (and packages it depends on if binaries are out of date) or run a test program

Building
bash$ glastpack.pl build aPackage dirTagVersion
Here dirTagVersion is the string appearing as part of the path to the package. For tagged packages this string will just be the tag. A package in development (HEAD version) still will have some tag-like string as part of its path; this is what you use. For example,
bash$ glastpack.pl build detModel v2r12
Running a program
bash$ glastpack.pl run packageName version app
bash$ glastpack.pl run detModel v2r12 test.exe

glastpack and gdb

Normally glastpack defines necessary environment variables only when you issue a command such as glastpack.pl build.. or glastpack.pl run... and only within the context of that command. As of August, 2002, there is no glastpack command to start up the debugger; at best such a thing would be awkward to use. Instead, one can start up the debugger as usual as long as necessary environment variables, including LD_LIBRARY_PATH, are defined. Just go to the cmt directory of the top package (e.g., Gleam) and, preferably from a bash shell, issue the setup command:

  bash$ source setup.sh

Now your process has all the requisite definitions. Child processes will inherit them, as long as you don't reset anything (LD_LIBRARY_PATH is the most likely and most harmful to reset) in your .cshrc or .bashrc. This is crucial since gdb started from your terminal session (or gdb started from emacs started from your terminal session) is a child process. I haven't tried it, but it should also be possible to start up ddd this way.

Obscure but useful gdb commands

A few gdb commands which I've never had occasion to use before can come in very handy when debugging a large complicated application with dynamically-loaded libraries like Gleam.

control-C control-C
This sequence issues SIGINT. Since our applications don't handle SIGINT, the default action is for the debugger handle it by stopping execution and bringing up the (gdb) prompt. You can then examine variables, set breakpoints, etc. This can be useful if you want to break in to set a breakpoint while the application is waiting for interactive input (e.g., request for next event) or if application execution seems to be going wild.
info sharedlibrary
shows you which shared libraries have been loaded. You can't set a breakpoint in a shared library until it's been loaded. (But gdb does keep track if you rerun the program. It will complain when you first restart the program that breakpoints in dynamically-loaded shareables can't be enabled, but will automatically reactivate them when the shareable is again loaded.)
directory path-specification
This command adds a new directory to the list which will be searched for source code. By default this list includes only the current directory and the path of the source when it was compiled. Usually this is good enough, but not if object files or the source they were compiled from has moved. In particular, the pre-compiled version of Gaudi9 available to public Linux machines at SLAC falls into this category. In order to help gdb find the source for GaudiKernel, for example, you can issue the following (as of August, 2002, for GaudiSys_v9r0p6).

(gdb) directory /afs/slac/g/glast/ground/releases/GaudiSys_v9r0p6/GaudiKernel/v11r0p2/src/Lib

For some unknown reason in this context gdb would not translate an environment variable; I could only make this work by typing out the full absolute path.

print var-name.method(..)
If name is a std::string gdb won't let you just print it. Here is what happens:
(gdb) print name
$1 {static npos = Cannot access memory at address 0x0
However you can examine non-static fields or call non-static methods:
(gdb) print name.c_str()
$2 = 0x83b4fc8 "EventCnvSvc"

Created: 14 June 2002  J. Bogart
Last modified: 02 December 2002 11:40 -0800