Esempio n. 1
0
void *uwsgi_python_tracebacker_thread(void *foobar) {

	struct iovec iov[9];

	PyObject *new_thread = uwsgi_python_setup_thread("uWSGITraceBacker");
	if (!new_thread) return NULL;

	struct sockaddr_un so_sun;
	socklen_t so_sun_len = 0;

	char *str_wid = uwsgi_num2str(uwsgi.mywid);
	char *sock_path = uwsgi_concat2(up.tracebacker, str_wid);

	int current_defer_accept = uwsgi.no_defer_accept;
        uwsgi.no_defer_accept = 1;
	int fd = bind_to_unix(sock_path, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
        uwsgi.no_defer_accept = current_defer_accept;
	PyObject *threading_module = PyImport_ImportModule("threading");
	if (!threading_module) return NULL;
	//PyObject *threading_dict = PyModule_GetDict(threading_module);

	PyObject *traceback_module = PyImport_ImportModule("traceback");
	if (!traceback_module) return NULL;
	PyObject *traceback_dict = PyModule_GetDict(traceback_module);
	PyObject *extract_stack = PyDict_GetItemString(traceback_dict, "extract_stack");

	PyObject *sys_module = PyImport_ImportModule("sys");
	PyObject *sys_dict = PyModule_GetDict(sys_module);


	PyObject *_current_frames = PyDict_GetItemString(sys_dict, "_current_frames");

	uwsgi_log("python tracebacker for worker %d available on %s\n", uwsgi.mywid, sock_path);
	for(;;) {
		UWSGI_RELEASE_GIL;
		int client_fd = accept(fd, (struct sockaddr *) &so_sun, &so_sun_len);
		if (client_fd < 0) {
			uwsgi_error("accept()");
			UWSGI_GET_GIL;
			continue;
		}
		UWSGI_GET_GIL;
// here is the core of the tracebacker
		PyObject *current_frames = PyEval_CallObject(_current_frames, (PyObject *)NULL);
		if (!current_frames) goto end;
		uwsgi_log("current_frames = %p\n", current_frames);
		PyObject *current_frames_items = PyObject_GetAttrString(current_frames, "items");
		if (!current_frames_items) goto end;
		uwsgi_log("current_frames_items = %p\n", current_frames_items);
		PyObject *frames_ret = PyEval_CallObject(current_frames_items, (PyObject *)NULL);
		if (!frames_ret) goto end;
		uwsgi_log("frames_ret = %p\n", frames_ret);
		PyObject *frames_iter = PyObject_GetIter(frames_ret);
		uwsgi_log("frames_iter = %p\n", frames_iter);
		PyObject *frame = PyIter_Next(frames_iter);
		while(frame) {
			uwsgi_log("frame = %p\n", frame);
			PyObject *stack = PyTuple_GetItem(frame, 1);
			uwsgi_log("stack = %p\n", stack);
			PyObject *arg_tuple = PyTuple_New(1);
			PyTuple_SetItem(arg_tuple, 0, stack);
			PyObject *stacktrace = PyEval_CallObject( extract_stack, arg_tuple);
			uwsgi_log("stacktrace = %p\n", stacktrace);
			PyObject *stacktrace_iter = PyObject_GetIter(stacktrace);
			PyObject *st_items = PyIter_Next(stacktrace_iter);
			while(st_items) {
				uwsgi_log("st_items = %p\n", st_items);
				PyObject *st_filename = PyTuple_GetItem(st_items, 0);
				PyObject *st_lineno = PyTuple_GetItem(st_items, 1);
				PyObject *st_name = PyTuple_GetItem(st_items, 2);
				PyObject *st_line = PyTuple_GetItem(st_items, 3);
				iov[0].iov_base = "filename = ";
				iov[0].iov_len = 11;
				iov[1].iov_base = PyString_AsString(st_filename);
				iov[1].iov_len = strlen(iov[1].iov_base);
				iov[2].iov_base = " lineno = ";
				iov[2].iov_len = 10 ;
				iov[3].iov_base = uwsgi_num2str(PyInt_AsLong(st_lineno));
				iov[3].iov_len = strlen(iov[3].iov_base);
				iov[4].iov_base = " function = ";
				iov[4].iov_len = 12 ;
				iov[5].iov_base = PyString_AsString(st_name);
                                iov[5].iov_len = strlen(iov[5].iov_base);
				iov[6].iov_base = "\n";
				iov[6].iov_len = 1 ;
				if (st_line) {
				}
				if (writev(client_fd, iov, 7) < 0) {
					uwsgi_error("writev()");
				}
				st_items = PyIter_Next(stacktrace_iter);
			}
			frame = PyIter_Next(frames_iter);
		}

	
end:
		close(client_fd);
	}
	return NULL;
}
Esempio n. 2
0
void *uwsgi_python_autoreloader_thread(void *foobar) {

	PyObject *new_thread = uwsgi_python_setup_thread("uWSGIAutoReloader");
	if (!new_thread) return NULL;

	PyObject *modules = PyImport_GetModuleDict();

	if (uwsgi.mywid == 1) {
		uwsgi_log("Python auto-reloader enabled\n");
	}

	PyObject *times_dict = PyDict_New();
	char *filename;
	for(;;) {
		UWSGI_RELEASE_GIL;
		sleep(up.auto_reload);
		UWSGI_GET_GIL;
		// do not start monitoring til the first app is loaded (required for lazy mode)
		if (uwsgi_apps_cnt == 0) continue;
#ifdef UWSGI_PYTHON_OLD
                int pos = 0;
#else
                Py_ssize_t pos = 0;
#endif
		PyObject *mod_name, *mod;
                while (PyDict_Next(modules, &pos, &mod_name, &mod)) {
			int found = 0;
			struct uwsgi_string_list *usl = up.auto_reload_ignore;
			while(usl) {
				if (!strcmp(usl->value, PyString_AsString(mod_name))) {
					found = 1;
					break;
				}
				usl = usl->next;
			}
			if (found) continue;
			if (!PyObject_HasAttrString(mod, "__file__")) continue;
			PyObject *mod_file = PyObject_GetAttrString(mod, "__file__");
			if (!mod_file) continue;
#ifdef PYTHREE
			PyObject *zero = PyUnicode_AsUTF8String(mod_file);
			char *mod_filename = PyString_AsString(zero);
#else
			char *mod_filename = PyString_AsString(mod_file);
#endif
			if (!mod_filename) {
#ifdef PYTHREE
				Py_DECREF(zero);
#endif
				continue;
			}
			char *ext = strrchr(mod_filename, '.');
			if (ext && (!strcmp(ext+1, "pyc") || !strcmp(ext+1, "pyd") || !strcmp(ext+1, "pyo"))) {
				filename = uwsgi_concat2n(mod_filename, strlen(mod_filename)-1, "", 0);
			}
			else {
				filename = uwsgi_concat2(mod_filename, "");
			}
			if (uwsgi_check_python_mtime(times_dict, filename)) {
				UWSGI_RELEASE_GIL;
				return NULL;
			}
			free(filename);
#ifdef PYTHREE
			Py_DECREF(zero);
#endif
		}
	}

	return NULL;
}
Esempio n. 3
0
void *uwsgi_python_tracebacker_thread(void *foobar) {

	struct iovec iov[11];

	PyObject *new_thread = uwsgi_python_setup_thread("uWSGITraceBacker");
	if (!new_thread) return NULL;

	struct sockaddr_un so_sun;
	socklen_t so_sun_len = 0;

	char *str_wid = uwsgi_num2str(uwsgi.mywid);
	char *sock_path = uwsgi_concat2(up.tracebacker, str_wid);

	int current_defer_accept = uwsgi.no_defer_accept;
        uwsgi.no_defer_accept = 1;
	int fd = bind_to_unix(sock_path, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
	if (fd < 0) {
		uwsgi.no_defer_accept = current_defer_accept;
		free(str_wid);
		free(sock_path);
		return NULL;
	}
        uwsgi.no_defer_accept = current_defer_accept;

	PyObject *traceback_module = PyImport_ImportModule("traceback");
	if (!traceback_module) {
		free(str_wid);
		free(sock_path);
		close(fd);
		return NULL;
	}
	PyObject *traceback_dict = PyModule_GetDict(traceback_module);
	PyObject *extract_stack = PyDict_GetItemString(traceback_dict, "extract_stack");

	PyObject *sys_module = PyImport_ImportModule("sys");
	PyObject *sys_dict = PyModule_GetDict(sys_module);

	PyObject *_current_frames = PyDict_GetItemString(sys_dict, "_current_frames");

	uwsgi_log("python tracebacker for worker %d available on %s\n", uwsgi.mywid, sock_path);

	for(;;) {
		UWSGI_RELEASE_GIL;
		int client_fd = accept(fd, (struct sockaddr *) &so_sun, &so_sun_len);
		if (client_fd < 0) {
			uwsgi_error("accept()");
			UWSGI_GET_GIL;
			continue;
		}
		UWSGI_GET_GIL;
// here is the core of the tracebacker
		PyObject *current_frames = PyEval_CallObject(_current_frames, (PyObject *)NULL);
		if (!current_frames) goto end2;

		PyObject *current_frames_items = PyObject_GetAttrString(current_frames, "items");
		if (!current_frames_items) goto end;

		PyObject *frames_ret = PyEval_CallObject(current_frames_items, (PyObject *)NULL);
		if (!frames_ret) goto end3;

		PyObject *frames_iter = PyObject_GetIter(frames_ret);
		if (!frames_iter) goto end4;


		// we have the first frame, lets parse it
		if (write(client_fd, "*** uWSGI Python tracebacker output ***\n\n", 41) < 0) {
			uwsgi_error("write()");
		}
		PyObject *frame = PyIter_Next(frames_iter);
		while(frame) {
			PyObject *thread_id = PyTuple_GetItem(frame, 0);
			if (!thread_id) goto next2;

			PyObject *stack = PyTuple_GetItem(frame, 1);
			if (!stack) goto next2;

			PyObject *arg_tuple = PyTuple_New(1);
			PyTuple_SetItem(arg_tuple, 0, stack);
			Py_INCREF(stack);
			PyObject *stacktrace = PyEval_CallObject( extract_stack, arg_tuple);
			Py_DECREF(arg_tuple);
			if (!stacktrace) goto next2;
			
			PyObject *stacktrace_iter = PyObject_GetIter(stacktrace);
			if (!stacktrace_iter) { Py_DECREF(stacktrace); goto next2;}

			PyObject *st_items = PyIter_Next(stacktrace_iter);
			// we have the first traceback item
			while(st_items) {
#ifdef PYTHREE
				int thread_name_need_free = 0;
#endif
				PyObject *st_filename = PyTuple_GetItem(st_items, 0);
				if (!st_filename) { Py_DECREF(st_items); goto next; }
				PyObject *st_lineno = PyTuple_GetItem(st_items, 1);
				if (!st_lineno) {Py_DECREF(st_items); goto next;}
				PyObject *st_name = PyTuple_GetItem(st_items, 2);
				if (!st_name) {Py_DECREF(st_items); goto next;}

				PyObject *st_line = PyTuple_GetItem(st_items, 3);

				iov[0].iov_base = "thread_id = ";
				iov[0].iov_len = 12;

				iov[1].iov_base = uwsgi_python_get_thread_name(thread_id);
				if (!iov[1].iov_base) {
					iov[1].iov_base = "<UnnamedPythonThread>";
				}
#ifdef PYTHREE
				else {
					thread_name_need_free = 1;
				}
#endif
				iov[1].iov_len = strlen(iov[1].iov_base);

				iov[2].iov_base = " filename = ";
				iov[2].iov_len = 12;

#ifdef PYTHREE
				PyObject *st_filename_utf8 = PyUnicode_AsUTF8String(st_filename);
				if (!st_filename_utf8) {
					if (thread_name_need_free) free(iov[1].iov_base);
					goto next;
				}
				iov[3].iov_base = PyString_AsString(st_filename_utf8);
#else
				iov[3].iov_base = PyString_AsString(st_filename);
#endif
				iov[3].iov_len = strlen(iov[3].iov_base);

				iov[4].iov_base = " lineno = ";
				iov[4].iov_len = 10 ;

				iov[5].iov_base = uwsgi_num2str(PyInt_AsLong(st_lineno));
				iov[5].iov_len = strlen(iov[5].iov_base);

				iov[6].iov_base = " function = ";
				iov[6].iov_len = 12 ;

#ifdef PYTHREE
                                PyObject *st_name_utf8 = PyUnicode_AsUTF8String(st_name);
                                if (!st_name_utf8) {
					if (thread_name_need_free) free(iov[1].iov_base);
					Py_DECREF(st_filename_utf8);
					goto next;
				}
				iov[7].iov_base = PyString_AsString(st_name_utf8);
#else
				iov[7].iov_base = PyString_AsString(st_name);
#endif
                                iov[7].iov_len = strlen(iov[7].iov_base);

				iov[8].iov_base = "";
				iov[8].iov_len = 0 ;

				iov[9].iov_base = "";
				iov[9].iov_len = 0;

				iov[10].iov_base = "\n";
				iov[10].iov_len = 1;

#ifdef PYTHREE
				PyObject *st_line_utf8 = NULL;
#endif
				if (st_line) {
					iov[8].iov_base = " line = ";
					iov[8].iov_len = 8;
#ifdef PYTHREE
                                	PyObject *st_line_utf8 = PyUnicode_AsUTF8String(st_line);
                                	if (!st_line_utf8) {
						if (thread_name_need_free) free(iov[1].iov_base);
                                        	Py_DECREF(st_filename_utf8);
                                        	Py_DECREF(st_name_utf8);
                                        	goto next;
                                	}
					iov[9].iov_base = PyString_AsString(st_line_utf8);
#else
					iov[9].iov_base = PyString_AsString(st_line);
#endif
					iov[9].iov_len = strlen(iov[9].iov_base);
				}

				if (writev(client_fd, iov, 11) < 0) {
					uwsgi_error("writev()");
				}

				// free the line_no
				free(iov[5].iov_base);
				Py_DECREF(st_items);
#ifdef PYTHREE
				Py_DECREF(st_filename_utf8);
				Py_DECREF(st_name_utf8);
				if (st_line_utf8) {
					Py_DECREF(st_line_utf8);
				}
				if (thread_name_need_free)
					free(iov[1].iov_base);
#endif
				st_items = PyIter_Next(stacktrace_iter);
			}
			if (write(client_fd, "\n", 1) < 0) {
				uwsgi_error("write()");
			}
next:
			Py_DECREF(stacktrace_iter);
			Py_DECREF(stacktrace);
next2:
			Py_DECREF(frame);
			frame = PyIter_Next(frames_iter);
		}

		Py_DECREF(frames_iter);
end4:	
		Py_DECREF(frames_ret);
end3:	
		Py_DECREF(current_frames_items);
end:
		Py_DECREF(current_frames);
end2:
		close(client_fd);
	}
	return NULL;
}