2016-05-04 12 views
0

Ich möchte Stacks von C für Node.js programmgesteuert verfolgen (JS-Adressen beiseite).Dtrace von C liefert nicht das gleiche Profiling-Ergebnis im Vergleich zur Befehlszeile

Der folgende Befehl gibt mir Stapel mit aufgelösten c++ Symbolen.

Der folgende C-Code gibt nur Adressen für Nodes C/C++ - Code zurück. Was wäre das Äquivalent?

#include <dtrace.h> 
#include <signal.h> 
#include <stdio.h> 

struct ps_prochandle *g_pr; 
static dtrace_hdl_t* g_dtp; 

static int chewrec (const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg) { 
    // A NULL rec indicates that we've processed the last record. 
    if (rec == NULL) { 
     return (DTRACE_CONSUME_NEXT); 
    } 
    return (DTRACE_CONSUME_THIS); 
} 

static const char* g_prog = 
    "#pragma D option switchrate=1000hz\n" 
    "profile-1ms /pid == 13221/ {\n" 
    "ustack();\n" 
    "}"; 

static int g_intr; 
static int g_exited; 

static void intr (int signo) { 
    g_intr = 1; 
} 


int main (int argc, char** argv) { 
    int err; 

    if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) { 
     fprintf(stderr, "failed to initialize dtrace: %s\n", dtrace_errmsg(NULL, err)); 
     return -1; 
    } 
    printf("Dtrace initialized\n"); 

    (void) dtrace_setopt(g_dtp, "bufsize", "4m"); 
    (void) dtrace_setopt(g_dtp, "aggsize", "4m"); 

    printf("dtrace options set\n"); 

    dtrace_prog_t* prog; 
    if ((prog = dtrace_program_strcompile(g_dtp, g_prog, DTRACE_PROBESPEC_NAME, DTRACE_C_CPP, 0, NULL)) == NULL) { 
     fprintf(stderr, "failed to compile dtrace program\n"); 
     return -1; 
    } else { 
     printf("dtrace program compiled\n"); 
    } 

    dtrace_proginfo_t info; 
    if (dtrace_program_exec(g_dtp, prog, &info) == -1) { 
     fprintf(stderr, "failed to enable dtrace probes\n"); 
     return -1; 
    } else { 
     printf("dtrace probes enabled\n"); 
    } 

    struct sigaction act; 
    (void) sigemptyset(&act.sa_mask); 
    act.sa_flags = 0; 
    act.sa_handler = intr; 
    (void) sigaction(SIGINT, &act, NULL); 
    (void) sigaction(SIGTERM, &act, NULL); 

    if (dtrace_go(g_dtp) != 0) { 
     fprintf(stderr, "could not start instrumentation\n"); 
     return -1; 
    } else { 
     printf("instrumentation started ..\n"); 
    } 

    int done = 0; 
    do { 
     if (!g_intr && !done) { 
     dtrace_sleep(g_dtp); 
     } 

     if (done || g_intr || g_exited) { 
     done = 1; 
     if (dtrace_stop(g_dtp) == -1) { 
      fprintf(stderr, "could not stop tracing\n"); 
      return -1; 
     } 
     } 

     switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) { 
     case DTRACE_WORKSTATUS_DONE: 
      done = 1; 
      break; 
     case DTRACE_WORKSTATUS_OKAY: 
      break; 
     default: 
      fprintf(stderr, "processing aborted"); 
      return -1; 
     } 
    } while (!done); 

    printf("closing dtrace\n"); 
    dtrace_close(g_dtp); 

    return 0; 
} 
+0

Es gibt ein Ding namens [Ustack Helfer] (https://www.joyent.com/blog/understanding-dtrace-ustack-helpers) Das sollte Ihnen helfen, eine Aufgabe zu erreichen, aber Sie müssen 'jstack()' anstelle von 'ustack()' aus Ihrem Code aufrufen. – myaut

+0

@myaut Es ist ein wenig komplizierter als das, aber trotzdem danke. Ich postete dies a vorhin auf der Dtrace-Mailingliste, mit der folgenden Antwort, die auch Ihre Komponente hat – eljefedelrodeodeljefe

Antwort

1

Von der dtrace-Mailing-Liste, Robert Mustacchi:

TL; DR resolve Symbole sich in Userland.

„Also, alle die Symbolauflösungsverarbeitung wird immer im Benutzer Land getan. In anderen Worten, DTrace im Kernel immer nur Adressen wie sammelt man für die Fälle sind zu sehen, wo Sie verwenden ustack und nicht ein Ustack Handler über die Jstack() Aktion (jstack() gibt auch nur Symbole für nicht-native Rahmen). Beachten Sie, dass Sie wollen, wenn Sie die JavaScript-spezifischen Symbole zusätzlich zu den nativen sehen möchten Verwenden Sie jstack() in Ihren Beispielen und nicht ustack().

Die Art, wie Sie diese durchführen können Die Zuordnungen ändern sich abhängig von , auf welchem ​​System Sie arbeiten. Wenn Sie sich ansehen, was DTrace auf illumos für das Drucken der Ergebnisse von ustack() (http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libdtrace/common/dt_consume.c#1320), tut, dann sehen Sie, dass es libproc und die Plookup_by_addr() -Funktion verwendet, um die Übersetzung durchzuführen. Obwohl es sich lohnt, darauf hinzuweisen, dass weder stabile Schnittstellen sind, obwohl sie sich selten ändern. "