Пример #1
0
static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
  int n = 0, i = 0;

  // add threads
  n = get_num_threads(ph);
  for (i = 0; i < n; i++) {
    jobject thread;
    jobject threadList;
    lwpid_t lwpid;

    lwpid = get_lwp_id(ph, i);
    thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,
                                      (jlong)lwpid);
    CHECK_EXCEPTION;
    threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);
    CHECK_EXCEPTION;
    (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);
    CHECK_EXCEPTION;
  }

  // add load objects
  n = get_num_libs(ph);
  for (i = 0; i < n; i++) {
     uintptr_t base;
     const char* name;
     jobject loadObject;
     jobject loadObjectList;

     base = get_lib_base(ph, i);
     name = get_lib_name(ph, i);
     loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
                                   (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
     CHECK_EXCEPTION;
     loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
     CHECK_EXCEPTION;
     (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
     CHECK_EXCEPTION;
  }
}
Пример #2
0
/* Parses gdb's stdout fd after requesting a backtrace. The result is stored
in a linked list of FuncInfo structures.  */
static List *
parse_stack_trace (int gdb) {
    int i;
    int parentheses_are_off = 0;
    char c;
    char buf[4096];
    List *stack = NULL;
    FuncInfo *f;
    List *libs = NULL;
    SharedLib *lib;
    
    enum {
        NONE,
        ADDR,
        FUNC,
        ARGS,
        FILE,
        LINE,
        LIB,
        QUOTE,
        FROMADDR,
        TOADDR,
        SYMS,
        SONAME
    } state = NONE, prev_state = NONE;
    
    while (read(gdb, &c, 1)) {
        switch (state) {
        case NONE:
            if (c == '#') {
                f = calloc(sizeof (FuncInfo), 1);
                while (read(gdb, &c, 1))
                    if (!isdigit(c))
                        break;
                while (read(gdb, &c, 1))
                    if (!isspace(c)) {
                        buf[0] = c;
                        i = 1;
                        state = isdigit(c) ? ADDR : FUNC;
                        break;
                    }
            }
            else if (!stack && c == '0') {
                lib = calloc(sizeof (SharedLib), 1);
                state = FROMADDR;
                buf[0] = c;
                i = 1;
            }
            else if (stack && c == '(') {
                read(gdb, buf, 3);
                if (!strncmp(buf, "gdb", 3))
                    goto done;
            }
            else if (!stack && c == 'N') {
                read(gdb, buf, 7);
                if (!strncmp(buf, "o stack", 7))
                    goto done;
            }
            break;
        case FROMADDR:
            if (!isspace(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                sscanf(buf, "%p", &lib->from);
                read(gdb, buf, 1);
                state = TOADDR;
            }
            break;
        case TOADDR:
            if (!isspace(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                sscanf(buf, "%p", &lib->to);
                read(gdb, buf, 1);
                state = SYMS;
            }
            break;
        case SYMS:
            if (!isspace(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                if (eq(buf, "Yes"))
                    lib->readsyms = 1;
                read(gdb, buf, 3);
                if (strncmp(buf, "(*)", 3))
                    lib->dbinfo = 1;
                while (read(gdb, &c, 1))
                    if (!isspace(c)) {
                        buf[0] = c;
                        i = 1;
                        break;
                    }
                state = SONAME;
            }
            break;
        case SONAME:
            if (c != '\n') {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                lib->name = strdup(buf);
                libs = list_push(libs, lib);
                state = NONE;
            }
            break;
        case ADDR:
            if (!isspace(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                sscanf(buf, "%p", &f->addr);
                f->lib = get_lib_name(libs, f->addr);
                read(gdb, buf, 3);
                state = FUNC;
            }
            break;
        case FUNC:
            if (!isspace(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                f->func = strdup(buf);
                state = ARGS;
            }
            break;
        case ARGS:
            buf[i++] = c;
            if (c == '(')
                parentheses_are_off++;
            else if (c == ')') {
                parentheses_are_off--;
                if (parentheses_are_off)
                    continue;
                buf[i] = 0;
                i = 0;
                f->args = strdup(buf);
                read(gdb, &c, 1);
                if (c == '\n') {
                    stack = list_push(stack, f);
                    state = NONE;
                    break;
                }
                read(gdb, buf, 3);
                if (!strncmp(buf, "at ", 3)) {
                    state = FILE;
                }
                else if (!strncmp(buf, "fro", 3)) {
                    state = LIB;
                    read(gdb, buf, 2);
                }
                else {
                    free(f);
                    state = NONE;
                }
            }
            else if (c == '"') {
                prev_state = ARGS;
                state = QUOTE;
            }
            break;
        case QUOTE:
            buf[i++] = c;
            if (c == '\\') {
                read(gdb, &c, 1);
                buf[i++] = c;
            }
            else if (c == '"')
                state = prev_state;
            break;
        case LIB:
            if (!isspace(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                if (!f->lib)
                    f->lib = strdup(buf);
                stack = list_push(stack, f);
                state = NONE;
            }
            break;
        case FILE:
            if (c != ':') {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                f->file = strdup(buf);
                state = LINE;
            }
            break;
        case LINE:
            if (isdigit(c)) {
                buf[i++] = c;
            }
            else {
                buf[i] = 0;
                i = 0;
                f->line = atoi(buf);
                stack = list_push(stack, f);
                state = NONE;
            }
            break;
        }
    }
    
    done:
    list_free(libs, shared_lib_free);
    return stack;
}