};
-#define PREFIX_BUF_SIZE (PREFIX_MAX_FUNC_NAME * MAX_BT_FUNC)
-
class StringPrefixes {
private:
std::set<pstring> pset;
- char* buf;
-private:
+
void addPrefix(char* startbuf, int n) {
std::set<pstring>::iterator elem = pset.find(pstring(startbuf, n));
bool replace = elem != pset.end() && n < elem->n;
}
}
public:
- StringPrefixes(const char* source);
+ StringPrefixes();
bool contain(const char* s) {
- if (pset.find(pstring(s, strlen(s) + 1)) != pset.end()) {
- os::log("Backtrace for %s is enabled", s);
- return true;
- }
- return false;
+ return pset.find(pstring(s, strlen(s) + 1)) != pset.end();
}
};
+StringPrefixes::StringPrefixes() {
+ char *list = getenv("APITRACE_BACKTRACE");
+ if (!list)
+ return;
+ for (char *t = strdup(list); ; t = NULL) {
+ char *tok = strtok(t, " \t\r\n");
+ if (!tok)
+ break;
+ if (tok[0] == '#')
+ continue;
+ if (tok[strlen(tok) - 1] == '*')
+ addPrefix(tok, strlen(tok) - 1);
+ else
+ addPrefix(tok, strlen(tok) + 1);
+ }
+}
+
+
bool backtrace_is_needed(const char* fname) {
- static StringPrefixes backtraceFunctionNamePrefixes(APITRACE_FNAMES_SOURCE);
+ static StringPrefixes backtraceFunctionNamePrefixes;
return backtraceFunctionNamePrefixes.contain(fname);
}
namespace trace {
-StringPrefixes::StringPrefixes(const char* source) {
- buf = (char*)malloc(sizeof(char) * PREFIX_BUF_SIZE);
- char* startbuf = buf;
- int n = 0;
- FILE* f = fopen(source, "r");
- if (f == NULL) {
- os::log("Cannot open " APITRACE_FNAMES_FILE);
- }
- while ((startbuf = fgets(startbuf, PREFIX_MAX_FUNC_NAME, f))) {
- n = strlen(startbuf);
- if (startbuf[n - 1] == '\n') {
- n--;
- }
- if (n > 2 && startbuf[0] != '#') {
- int psize;
- if (startbuf[n - 1] != '*') {
- startbuf[n] = '\0';
- psize = n + 1;
- }
- else {
- psize = n - 1;
- }
- addPrefix(startbuf, psize);
- startbuf += n + 1;
- n = 0;
- }
- }
- fclose(f);
-}
-
-
/* The following two declarations are copied from Android sources */
enum DebugTargetKind {
size_t bufSize;
void (*dumpBacktrace)(const DebugOutputTarget*, void*);
DebugOutputTarget debugTarget;
+ Id nextFrameId;
public:
DalvikBacktraceProvider() {
+ nextFrameId = 0;
FILE* (*open_memstream_exp)(char**, size_t*);
void (*createDebugTarget)(DebugOutputTarget*, FILE*);
void* handle = dlopen("/system/lib/libdvm.so", 0);
char* rawBacktrace_it = rawBacktrace;
while (*rawBacktrace_it != '\0') {
RawStackFrame stackFrame;
+ // TODO: Keep a cache of stack frames
+ stackFrame.id = nextFrameId++;
/* skip leading space */
while (*rawBacktrace_it == ' ') {
rawBacktrace_it++;
rawBacktrace_it++;
}
if (*rawBacktrace_it == ':') {
- stackFrame.linenumber = rawBacktrace_it + 1;
+ const char *linenumber = rawBacktrace_it + 1;
*rawBacktrace_it = '\0';
while (*rawBacktrace_it != ')') {
rawBacktrace_it++;
}
*rawBacktrace_it = '\0';
rawBacktrace_it++;
+ stackFrame.linenumber = atoi(linenumber);
}
else {
stackFrame.filename = NULL;
namespace trace {
-StringPrefixes::StringPrefixes(const char* source) {
- buf = (char*)malloc(sizeof(char) * PREFIX_BUF_SIZE);
- char* startbuf = buf;
- int n = 0;
- char* s = getenv(source);
- char end = ';';
- if (s == NULL) {
- return;
- }
- *buf = ';';
- strncpy(buf + 1, s, PREFIX_BUF_SIZE - 2);
- while (end != '\0') {
- startbuf++;
- while (*(startbuf + n) != ';' && *(startbuf + n) != '\0') {
- n++;
- }
- end = startbuf[n];
- if (n > 2 && startbuf[0] != '#') {
- int psize;
- if (startbuf[n - 1] != '*') {
- startbuf[n] = '\0';
- psize = n + 1;
- }
- else {
- psize = n - 1;
- }
- addPrefix(startbuf, psize);
- startbuf += n;
- n = 0;
- }
- }
-}
#define BT_DEPTH 10
* functions on the stack to avoid recording these frames.
*/
int numOfNestedFunctions;
+ Id nextFrameId;
private:
/*
* Parse a stack frame, expecting:
char* frame_symbol_copy = new char[strlen(frame_symbol) + 1];
strcpy(frame_symbol_copy, frame_symbol);
RawStackFrame* parsedFrame = new RawStackFrame;
+ parsedFrame->id = nextFrameId++;
char* frame_it = frame_symbol_copy;
parsedFrame->module = frame_it;
+ char* offset = NULL;
while (true) {
switch (*frame_it) {
case '(':
case '[':
*frame_it = '\0';
frame_it++;
- parsedFrame->offset = frame_it;
+ offset = frame_it;
break;
case ']':
*frame_it = '\0';
+ sscanf(offset, "%llx", &parsedFrame->offset);
cache[frame] = parsedFrame;
return parsedFrame;
case '\0':
}
public:
GlibcBacktraceProvider() :
- numOfNestedFunctions(0) {
- }
+ numOfNestedFunctions(0),
+ nextFrameId(0)
+ {}
+
std::vector<RawStackFrame> getParsedBacktrace() {
std::vector<RawStackFrame> parsedBacktrace;
void *array[numOfNestedFunctions + BT_DEPTH];