Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RospyLogger stuck in indefinte loop #2352

Open
StephanOLC opened this issue Oct 4, 2023 · 1 comment · May be fixed by #2353
Open

RospyLogger stuck in indefinte loop #2352

StephanOLC opened this issue Oct 4, 2023 · 1 comment · May be fixed by #2353

Comments

@StephanOLC
Copy link

StephanOLC commented Oct 4, 2023

By importing rosbag the standard logger is overwritte.
When sending a warning or error the logger is stuck in an indefinte loop.
This can cause other python libraries to malfunction (for example Flask).
To reproduce

import rosbag
import logging

logger = logging.getLogger('myLogger') # gets a RospyLogger object
logger.warn('message') # gets stuck in infinite loop

Infinite Loop is inside def findCaller(self, *args, **kwargs): in roslogging.py.

Cause of the issue is:

file_name, lineno, func_name = super(RospyLogger, self).findCaller(*args, **kwargs)[:3] # returns file_name = ".../rosgraph/roslogging.py" lineno = 57  call func_name = 'findCaller'

returns itself as the caller:

Afterwards it tries to find a matching stackframe (skipping the first), but there is none.
The loop to do so is a while loop, but the condition does not change, as f is not reassigned if the last frame is reached.

while hasattr(f, "f_code"):
            # Search for the right frame using the data already found by parent class.
            co = f.f_code
            filename = os.path.normcase(co.co_filename)
            if filename == file_name and f.f_lineno == lineno and co.co_name == func_name:
                break
            if f.f_back:
                f = f.f_back

There are two things to fix:

  • Change the super().findCaller() so it does not return itself rather than the intended function. (Maybe stacklevel)
  • Prevent infinite loop by adding a else statement that does something (Throw Error?)

Alternativly do not set the global Logging class to RaspyLogger.

@jblee123
Copy link

I had this same issue running noetic compiled on Ubuntu 24.04 with python 3.12. I don't know if it was the ROS code or some change in the behavior of the underlying python that caused this to break (since there was evidently no issue on 20.04), but adding this hack to the top of the function seems to have fixed it for me:

        # Increment the "stacklevel" param, be it a positional or keyword
        # argument. Otherwise the call to the parent class's findCaller
        # function will simply return this location.
        if len(args) > 1:
            args_list = list(args)
            args_list[1] += 1
            args = tuple(args_list)
        if 'stacklevel' in kwargs:
            kwargs['stacklevel'] = kwargs['stacklevel'] + 1

This is a very quick-and-dirty, barely tested first-pass, so I'm open to suggestions for better fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants