Beispiel #1
0
const char*
_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
                         PyThreadState *current_thread)
{
    PyThreadState *tstate;
    unsigned int nthreads;

    /* Get the current interpreter from the current thread */
    tstate = PyInterpreterState_ThreadHead(interp);
    if (tstate == NULL)
        return "unable to get the thread head state";

    /* Dump the traceback of each thread */
    tstate = PyInterpreterState_ThreadHead(interp);
    nthreads = 0;
    do
    {
        if (nthreads != 0)
            write(fd, "\n", 1);
        if (nthreads >= MAX_NTHREADS) {
            PUTS(fd, "...\n");
            break;
        }
        write_thread_id(fd, tstate, tstate == current_thread);
        dump_traceback(fd, tstate, 0);
        tstate = PyThreadState_Next(tstate);
        nthreads++;
    } while (tstate != NULL);

    return NULL;
}
Beispiel #2
0
int gdbr_step(libgdbr_t *g, int tid) {
	char thread_id[64];
	if (write_thread_id (thread_id, sizeof (thread_id) - 1, g->pid, tid,
			     g->stub_features.multiprocess) < 0) {
		return send_vcont (g, CMD_C_STEP, NULL);
	}
	return send_vcont (g, CMD_C_STEP, thread_id);
}
Beispiel #3
0
int gdbr_step(libgdbr_t *g, int tid) {
	char thread_id[64] = {0};
	if (tid <= 0 || write_thread_id (thread_id, sizeof (thread_id) - 1, g->pid, tid,
			     g->stub_features.multiprocess) < 0) {
		send_vcont (g, "vCont?", NULL);
		send_vcont (g, "Hc0", NULL);
		return send_vcont (g, CMD_C_STEP, NULL);
	}
	return send_vcont (g, CMD_C_STEP, thread_id);
}
Beispiel #4
0
int gdbr_continue(libgdbr_t *g, int pid, int tid, int sig) {
	char thread_id[64] = { 0 };
	char command[16] = { 0 };
	if (sig <= 0) {
		strncpy (command, CMD_C_CONT, sizeof (command) - 1);
	} else {
		snprintf (command, sizeof (command) - 1, "%s%02x", CMD_C_CONT_SIG, sig);
	}
	if (write_thread_id (thread_id, sizeof (thread_id) - 1, g->pid, tid,
			     g->stub_features.multiprocess) < 0) {
		return send_vcont (g, command, NULL);
	}
	return send_vcont (g, command, thread_id);
}
Beispiel #5
0
int gdbr_select(libgdbr_t *g, int pid, int tid) {
	char cmd[64] = { 0 };
	reg_cache.valid = false;
	g->pid = pid;
	g->tid = tid;
	strcpy (cmd, "Hg");
	if (write_thread_id (cmd + 2, sizeof (cmd) - 3, pid, tid,
			     g->stub_features.multiprocess) < 0) {
		return -1;
	}
	g->stop_reason.is_valid = false;
	if (send_msg (g, cmd) < 0 || read_packet (g, false) < 0 || send_ack (g) < 0) {
		return -1;
	}
	if (strcmp (g->data, "OK")) {
		return -1;
	}
	return 0;
}
Beispiel #6
0
bool gdbr_is_thread_dead (libgdbr_t *g, int pid, int tid) {
	if (!g) {
		return false;
	}
	if (g->stub_features.multiprocess && pid <= 0) {
		return false;
	}
	char msg[64] = { 0 }, thread_id[63] = { 0 };
	if (write_thread_id (thread_id, sizeof (thread_id) - 1, pid, tid,
			     g->stub_features.multiprocess) < 0) {
		return false;
	}
	if (snprintf (msg, sizeof (msg) - 1, "T%s", thread_id) < 0) {
		return false;
	}
	if (send_msg (g, msg) < 0 || read_packet (g) < 0 || send_ack (g) < 0) {
		return false;
	}
	if (g->data_len == 3 && g->data[0] == 'E') {
		return true;
	}
	return false;
}
Beispiel #7
0
/* Dump the traceback of all Python threads into fd. Use write() to write the
   traceback and retry if write() is interrupted by a signal (failed with
   EINTR), but don't call the Python signal handler.

   The caller is responsible to call PyErr_CheckSignals() to call Python signal
   handlers if signals were received. */
const char*
_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
                         PyThreadState *current_tstate)
{
    PyThreadState *tstate;
    unsigned int nthreads;

    if (current_tstate == NULL) {
        /* _Py_DumpTracebackThreads() is called from signal handlers by
           faulthandler.

           SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
           and are thus delivered to the thread that caused the fault. Get the
           Python thread state of the current thread.

           PyThreadState_Get() doesn't give the state of the thread that caused
           the fault if the thread released the GIL, and so this function
           cannot be used. Read the thread specific storage (TSS) instead: call
           PyGILState_GetThisThreadState(). */
        current_tstate = PyGILState_GetThisThreadState();
    }

    if (interp == NULL) {
        if (current_tstate == NULL) {
            interp = _PyGILState_GetInterpreterStateUnsafe();
            if (interp == NULL) {
                /* We need the interpreter state to get Python threads */
                return "unable to get the interpreter state";
            }
        }
        else {
            interp = current_tstate->interp;
        }
    }
    assert(interp != NULL);

    /* Get the current interpreter from the current thread */
    tstate = PyInterpreterState_ThreadHead(interp);
    if (tstate == NULL)
        return "unable to get the thread head state";

    /* Dump the traceback of each thread */
    tstate = PyInterpreterState_ThreadHead(interp);
    nthreads = 0;
    _Py_BEGIN_SUPPRESS_IPH
    do
    {
        if (nthreads != 0)
            PUTS(fd, "\n");
        if (nthreads >= MAX_NTHREADS) {
            PUTS(fd, "...\n");
            break;
        }
        write_thread_id(fd, tstate, tstate == current_tstate);
        dump_traceback(fd, tstate, 0);
        tstate = PyThreadState_Next(tstate);
        nthreads++;
    } while (tstate != NULL);
    _Py_END_SUPPRESS_IPH

    return NULL;
}