[New-bugs-announce] [issue41503] Race between setTarget and flush in logging.handlers.MemoryHandler

Irit Katriel report at bugs.python.org
Fri Aug 7 11:10:00 EDT 2020


New submission from Irit Katriel <iritkatriel at yahoo.com>:

The `logging.handlers.MemoryHandler.setTarget()` method does not acquire the lock, so it can change the target while flush is processing the buffer.

The script below causes flush to call target.handle when target is None, causing:

  File "C:\Users\User\src\cpython\lib\logging\handlers.py", line 1265, in emit
    self.flush()
  File "C:\Users\User\src\cpython\lib\logging\handlers.py", line 1348, in flush
    self.target.handle(record)
AttributeError: 'NoneType' object has no attribute 'handle'


------------------------------------------------
import io
import logging.handlers
import threading
import time

class SlowHandler:
    def __init__(self):
        self.stream = io.StringIO()
        self.streamHandler = logging.StreamHandler(self.stream)

    def handle(self, msg):
        time.sleep(1)
        self.streamHandler.handle(msg)

target = SlowHandler()
mem_hdlr = logging.handlers.MemoryHandler(10, logging.ERROR, target)
mem_logger = logging.getLogger('mem')
mem_logger.propagate = False
mem_logger.addHandler(mem_hdlr)

def toggleTarget():
    time.sleep(1)
    mem_hdlr.setTarget(None)

t = threading.Thread(target=toggleTarget, args=())
t.daemon = True
t.start()

while True:
    time.sleep(0.1)
    mem_logger.warning("warning not flushed")
    mem_logger.error("error is flushed")

------------------------------------------------

----------
components: Library (Lib)
messages: 375001
nosy: iritkatriel
priority: normal
severity: normal
status: open
title: Race between setTarget and flush in logging.handlers.MemoryHandler
type: behavior
versions: Python 3.10

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue41503>
_______________________________________


More information about the New-bugs-announce mailing list