This file documents known incompatibilities between Linux and Solaris dtrace,
together with the difficulty of overcoming them, and the likelihood that they
will be overcome.


Missing providers
-----------------
Difficulty: Medium
Likelihood: High

Some providers are missing.



No traceback for local functions or stripped executables
--------------------------------------------------------
Difficulty: Medium
Likelihood: Medium

However, even when ustack() is fixed, the userspace traceback will not be up to
the standards you may expect from Solaris, because Linux has no analogue of the
Solaris local dynamic symbol table, so static symbols and those hidden via
-fvisibility=hidden will not be named in the traceback.  In particular the pid
provider will be negatively impacted.

There are two options to fix this: firstly, we could use DWARF to look up the
symbols, as gdb does: alternatively, we could implement a local dynamic symbol
table, and alter the compiler to handle it.  The former solution provides
theoretically complete compatibility with existing binaries, but has the problem
that DWARF debugging info is so voluminous that it would make dtrace terribly
slow and memory-hungry (as slow and memory-hungry as gdb is when tracing a large
program).  Worse yet, because DWARF debugging info is so large, it is rarely
installed, so the output would be incomplete anyway.

So this may instead need to be fixed by introducing support for .SUNW_ldynsym in
the Oracle Enterprise Linux toolchain.  Binaries compiled with other toolchains
won't get full tracebacks, but we can live with that.


No projects, zones, tasks, contracts, or message queues
-------------------------------------------------------
Difficulty: High
Likelihood: Low (unless kernel support is added)

The Linux kernel does not implement projects, zones, tasks, contracts, or
message queues: all corresponding identifiers are gone, and the msgdsize() and
msgsize() subroutines no longer work.  (It would be possible to keep them but
mark them reserved, but the result would be the same: D scripts that use these
identifiers would fail to compile, or fail to work as expected.)


Kernel probe names differ
-------------------------
Difficulty: Very high
Likelihood: Nil

Kernel probe names largely differ between Solaris and Linux. This is no
different from other dtrace platforms, for the same reason, and is just as
unlikely to be fixed. The kernels are different, with differently-named
functions in, the probe names are derived from the names of the functions, thus
the probes are different.


-Xs semantics differ
--------------------
Difficulty: High
Likelihood: Nil

GNU cpp does not implement the various conformance levels supported by Solaris
cpp: instead, you in practice have a choice between a traditional cpp and a
fully standards-conformant one with __STDC__=1. The other variants (with
__STDC__=0 but ISO C rules, and turning various header K&R compatibility
extensions off and on) only exist because of Solaris's commitment to backward-
compatibility-to-a-fault in the C library headers. glibc does not have this
commitment, so most of these options make no sense.

In Linux dtrace, -Xa, -Xc and -Xt all set __STDC__=1; -Xs unsets it and sets
-traditional.


Library differences
-------------------
Difficulty: Very high
Likelihood: Nil

For consumers of libdtrace, <dtrace.h> has various differences.  These reflect
intrinsic Solaris/Linux differences which will not be fixed.

Currently:

dtrace_objinfo.dto_flags has lost the DTRACE_OBJ_F_PRIMARY value: the Linux
kernel has no concept of 'primary modules'.  As a consequence, the 'primary'
linkmode option is gone.  dtrace_objinfo.dto_file for a kernel module will
be the null string before that module is loaded, and may be the null string
afterwards if the module's CTF was loaded from the CTF archive.

Because modules in the Linux kernel may have many discontiguous regions of text
and data interspersed with other modules, dtrace_objinfo no longer has
dto_text_va, dto_data_va, dto_bss_va or the corresponding _size members;
instead, dto_text_addrs and dto_data_addrs and corresponding _size members
provide access to sorted arrays of dtrace_addr_range_t structures representing
all text and data ranges in the object: these arrays are freed at
dt_module_destroy() time.  A new function dtrace_addr_range_cmp() permits
bsearch()ing of these arrays.  (We no longer distinguish between initialized
data and bss sections.)

