Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8b6b491

Browse files
committed
The logreader object did not always refill the input buffer correctly
and got confused by certain log files. Remove logreader_refill and the associated logic and replace with fgetc.
1 parent d7abe2a commit 8b6b491

1 file changed

Lines changed: 56 additions & 105 deletions

File tree

Modules/_hotshot.c

Lines changed: 56 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,8 @@ typedef struct {
8383
PyObject_HEAD
8484
PyObject *info;
8585
FILE *logfp;
86-
int filled;
87-
int index;
8886
int linetimings;
8987
int frametimings;
90-
unsigned char buffer[BUFFERSIZE];
9188
} LogReaderObject;
9289

9390
static PyObject * ProfilerError = NULL;
@@ -272,25 +269,21 @@ logreader_tp_iter(LogReaderObject *self)
272269
static int
273270
unpack_packed_int(LogReaderObject *self, int *pvalue, int discard)
274271
{
272+
int c;
275273
int accum = 0;
276274
int bits = 0;
277-
int index = self->index;
278275
int cont;
279276

280277
do {
281-
if (index >= self->filled)
282-
return ERR_EOF;
283278
/* read byte */
284-
accum |= ((self->buffer[index] & 0x7F) >> discard) << bits;
279+
if ((c = fgetc(self->logfp)) == EOF)
280+
return ERR_EOF;
281+
accum |= ((c & 0x7F) >> discard) << bits;
285282
bits += (7 - discard);
286-
cont = self->buffer[index] & 0x80;
287-
/* move to next */
283+
cont = c & 0x80;
288284
discard = 0;
289-
index++;
290285
} while (cont);
291286

292-
/* save state */
293-
self->index = index;
294287
*pvalue = accum;
295288

296289
return 0;
@@ -302,43 +295,37 @@ unpack_packed_int(LogReaderObject *self, int *pvalue, int discard)
302295
static int
303296
unpack_string(LogReaderObject *self, PyObject **pvalue)
304297
{
298+
int i;
305299
int len;
306-
int oldindex = self->index;
307-
int err = unpack_packed_int(self, &len, 0);
308-
309-
if (!err) {
310-
/* need at least len bytes in buffer */
311-
if (len > (self->filled - self->index)) {
312-
self->index = oldindex;
313-
err = ERR_EOF;
314-
}
315-
else {
316-
*pvalue = PyString_FromStringAndSize((char *)self->buffer + self->index,
317-
len);
318-
if (*pvalue == NULL) {
319-
self->index = oldindex;
320-
err = ERR_EXCEPTION;
321-
}
322-
else
323-
self->index += len;
300+
int err;
301+
char *buf;
302+
303+
if ((err = unpack_packed_int(self, &len, 0)))
304+
return err;
305+
306+
buf = malloc(len);
307+
for (i=0; i < len; i++) {
308+
if ((buf[i] = fgetc(self->logfp)) == EOF) {
309+
free(buf);
310+
return ERR_EOF;
324311
}
325312
}
326-
return err;
313+
*pvalue = PyString_FromStringAndSize(buf, len);
314+
free(buf);
315+
if (*pvalue == NULL) {
316+
return ERR_EXCEPTION;
317+
}
318+
return 0;
327319
}
328320

329321

330322
static int
331-
unpack_add_info(LogReaderObject *self, int skip_opcode)
323+
unpack_add_info(LogReaderObject *self)
332324
{
333325
PyObject *key;
334326
PyObject *value = NULL;
335327
int err;
336328

337-
if (skip_opcode) {
338-
if (self->buffer[self->index] != WHAT_ADD_INFO)
339-
return ERR_BAD_RECTYPE;
340-
self->index++;
341-
}
342329
err = unpack_string(self, &key);
343330
if (!err) {
344331
err = unpack_string(self, &value);
@@ -368,25 +355,6 @@ unpack_add_info(LogReaderObject *self, int skip_opcode)
368355
}
369356

370357

371-
static void
372-
logreader_refill(LogReaderObject *self)
373-
{
374-
int needed;
375-
size_t res;
376-
377-
if (self->index) {
378-
memmove(self->buffer, &self->buffer[self->index],
379-
self->filled - self->index);
380-
self->filled = self->filled - self->index;
381-
self->index = 0;
382-
}
383-
needed = BUFFERSIZE - self->filled;
384-
if (needed > 0) {
385-
res = fread(&self->buffer[self->filled], 1, needed, self->logfp);
386-
self->filled += res;
387-
}
388-
}
389-
390358
static void
391359
eof_error(void)
392360
{
@@ -397,7 +365,8 @@ eof_error(void)
397365
static PyObject *
398366
logreader_tp_iternext(LogReaderObject *self)
399367
{
400-
int what, oldindex;
368+
int c;
369+
int what;
401370
int err = ERR_NONE;
402371
int lineno = -1;
403372
int fileno = -1;
@@ -413,22 +382,18 @@ logreader_tp_iternext(LogReaderObject *self)
413382
"cannot iterate over closed LogReader object");
414383
return NULL;
415384
}
416-
restart:
417-
if ((self->filled - self->index) < MAXEVENTSIZE)
418-
logreader_refill(self);
419385

420-
/* end of input */
421-
if (self->filled == 0)
386+
restart:
387+
/* decode the record type */
388+
if ((c = fgetc(self->logfp)) == EOF)
422389
return NULL;
423390

424-
oldindex = self->index;
391+
what = c & WHAT_OTHER;
392+
if (what == WHAT_OTHER)
393+
what = c; /* need all the bits for type */
394+
else
395+
ungetc(c, self->logfp); /* type byte includes packed int */
425396

426-
/* decode the record type */
427-
what = self->buffer[self->index] & WHAT_OTHER;
428-
if (what == WHAT_OTHER) {
429-
what = self->buffer[self->index];
430-
self->index++;
431-
}
432397
switch (what) {
433398
case WHAT_ENTER:
434399
err = unpack_packed_int(self, &fileno, 2);
@@ -447,7 +412,7 @@ logreader_tp_iternext(LogReaderObject *self)
447412
err = unpack_packed_int(self, &tdelta, 0);
448413
break;
449414
case WHAT_ADD_INFO:
450-
err = unpack_add_info(self, 0);
415+
err = unpack_add_info(self);
451416
break;
452417
case WHAT_DEFINE_FILE:
453418
err = unpack_packed_int(self, &fileno, 0);
@@ -468,40 +433,29 @@ logreader_tp_iternext(LogReaderObject *self)
468433
}
469434
break;
470435
case WHAT_LINE_TIMES:
471-
if (self->index >= self->filled)
436+
if ((c = fgetc(self->logfp)) == EOF)
472437
err = ERR_EOF;
473438
else {
474-
self->linetimings = self->buffer[self->index] ? 1 : 0;
475-
self->index++;
476-
goto restart;
477-
}
439+
self->linetimings = c ? 1 : 0;
440+
goto restart;
441+
}
478442
break;
479443
case WHAT_FRAME_TIMES:
480-
if (self->index >= self->filled)
444+
if ((c = fgetc(self->logfp)) == EOF)
481445
err = ERR_EOF;
482446
else {
483-
self->frametimings = self->buffer[self->index] ? 1 : 0;
484-
self->index++;
485-
goto restart;
486-
}
447+
self->frametimings = c ? 1 : 0;
448+
goto restart;
449+
}
487450
break;
488451
default:
489452
err = ERR_BAD_RECTYPE;
490453
}
491-
if (err == ERR_EOF && oldindex != 0) {
492-
/* It looks like we ran out of data before we had it all; this
493-
* could easily happen with large packed integers or string
494-
* data. Try forcing the buffer to be re-filled before failing.
495-
*/
496-
err = ERR_NONE;
497-
logreader_refill(self);
498-
}
499454
if (err == ERR_BAD_RECTYPE) {
500455
PyErr_SetString(PyExc_ValueError,
501456
"unknown record type in log file");
502457
}
503458
else if (err == ERR_EOF) {
504-
/* Could not avoid end-of-buffer error. */
505459
eof_error();
506460
}
507461
else if (!err) {
@@ -1389,12 +1343,12 @@ hotshot_logreader(PyObject *unused, PyObject *args)
13891343
{
13901344
LogReaderObject *self = NULL;
13911345
char *filename;
1346+
int c;
1347+
int err = 0;
13921348

13931349
if (PyArg_ParseTuple(args, "s:logreader", &filename)) {
13941350
self = PyObject_New(LogReaderObject, &LogReaderType);
13951351
if (self != NULL) {
1396-
self->filled = 0;
1397-
self->index = 0;
13981352
self->frametimings = 1;
13991353
self->linetimings = 0;
14001354
self->info = NULL;
@@ -1410,14 +1364,17 @@ hotshot_logreader(PyObject *unused, PyObject *args)
14101364
Py_DECREF(self);
14111365
goto finally;
14121366
}
1413-
/* Aggressively attempt to load all preliminary ADD_INFO
1414-
* records from the log so the info records are available
1415-
* from a fresh logreader object.
1416-
*/
1417-
logreader_refill(self);
1418-
while (self->filled > self->index
1419-
&& self->buffer[self->index] == WHAT_ADD_INFO) {
1420-
int err = unpack_add_info(self, 1);
1367+
/* read initial info */
1368+
for (;;) {
1369+
if ((c = fgetc(self->logfp)) == EOF) {
1370+
eof_error();
1371+
break;
1372+
}
1373+
if (c != WHAT_ADD_INFO) {
1374+
ungetc(c, self->logfp);
1375+
break;
1376+
}
1377+
err = unpack_add_info(self);
14211378
if (err) {
14221379
if (err == ERR_EOF)
14231380
eof_error();
@@ -1426,12 +1383,6 @@ hotshot_logreader(PyObject *unused, PyObject *args)
14261383
"unexpected error");
14271384
break;
14281385
}
1429-
/* Refill agressively so we can avoid EOF during
1430-
* initialization unless there's a real EOF condition
1431-
* (the tp_iternext handler loops attempts to refill
1432-
* and try again).
1433-
*/
1434-
logreader_refill(self);
14351386
}
14361387
}
14371388
}

0 commit comments

Comments
 (0)