prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  profiling/line2def does not handle empty filenames
  ### Which version of dd-trace-py are you using?
  We're not running dd-trace - we're running the profiler by importing `ddtrace.profiling.auto`.
  
  ### Which version of the libraries are you using?
  ddtrace: 0.40.0
  datadog: 0.38.0
  
  You can copy/paste the output of `pip freeze` here.
  
  ### How can we reproduce your problem?
  I'm unsure - this appears to happen sporadically.
  
  ### What is the result that you get?
  First, ddtrace runs into a KeyError in `_to_Location`, line 90:
  ```
  def _to_Location(self, filename, lineno, funcname=None):
          try:
              return self._locations[(filename, lineno, funcname)]
  ```
  `filename` is '', `lineno` is 1, `funcname` is None.
  
  Next, in `filename_and_lineno_to_def`, line 63, we get an IndexError:
  ```
  def filename_and_lineno_to_def(filename, lineno):
      if filename[0] == "<" and filename[-1] == ">":
          return default_def(filename, lineno)
  ```
  Since the filename is an empty string, this complains.
  
  
  
  ### What is the result that you expected?
  Not an error.
  
  If you need more information, please let me know!
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ddtrace/profiling/_line2def.py`
  Content:
  ```
  1 # -*- encoding: utf-8 -*-
  2 import ast
  3 
  4 import intervaltree
  5 
  6 
  7 try:
  8     from functools import lru_cache
  9 except ImportError:
  10     # This is for Python 2 but Python 2 does not use this module.
  11     # It's just useful for unit tests.
  12     def lru_cache(maxsize):
  13         def w(f):
  14             return f
  15 
  16         return w
  17 
  18 
  19 try:
  20     # Python 2 does not have this.
  21     from tokenize import open as source_open
  22 except ImportError:
  23     source_open = open
  24 
  25 from ddtrace.vendor import six
  26 
  27 
  28 def _compute_interval(node):
  29     min_lineno = node.lineno
  30     max_lineno = node.lineno
  31     for node in ast.walk(node):
  32         if hasattr(node, "lineno"):
  33             min_lineno = min(min_lineno, node.lineno)
  34             max_lineno = max(max_lineno, node.lineno)
  35     return (min_lineno, max_lineno + 1)
  36 
  37 
  38 if six.PY3:
  39     _DEFS = (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)
  40 else:
  41     _DEFS = (ast.FunctionDef, ast.ClassDef)
  42 
  43 
  44 @lru_cache(maxsize=256)
  45 def file_to_tree(filename):
  46     # Use tokenize.open to detect encoding
  47     with source_open(filename) as f:
  48         parsed = ast.parse(f.read(), filename=filename)
  49     tree = intervaltree.IntervalTree()
  50     for node in ast.walk(parsed):
  51         if isinstance(node, _DEFS):
  52             start, end = _compute_interval(node)
  53             tree[start:end] = node
  54     return tree
  55 
  56 
  57 def default_def(filename, lineno):
  58     return filename + ":" + str(lineno)
  59 
  60 
  61 @lru_cache(maxsize=8192)
  62 def filename_and_lineno_to_def(filename, lineno):
  63     if filename[0] == "<" and filename[-1] == ">":
  64         return default_def(filename, lineno)
  65 
  66     try:
  67         matches = file_to_tree(filename)[lineno]
  68     except (IOError, OSError, SyntaxError):
  69         return default_def(filename, lineno)
  70     if matches:
  71         return min(matches, key=lambda i: i.length()).data.name
  72 
  73     return default_def(filename, lineno)
  74
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/ddtrace/profiling/_line2def.py b/ddtrace/profiling/_line2def.py
  --- a/ddtrace/profiling/_line2def.py
  +++ b/ddtrace/profiling/_line2def.py
  @@ -55,12 +55,12 @@
   
   
   def default_def(filename, lineno):
  -    return filename + ":" + str(lineno)
  +    return str(filename) + ":" + str(lineno)
   
   
   @lru_cache(maxsize=8192)
   def filename_and_lineno_to_def(filename, lineno):
  -    if filename[0] == "<" and filename[-1] == ">":
  +    if not filename or (filename[0] == "<" and filename[-1] == ">"):
           return default_def(filename, lineno)
   
       try:
  
