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.
This commit is contained in:
Fred Drake 2001-12-04 21:40:53 +00:00
parent bebfe03617
commit 62c1e3c1b9

View file

@ -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)
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)
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)
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,
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)
} }
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)
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,
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,
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)
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;