Skip to content

Instantly share code, notes, and snippets.

@jverkoey
Created July 10, 2015 20:51
Show Gist options
  • Save jverkoey/b0fc07a089b3048e0b9b to your computer and use it in GitHub Desktop.
Save jverkoey/b0fc07a089b3048e0b9b to your computer and use it in GitHub Desktop.
DTSendSignalFlag
// As seen here http://www.freelancemadscience.com/fmslabs_blog/2012/9/18/advanced-profiling-with-the-dtperformancesession-framework.html
// and here: http://stackoverflow.com/questions/20269630/xcode-instruments-trace-comparison
// This was sadly broken in iOS 7 and flags no longer show up in Instruments. Any ideas?
#define DT_KEY_USERID "DT_KEY_USERID"
#define DT_KEY_SOURCE "DT_KEY_SOURCE"
#define DT_KEY_BACKTRACE "DT_KEY_BACKTRACE"
#define DT_KEY_TIMESEC "DT_KEY_TIMESEC"
#define DT_KEY_TIMENSEC "DT_KEY_TIMENSEC"
#define DT_KEY_THREADID "DT_KEY_THREADID"
#define DT_KEY_DT_SIGNAL "DT_KEY_DT_SIGNAL"
//ASL-based signal flag
#define DT_ASL_SIGNAL_VALUE "1095985511"
#define DT_POINT_SIGNAL "DT_POINT_SIGNAL"
#define DT_START_SIGNAL "DT_START_SIGNAL"
#define DT_END_SIGNAL "DT_END_SIGNAL"
#include <unistd.h>
#include <mach/mach_init.h>
#include <mach/mach_time.h>
#include <string.h>
#include <libgen.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <execinfo.h>
#include <stdio.h>
#include <mach/mach_port.h>
#include <mach/port.h>
#include <mach/task.h>
#include <asl.h>
#include <sys/time.h>
void DTSendSignalFlag(char *useridstr, char *signalstr, BOOL add_backtrace) {
struct timeval tp = {
0L, 0
};
long timesec = 0L;
int32_t timensec = 0;
int todstat = gettimeofday( & tp, NULL), btct = 0L;
unsigned int lineno = __LINE__;
unsigned long long btrace[65], b = 0ULL;
size_t ulen = strlen(useridstr);
mach_port_t tthid = mach_thread_self();
if (MACH_PORT_VALID(tthid)) {
mach_port_deallocate(mach_task_self(), tthid);
}
if (add_backtrace) {
btct = backtrace((void * * ) & btrace, 64);
}
if (ulen) {
char * aslID = (char * ) calloc(32 + ulen, sizeof(char));
if (aslID) {
aslclient tracerhdl;
const char * aslFAC = signalstr;
char thstr[24];
char timestr[24];
snprintf(aslID, 32 + ulen, "%s.%llx", useridstr, (unsigned long long) tthid);
tracerhdl = asl_open(aslID, aslFAC, ASL_OPT_NO_DELAY);
if (tracerhdl) {
char * dttbtstr = NULL;
const char * filename = basename((char * ) __FILE__);
const char * funcname = (char * ) __PRETTY_FUNCTION__;
char * sourcestr = NULL;
size_t blen = 0, filen = 0, fulen = 0;
aslmsg tracermsg = asl_new(ASL_TYPE_MSG);
if (tracermsg) {
if (0 == todstat) {
timesec = tp.tv_sec;
timensec = tp.tv_usec * 1000;
snprintf(timestr, 22, "0x%lx", timesec);
asl_set(tracermsg, DT_KEY_TIMESEC, timestr);
snprintf(timestr, 22, "0x%x", timensec);
asl_set(tracermsg, DT_KEY_TIMENSEC, timestr);
}
asl_set(tracermsg, DT_KEY_USERID, useridstr);
char * uidStr = NULL;
if (asprintf( & uidStr, "%d", (int) getuid()) != -1) {
asl_set(tracermsg, ASL_KEY_READ_UID, uidStr);
free(uidStr);
}
asl_set(tracermsg, ASL_KEY_LEVEL, ASL_STRING_NOTICE);
asl_set(tracermsg, ASL_KEY_FACILITY, aslFAC);
snprintf(thstr, 22, "0x%llx", (unsigned long long) tthid);
asl_set(tracermsg, DT_KEY_THREADID, thstr);
filen = strlen(filename) + 16;
fulen = strlen(funcname);
blen = filen + fulen;
sourcestr = (char * ) calloc(blen, sizeof(char));
if (sourcestr) {
snprintf(sourcestr, blen, "%s:%u, %s", filename, lineno, funcname);
asl_set(tracermsg, DT_KEY_SOURCE, sourcestr);
}
if (btct > 0) {
size_t btct_u = (size_t) btct;
blen = (btct_u * 16) + btct_u * 3;
dttbtstr = (char * ) calloc(blen, sizeof(char));
if (dttbtstr) {
char framestr[32];
for (b = 0; b < btct_u; b++) {
snprintf(framestr, 22, "0x%llx%c", btrace[b], (b < btct_u - 1) ? ',' : '\0');
strncat(dttbtstr, framestr, strlen(framestr));
}
asl_set(tracermsg, DT_KEY_BACKTRACE, dttbtstr);
}
}
asl_set(tracermsg, DT_KEY_DT_SIGNAL, DT_ASL_SIGNAL_VALUE);
asl_log(tracerhdl, tracermsg, ASL_LEVEL_NOTICE, "*** %lx.%x:%s:%s\n%s\n", timesec, (uint32_t) timensec, signalstr, sourcestr, (btct) ? dttbtstr : "<no backtrace>");
asl_free(tracermsg);
asl_close(tracerhdl);
if (dttbtstr) free(dttbtstr);
if (sourcestr) free(sourcestr);
}
}
if (aslID) free(aslID);
}
}
}
// Signal
DTSendSignalFlag("identifier", DT_POINT_SIGNAL, TRUE);
// Measure between a range.
DTSendSignalFlag("identifier", DT_START_SIGNAL, TRUE);
DTSendSignalFlag("identifier", DT_END_SIGNAL, TRUE);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment