Skip to content

Low level Tools for ccore modules

Gary Pavlis edited this page Jan 11, 2021 · 3 revisions

Low-level Tools for ccore Modules

Much of the material here can be found on various discussion on the web, but it is useful to preserve it here to reduce searching. Some of the lower level components of MsPASS are constructed from C++ code that is exposed to python through the package called pybind11. With pybind11 and the right compiler one can build MsPASS from source code using the setup.py file found at the top-level of the package. For the record a typical usage would be:

pip install --user ./   # run from directory where setup.py is located

pip compiles and constructs a set of dynamic libraries (shared objects = .so files in linux) that are loadable in python with an import statement. e.g. in MsPASS a common construct is:

from mspasspy.ccore.seismic import TimeSeries

The mspasspy.ccore.seismic symbol, if you install python as above with --user, will be located in the following (unix) directory: ~/.local/lib/python3.8/site-packages/mspasspy/ccore (noting python3.8 may be different - is defines the version number of your python setup). In that directory you will see a file with a name like this: seismic.cpython-38-x86_64-linux-gnu.so. The gibberish after the word "seismic" is system dependent but "seismic" is the key combined with "mspass.ccore" to define a path that file.

We put all that background here to clarify that this particular module is a binary ".so" file produced by compiling a bunch of C++ code. For technical reasons C++ compilers universally use a process called "name mangling", which can make an error message very confusing. For example, here is an error encountered during development that is about as understandable directly as hieroglyphics.

In [1]: import mspasspy.ccore.algorithms.basic
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-0344a61501eb> in <module>
----> 1 import mspasspy.ccore.algorithms.basic

ImportError: /home/pavlis/.local/lib/python3.8/site-packages/mspasspy/ccore/algorithms/basic.cpython-38-x86_64-linux-gnu.so: undefined symbol: _ZN6mspass10algorithms11BundleGroupERKSt6vectorINS_7seismic10TimeSeriesESaIS3_EEmm

What, the rookie will ask, is what the heck is _ZN6mspass10algorithms11BundleGroupERKSt6vectorINS_7seismic10TimeSeriesESaIS3_EEmm? That is a type example of name mangling. How do we figure out what that symbol is?

There is a useful tool for this on most linux systems called c++filt. It is a standard unix "filter" so it reads from stdin. To find out what that weird symbol is we can run this from a unix shell like this:

echo _ZN6mspass10algorithms11BundleGroupERKSt6vectorINS_7seismic10TimeSeriesESaIS3_EEmm | c++filt

which will generate this output:

mspass::algorithms::BundleGroup(std::vector<mspass::seismic::TimeSeries, std::allocator<mspass::seismic::TimeSeries> > const&, unsigned long, unsigned long)

That general approach can help in sorting out problems in ccore functions by at least showing which function or class is causing a problem.

A couple related uses of c++filt on ccore module is in conjuction with two common linux tools for examining ".so" files or ".o" files. For the above example .so file the following work but will generate very large outputs that are data for helping sort out some kinds of low level library problems.

  1. The nm command:
nm basic.cpython-38-x86_64-linux-gnu.so | c++filt
  1. the objtool command:
objdump -t basic.cpython-38-x86_64-linux-gnu.so

Where in both cases above I shorted the path for the so file by using a cd to the directory where the so file is stored.