verification_info: {"golden_diff": "diff --git a/ddtrace/profiling/_line2def.py b/ddtrace/profiling/_line2def.py\n--- a/ddtrace/profiling/_line2def.py\n+++ b/ddtrace/profiling/_line2def.py\n@@ -55,12 +55,12 @@\n \n \n def default_def(filename, lineno):\n-    return filename + \":\" + str(lineno)\n+    return str(filename) + \":\" + str(lineno)\n \n \n @lru_cache(maxsize=8192)\n def filename_and_lineno_to_def(filename, lineno):\n-    if filename[0] == \"<\" and filename[-1] == \">\":\n+    if not filename or (filename[0] == \"<\" and filename[-1] == \">\"):\n         return default_def(filename, lineno)\n \n     try:\n", "issue": "profiling/line2def does not handle empty filenames\n### Which version of dd-trace-py are you using?\r\nWe're not running dd-trace - we're running the profiler by importing `ddtrace.profiling.auto`.\r\n\r\n### Which version of the libraries are you using?\r\nddtrace: 0.40.0\r\ndatadog: 0.38.0\r\n\r\nYou can copy/paste the output of `pip freeze` here.\r\n\r\n### How can we reproduce your problem?\r\nI'm unsure - this appears to happen sporadically.\r\n\r\n### What is the result that you get?\r\nFirst, ddtrace runs into a KeyError in `_to_Location`, line 90:\r\n```\r\ndef _to_Location(self, filename, lineno, funcname=None):\r\n        try:\r\n            return self._locations[(filename, lineno, funcname)]\r\n```\r\n`filename` is '', `lineno` is 1, `funcname` is None.\r\n\r\nNext, in `filename_and_lineno_to_def`, line 63, we get an IndexError:\r\n```\r\ndef filename_and_lineno_to_def(filename, lineno):\r\n    if filename[0] == \"<\" and filename[-1] == \">\":\r\n        return default_def(filename, lineno)\r\n```\r\nSince the filename is an empty string, this complains.\r\n\r\n\r\n\r\n### What is the result that you expected?\r\nNot an error.\r\n\r\nIf you need more information, please let me know!\n", "before_files": [{"content": "# -*- encoding: utf-8 -*-\nimport ast\n\nimport intervaltree\n\n\ntry:\n    from functools import lru_cache\nexcept ImportError:\n    # This is for Python\u00a02 but Python\u00a02 does not use this module.\n    # It's just useful for unit tests.\n    def lru_cache(maxsize):\n        def w(f):\n            return f\n\n        return w\n\n\ntry:\n    # Python\u00a02 does not have this.\n    from tokenize import open as source_open\nexcept ImportError:\n    source_open = open\n\nfrom ddtrace.vendor import six\n\n\ndef _compute_interval(node):\n    min_lineno = node.lineno\n    max_lineno = node.lineno\n    for node in ast.walk(node):\n        if hasattr(node, \"lineno\"):\n            min_lineno = min(min_lineno, node.lineno)\n            max_lineno = max(max_lineno, node.lineno)\n    return (min_lineno, max_lineno + 1)\n\n\nif six.PY3:\n    _DEFS = (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)\nelse:\n    _DEFS = (ast.FunctionDef, ast.ClassDef)\n\n\n@lru_cache(maxsize=256)\ndef file_to_tree(filename):\n    # Use tokenize.open to detect encoding\n    with source_open(filename) as f:\n        parsed = ast.parse(f.read(), filename=filename)\n    tree = intervaltree.IntervalTree()\n    for node in ast.walk(parsed):\n        if isinstance(node, _DEFS):\n            start, end = _compute_interval(node)\n            tree[start:end] = node\n    return tree\n\n\ndef default_def(filename, lineno):\n    return filename + \":\" + str(lineno)\n\n\n@lru_cache(maxsize=8192)\ndef filename_and_lineno_to_def(filename, lineno):\n    if filename[0] == \"<\" and filename[-1] == \">\":\n        return default_def(filename, lineno)\n\n    try:\n        matches = file_to_tree(filename)[lineno]\n    except (IOError, OSError, SyntaxError):\n        return default_def(filename, lineno)\n    if matches:\n        return min(matches, key=lambda i: i.length()).data.name\n\n    return default_def(filename, lineno)\n", "path": "ddtrace/profiling/_line2def.py"}], "after_files": [{"content": "# -*- encoding: utf-8 -*-\nimport ast\n\nimport intervaltree\n\n\ntry:\n    from functools import lru_cache\nexcept ImportError:\n    # This is for Python\u00a02 but Python\u00a02 does not use this module.\n    # It's just useful for unit tests.\n    def lru_cache(maxsize):\n        def w(f):\n            return f\n\n        return w\n\n\ntry:\n    # Python\u00a02 does not have this.\n    from tokenize import open as source_open\nexcept ImportError:\n    source_open = open\n\nfrom ddtrace.vendor import six\n\n\ndef _compute_interval(node):\n    min_lineno = node.lineno\n    max_lineno = node.lineno\n    for node in ast.walk(node):\n        if hasattr(node, \"lineno\"):\n            min_lineno = min(min_lineno, node.lineno)\n            max_lineno = max(max_lineno, node.lineno)\n    return (min_lineno, max_lineno + 1)\n\n\nif six.PY3:\n    _DEFS = (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)\nelse:\n    _DEFS = (ast.FunctionDef, ast.ClassDef)\n\n\n@lru_cache(maxsize=256)\ndef file_to_tree(filename):\n    # Use tokenize.open to detect encoding\n    with source_open(filename) as f:\n        parsed = ast.parse(f.read(), filename=filename)\n    tree = intervaltree.IntervalTree()\n    for node in ast.walk(parsed):\n        if isinstance(node, _DEFS):\n            start, end = _compute_interval(node)\n            tree[start:end] = node\n    return tree\n\n\ndef default_def(filename, lineno):\n    return str(filename) + \":\" + str(lineno)\n\n\n@lru_cache(maxsize=8192)\ndef filename_and_lineno_to_def(filename, lineno):\n    if not filename or (filename[0] == \"<\" and filename[-1] == \">\"):\n        return default_def(filename, lineno)\n\n    try:\n        matches = file_to_tree(filename)[lineno]\n    except (IOError, OSError, SyntaxError):\n        return default_def(filename, lineno)\n    if matches:\n        return min(matches, key=lambda i: i.length()).data.name\n\n    return default_def(filename, lineno)\n", "path": "ddtrace/profiling/_line2def.py"}]}