Commit ef7303df authored by Fred Drake's avatar Fred Drake

Make sure to propogate errors that arise when profiling data cannot be

written to the log file, and turn off the profiler.
This closes SF bug #483925.
parent 590d9e12
...@@ -590,6 +590,8 @@ logreader_next(LogReaderObject *self, PyObject *args) ...@@ -590,6 +590,8 @@ logreader_next(LogReaderObject *self, PyObject *args)
return result; return result;
} }
static void
do_stop(ProfilerObject *self);
static int static int
flush_data(ProfilerObject *self) flush_data(ProfilerObject *self)
...@@ -605,6 +607,7 @@ flush_data(ProfilerObject *self) ...@@ -605,6 +607,7 @@ flush_data(ProfilerObject *self)
if (written == 0) { if (written == 0) {
char *s = PyString_AsString(self->logfilename); char *s = PyString_AsString(self->logfilename);
PyErr_SetFromErrnoWithFilename(PyExc_IOError, s); PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
do_stop(self);
return -1; return -1;
} }
} }
...@@ -612,13 +615,14 @@ flush_data(ProfilerObject *self) ...@@ -612,13 +615,14 @@ flush_data(ProfilerObject *self)
if (fflush(self->logfp)) { if (fflush(self->logfp)) {
char *s = PyString_AsString(self->logfilename); char *s = PyString_AsString(self->logfilename);
PyErr_SetFromErrnoWithFilename(PyExc_IOError, s); PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
do_stop(self);
return -1; return -1;
} }
} }
return 0; return 0;
} }
static inline void static inline int
pack_packed_int(ProfilerObject *self, int value) pack_packed_int(ProfilerObject *self, int value)
{ {
unsigned char partial; unsigned char partial;
...@@ -631,13 +635,14 @@ pack_packed_int(ProfilerObject *self, int value) ...@@ -631,13 +635,14 @@ pack_packed_int(ProfilerObject *self, int value)
self->buffer[self->index] = partial; self->buffer[self->index] = partial;
self->index++; self->index++;
} while (value); } while (value);
return 0;
} }
/* Encode a modified packed integer, with a subfield of modsize bits /* Encode a modified packed integer, with a subfield of modsize bits
* containing the value "subfield". The value of subfield is not * containing the value "subfield". The value of subfield is not
* checked to ensure it actually fits in modsize bits. * checked to ensure it actually fits in modsize bits.
*/ */
static inline void static inline int
pack_modified_packed_int(ProfilerObject *self, int value, pack_modified_packed_int(ProfilerObject *self, int value,
int modsize, int subfield) int modsize, int subfield)
{ {
...@@ -651,125 +656,154 @@ pack_modified_packed_int(ProfilerObject *self, int value, ...@@ -651,125 +656,154 @@ pack_modified_packed_int(ProfilerObject *self, int value,
b |= 0x80; b |= 0x80;
self->buffer[self->index] = b; self->buffer[self->index] = b;
self->index++; self->index++;
pack_packed_int(self, value >> bits); return pack_packed_int(self, value >> bits);
}
else {
self->buffer[self->index] = b;
self->index++;
} }
self->buffer[self->index] = b;
self->index++;
return 0;
} }
static void static int
pack_string(ProfilerObject *self, const char *s, int len) pack_string(ProfilerObject *self, const char *s, int len)
{ {
if (len + PISIZE + self->index >= BUFFERSIZE) if (len + PISIZE + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
pack_packed_int(self, len); return -1;
}
if (pack_packed_int(self, len) < 0)
return -1;
memcpy(self->buffer + self->index, s, len); memcpy(self->buffer + self->index, s, len);
self->index += len; self->index += len;
return 0;
} }
static void static int
pack_add_info(ProfilerObject *self, const char *s1, const char *s2) pack_add_info(ProfilerObject *self, const char *s1, const char *s2)
{ {
int len1 = strlen(s1); int len1 = strlen(s1);
int len2 = strlen(s2); int len2 = strlen(s2);
if (len1 + len2 + PISIZE*2 + 1 + self->index >= BUFFERSIZE) if (len1 + len2 + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_ADD_INFO; self->buffer[self->index] = WHAT_ADD_INFO;
self->index++; self->index++;
pack_string(self, s1, len1); if (pack_string(self, s1, len1) < 0)
pack_string(self, s2, len2); return -1;
return pack_string(self, s2, len2);
} }
static void static int
pack_define_file(ProfilerObject *self, int fileno, const char *filename) pack_define_file(ProfilerObject *self, int fileno, const char *filename)
{ {
int len = strlen(filename); int len = strlen(filename);
if (len + PISIZE*2 + 1 + self->index >= BUFFERSIZE) if (len + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_DEFINE_FILE; self->buffer[self->index] = WHAT_DEFINE_FILE;
self->index++; self->index++;
pack_packed_int(self, fileno); if (pack_packed_int(self, fileno) < 0)
pack_string(self, filename, len); return -1;
return pack_string(self, filename, len);
} }
static void static int
pack_define_func(ProfilerObject *self, int fileno, int lineno, pack_define_func(ProfilerObject *self, int fileno, int lineno,
const char *funcname) const char *funcname)
{ {
int len = strlen(funcname); int len = strlen(funcname);
if (len + PISIZE*3 + 1 + self->index >= BUFFERSIZE) if (len + PISIZE*3 + 1 + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_DEFINE_FUNC; self->buffer[self->index] = WHAT_DEFINE_FUNC;
self->index++; self->index++;
pack_packed_int(self, fileno); if (pack_packed_int(self, fileno) < 0)
pack_packed_int(self, lineno); return -1;
pack_string(self, funcname, len); if (pack_packed_int(self, lineno) < 0)
return -1;
return pack_string(self, funcname, len);
} }
static void static int
pack_line_times(ProfilerObject *self) pack_line_times(ProfilerObject *self)
{ {
if (2 + self->index >= BUFFERSIZE) if (2 + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_LINE_TIMES; self->buffer[self->index] = WHAT_LINE_TIMES;
self->buffer[self->index + 1] = self->linetimings ? 1 : 0; self->buffer[self->index + 1] = self->linetimings ? 1 : 0;
self->index += 2; self->index += 2;
return 0;
} }
static void static int
pack_frame_times(ProfilerObject *self) pack_frame_times(ProfilerObject *self)
{ {
if (2 + self->index >= BUFFERSIZE) if (2 + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_FRAME_TIMES; self->buffer[self->index] = WHAT_FRAME_TIMES;
self->buffer[self->index + 1] = self->frametimings ? 1 : 0; self->buffer[self->index + 1] = self->frametimings ? 1 : 0;
self->index += 2; self->index += 2;
return 0;
} }
static inline void static inline int
pack_enter(ProfilerObject *self, int fileno, int tdelta, int lineno) pack_enter(ProfilerObject *self, int fileno, int tdelta, int lineno)
{ {
if (MPISIZE + PISIZE*2 + self->index >= BUFFERSIZE) if (MPISIZE + PISIZE*2 + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
return -1;
}
pack_modified_packed_int(self, fileno, 2, WHAT_ENTER); pack_modified_packed_int(self, fileno, 2, WHAT_ENTER);
pack_packed_int(self, lineno); pack_packed_int(self, lineno);
if (self->frametimings) if (self->frametimings)
pack_packed_int(self, tdelta); return pack_packed_int(self, tdelta);
else
return 0;
} }
static inline void static inline int
pack_exit(ProfilerObject *self, int tdelta) pack_exit(ProfilerObject *self, int tdelta)
{ {
if (MPISIZE + self->index >= BUFFERSIZE) if (MPISIZE + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
if (self->frametimings) return -1;
pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT);
else {
self->buffer[self->index] = WHAT_EXIT;
self->index++;
} }
if (self->frametimings)
return pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT);
self->buffer[self->index] = WHAT_EXIT;
self->index++;
return 0;
} }
static inline void static inline int
pack_lineno(ProfilerObject *self, int lineno) pack_lineno(ProfilerObject *self, int lineno)
{ {
if (MPISIZE + self->index >= BUFFERSIZE) if (MPISIZE + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
pack_modified_packed_int(self, lineno, 2, WHAT_LINENO); return -1;
}
return pack_modified_packed_int(self, lineno, 2, WHAT_LINENO);
} }
static inline void static inline int
pack_lineno_tdelta(ProfilerObject *self, int lineno, int tdelta) pack_lineno_tdelta(ProfilerObject *self, int lineno, int tdelta)
{ {
if (MPISIZE + PISIZE + self->index >= BUFFERSIZE) if (MPISIZE + PISIZE + self->index >= BUFFERSIZE) {
(void) flush_data(self); if (flush_data(self) < 0)
pack_modified_packed_int(self, lineno, 2, WHAT_LINENO); return 0;
pack_packed_int(self, tdelta); }
if (pack_modified_packed_int(self, lineno, 2, WHAT_LINENO) < 0)
return -1;
return pack_packed_int(self, tdelta);
} }
static inline int static inline int
...@@ -799,7 +833,9 @@ get_fileno(ProfilerObject *self, PyCodeObject *fcode) ...@@ -799,7 +833,9 @@ get_fileno(ProfilerObject *self, PyCodeObject *fcode)
} }
self->next_fileno++; self->next_fileno++;
Py_DECREF(obj); Py_DECREF(obj);
pack_define_file(self, fileno, PyString_AS_STRING(fcode->co_filename)); if (pack_define_file(self, fileno,
PyString_AS_STRING(fcode->co_filename)) < 0)
return -1;
} }
else { else {
/* already know this ID */ /* already know this ID */
...@@ -815,8 +851,9 @@ get_fileno(ProfilerObject *self, PyCodeObject *fcode) ...@@ -815,8 +851,9 @@ get_fileno(ProfilerObject *self, PyCodeObject *fcode)
else { else {
PyObject *name = PyDict_GetItem(dict, obj); PyObject *name = PyDict_GetItem(dict, obj);
if (name == NULL) { if (name == NULL) {
pack_define_func(self, fileno, fcode->co_firstlineno, if (pack_define_func(self, fileno, fcode->co_firstlineno,
PyString_AS_STRING(fcode->co_name)); PyString_AS_STRING(fcode->co_name)) < 0)
return -1;
if (PyDict_SetItem(dict, obj, fcode->co_name)) if (PyDict_SetItem(dict, obj, fcode->co_name))
return -1; return -1;
} }
...@@ -867,11 +904,13 @@ profiler_callback(ProfilerObject *self, PyFrameObject *frame, int what, ...@@ -867,11 +904,13 @@ profiler_callback(ProfilerObject *self, PyFrameObject *frame, int what,
fileno = get_fileno(self, frame->f_code); fileno = get_fileno(self, frame->f_code);
if (fileno < 0) if (fileno < 0)
return -1; return -1;
pack_enter(self, fileno, tdelta, if (pack_enter(self, fileno, tdelta,
frame->f_code->co_firstlineno); frame->f_code->co_firstlineno) < 0)
return -1;
break; break;
case PyTrace_RETURN: case PyTrace_RETURN:
pack_exit(self, tdelta); if (pack_exit(self, tdelta) < 0)
return -1;
break; break;
default: default:
/* should never get here */ /* should never get here */
...@@ -894,18 +933,19 @@ tracer_callback(ProfilerObject *self, PyFrameObject *frame, int what, ...@@ -894,18 +933,19 @@ tracer_callback(ProfilerObject *self, PyFrameObject *frame, int what,
fileno = get_fileno(self, frame->f_code); fileno = get_fileno(self, frame->f_code);
if (fileno < 0) if (fileno < 0)
return -1; return -1;
pack_enter(self, fileno, self->frametimings ? get_tdelta(self) : -1, return pack_enter(self, fileno,
frame->f_code->co_firstlineno); self->frametimings ? get_tdelta(self) : -1,
break; frame->f_code->co_firstlineno);
case PyTrace_RETURN: case PyTrace_RETURN:
pack_exit(self, get_tdelta(self)); return pack_exit(self, get_tdelta(self));
break;
case PyTrace_LINE: case PyTrace_LINE:
if (self->linetimings) if (self->linetimings)
pack_lineno_tdelta(self, frame->f_lineno, get_tdelta(self)); return pack_lineno_tdelta(self, frame->f_lineno, get_tdelta(self));
else else
pack_lineno(self, frame->f_lineno); return pack_lineno(self, frame->f_lineno);
break;
default: default:
/* ignore PyTrace_EXCEPTION */ /* ignore PyTrace_EXCEPTION */
break; break;
...@@ -1042,9 +1082,10 @@ profiler_addinfo(ProfilerObject *self, PyObject *args) ...@@ -1042,9 +1082,10 @@ profiler_addinfo(ProfilerObject *self, PyObject *args)
if (self->logfp == NULL) if (self->logfp == NULL)
PyErr_SetString(ProfilerError, "profiler already closed"); PyErr_SetString(ProfilerError, "profiler already closed");
else { else {
pack_add_info(self, key, value); if (pack_add_info(self, key, value) == 0) {
result = Py_None; result = Py_None;
Py_INCREF(result); Py_INCREF(result);
}
} }
} }
return result; return result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment