pmx
is a tool and library used to analyse processes and core files on Linux and Solaris.
OS (Compiler) | x86_64 | i686 |
---|---|---|
Linux (gcc/g++ 4.9.2) | ✅ | ✅ |
Solaris (gcc/g++ 4.9.2) | ✅ | ✅ |
Solaris (Oracle Studio) | ✖️ | ✅ |
- Extract stack trace from core file and live running process.
- Parse and print function arguments.
- Allow extension with a plugable shared library for user-defined complex data types.
- Features of
pstack
,pargs
,pmap
,pldd
on Solaris within one binary. - Work with corrupted stack when
gdb
fails to print stack trace. - Allow instrumentation of interested functions.
pmx
works with both core file or running process. To print the stack, run pmx -s core
on core file and pmx -s pid
on running process. The first thread stack will be printed.
It is equivalent to pmx -s core/1
or pmx -s pid/1
.
To see all thread, use the --all-threads
option.
pmx
assumes the process runs in current directory. To load dependent libraries from another
directory, use the -l
or --sysroot
option.
Full command options can be found from pmx -h
command output.
pmx
will parse and extract all primitive data types in C/C++. However, it's possible to
extend pmx
to parse composite data types and classes with an extenion shared library.
An extension should be define an TypePrinterEntry
array named type_printer_extension.
When pmx
starts, it'll find the libpmxext.so
library (configurable with -L
option) and
append the customized type printer to the supported type list. Refer to
test/lib/pmxext.cpp and the accompanying types_FOO.cpp
files for detail.
pmx
relies on the arguments to be passed onto stack. When code is compiled with
optimization, the compiler may optimize out arguments for efficiency. pmx
provides two macros
to instrument the function/method and save a copy of the arguments on the stack for easy argument
extraction.
To instrument a C or static C++ function, call the PMX_INSTRUMENT()
macro with all the argument
at the very first line of the function. Similarly, use PMX_INSTRUMENT_METHOD()
macro to instrument
C++ non-static methods.
#include "pmxsupport.h"
// Example of standard C function, or static C++ method. Up to 9 arguments are supported
static int foo(const char *a, int b, char *c, int d, const char *e)
{
PMX_INSTRUMENT(a, b, c, d, e);
// rest of function
}
//Example of a (non-static) C++ method. Up to 8 arguments are supported.
voi bar(void *a, int b, double c, char d)
{
// Note that 'this' is automatically added to the arguments by the macro, and can be analysed by pmx.
PMX_INSTRUMENT_METHOD(a, b, c, d);
// Rest of method
}
If you are interested in what the macro translates to, the instrumentation of bar()
would expand to:
void *vthis = this; // Syntactic work around as we can't dereference 'this' directly. No impact on compiled code.
volatile struct { // must be volatile so it isn't optimised away.
unsigned long start_tag;
void * pmx_vthis;
void *pmx_a;
int pmx_b;
double pmx_c;
char pmx_d;
unsigned long end_tag;
} mx_instrumentation =
{
0xCAFEF00D, // Magic number start tag
vthis,
a,
b,
c,
d,
0xFABABBA0 // Magic number end tag
};
Note instrumentation only works with gcc/g++ at the moment.
You will need autotools
to compile the project:
git clone git@github.com:murex/pmx.git
cd pmx
./autogen.sh
mkdir build
# change compiler as appropriate
../configure CC="g++492" CXX="g++492"
make
This will build pmx
binary, a test binary testpmx
which could generate a core file,
and a shared library plugin customized type printer defined in test/lib
diretory.
To test:
cd bin
./testpmx "hello pmx test"
# create a symbolic link to the shared library
ln -sf ../test/lib/.libs/libpmxext-0.1.so.0.0.1 libpmxext.so
./pmx -s core.xxx
pmx
and the accompanying materials are made available under the terms of the Eclipse
Public License v1.0 (here) which accompanies this ditribution, and is
available at http://www.eclipse.org/legal/epl-v10.html.
The master branch of this repository contains the latest stable changes. Pull requests should be submitted against the latest head of master. See here for contribution agreement and guidelines.