The dtrace_syminfo_t type populated by dtrace_lookup_by_name() and
dtrace_lookup_by_addr() no longer guarantees population of its id member:
for kernel symbols, it will always be zero.  In future a further API change may
require the caller to free the name member: this will be signalled by its no
longer being declared const.

The GElf_Sym parameter populated by dtrace_lookup_by_name() and
dtrace_lookup_by_addr() no longer guarantees population of its st_name or
st_other fields, and the only thing guaranteed about st_shndx is SHN_UNDEF
versus !SHN_UNDEF (there is no guarantee that it will correspond to an actual
ELF section).  If you want the symbol name, you should use the
dtrace_syminfo.name instead.  There is no guaranteed replacement for
st_other.

dtrace_update() now returns an error value, like dtrace_go() and dtrace_stop().

dtrace_proc_grab() has been renamed to dtrace_proc_grab_pid() to leave room
for future grabbing functions that may grab entities not identifiable by PID.

dtrace_proc_create() has grown a flags parameter.  Allowable values:

 - DTRACE_PROC_WAITING, indicating that a dtrace_proc_continue() should
   automatically be performed before returning.  This provides an analogue of
   the nomonitor parameter to dtrace_proc_grab(), which has itself transformed
   into a similar flags parameter.  (Unlike on Solaris libproc, all monitored
   processes have an associated monitor thread: this parameter minimizes the
   effect of this change, leading to an immediately running process similar to
   an unmonitored process on Solaris.)

 - DTRACE_PROC_SHORTLIVED, indicating that this process is not expected to be
   traced for long.  DTrace may respond by avoiding creation of a monitor
   thread, by aggressively aging the process out of any caches, etc.

The handle taken by the dtrace_proc_*() functions is now an opaque dtrace_proc
structure, not a ps_prochandle_t.  There is a new function to get the PID from
this structure.  The structure is owned by the caller and must be freed via a
call to dtrace_proc_release() before dtrace_close() to avoid a memory leak.

The creation functions have been renamed to gain a _pid() on the end of their
name, to ensure that previous users are rebuilt.  The creation functions return
the PID: failure is indicated by a negative return, following the usual
convention.

'struct dtrace_stmtdesc' has a new padding word, to work around GCC bug 36043,
which otherwise causes spurious reads off the end of this structure, which could
potentially cause DTrace to dump core if one of these structures wound up at the
end of a page at the end of a malloc() arena.  When this bug is fixed, this
padding will disappear.

All references to the type 'processor_t' are gone: this was Solaris-specific
anyway and all the structure fields that were declared of that type actually
always held CPU numbers.  To further signify this change, and better describe its
purpose, the dtv_status member of struct dtrace_vector is now named
dtv_cpu_status: it should return -1 if the requested CPU is not online, and
zero otherwise.  (This is what the code expected in any case.)


There is a new dtrace_debug_set_dump_sig() function, which sets the signal (by
default SIGUSR1); when DTRACE_DEBUG=signal is set in the environment at startup,
debugging output then goes into a ring buffer which is dumped to stderr when
this signal is sent.  If set to 0, this debugging facility is disabled.  (The
buffer is also dumped on dtrace_close() and on disconnection from traced
processes.)

The ring buffer is 100Mb long, by default: the optional DTRACE_DEBUG_BUF_SIZE
environment variable gives a new size, in Mb.

There is a new constant string exported, _libdtrace_vcs_version.  This contains
a string identifying the version of the built copy of libdtrace in the
development version control system: we do not define its format beyond that.


Incompatible behaviour for specific probes
------------------------------------------
proc:::signal-discard
	If a signal that is sent as event notification for a POSIX timer
	expiration should be discarded, no signal-discard probe is fired.
	The reason for this behaviour is that SDT probes do not work in
	IRQ context.
