Probing locations with no symbols

From OC Systems Wiki!
Revision as of 23:14, 18 December 2017 by Swn (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

In general, you will use the Apc compiler to compile probes written in APC which use probe points that name symbols in your program, like:

 probe thread
 {
    probe "my function"
    {
        ...
    }
 }

The symbols from your application and shared libraries will be entered in the Aprobe symbol table. In some cases Aprobe will filter out symbols either because they are not interesting or because probing them would be dangerous. Sometimes the symbols will be entered in the symbols table but they will be blocked from probing.

Disabling symbol filtering

On Linux you can disable symbol filtering by setting APROBE_DO_NOT_FILTER=true. This will put all symbols in the table and you are at your own risk when probing.

Adding a symbol

If you know a symbol address you can use the Aprobe API to add a symbol dynamically, which you can then probe using a call patch.

Use the following to define the symbol:

/* 
 * Create a new symbol ID within the module.  If FileName is ap_ExternSymbol
 * the function symbol is global, otherwise it is local.  If ModuleChecksum
 * is non-zero then this is compared with the module checksum and the
 * symbol is only added if the checksums match.  ap_NoSymbolId is
 * returned if the symbol cannot be created.  This can only be called
 * up to the completion of the probe program on_entry clause.  
 */ 
extern ap_SymbolIdT ap_RecordDynamicFunctionSymbol (
   ap_ModuleIdT ModuleId,
   ap_NameT     FunctionName,
   ap_NameT     FileName,
   ap_OffsetT   OffsetInModule,
   ap_SizeT     Size,
   ap_Uint32    ModuleChecksum);

Here is an example of defining a symbol:

probe program
{
   on_entry
   {
      ap_SymbolIdT Symbol =
         ap_RecordDynamicFunctionSymbol(
            ap_ApplicationModuleId(),
            "MyFunctionName",
            "myfile.c",
            0x1234,
            0x30,
            ap_GetModuleChecksum(ap_ApplicationModuleId());
    }
}
                                                                 


Create a call patch using the following:

typedef ap_Uint32 (*ap_CallPatchSubprogramT)
   (ap_ExecutionContextPtrT, ap_PatchIdT);   
/* 
   Creates a call patch and attaches it to the target memory location. 
   Returns a unique PatchId if successful, ap_NoPatchId otherwise. Note that
   the patch ID returned is the raw patch ID but the call patch ID will be
   passed to the patch subprogram.  
*/

extern ap_PatchIdT ap_CreateCallPatch (
   ap_AddressT,              /* Text section address that has to be patched. */
   ap_CallPatchSubprogramT); /* Subprogram to patch in a call for. */

Here is an example call patch

static ap_Uint32 CallPatchSubprogram
                    (ap_ExecutionContextPtrT ap_ExecutionContextPtr,
                     ap_PatchIdT             ap_PatchId)
{ 
   // do patch actions
}
probe program 
{
   on_entry
   {
         // Either get the address of a symbol or use an absolute address for a link map.
         ap_Address Address = ap_SymbolAddress(MySymbolId);
         ap_PatchId  PatchId;
         PatchId =
            ap_CreateCallPatch(
               Address,
               CallPatchSubprogram);
         if (ap_IsNoPatchId(PatchID))
         {
              ....
         }
   }
}

See aprobe.h for more information or contact OCS support.