dlltracer


Namedlltracer JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://github.com/microsoft/dlltracer-python
SummaryPython module for tracing Windows DLL loads
upload_time2023-10-02 11:53:30
maintainerNone
docs_urlNone
authorMicrosoft Corporation
requires_python>=3.7
licenseNone
keywords windows win32 dll
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # dlltracer

The `dlltracer` tool is an assistive tool for diagnosing import errors in
CPython when they are caused by DLL resolution failures on Windows.

In general, any DLL load error is reported as an `ImportError` of the top-level
extension module. No more specific information is available for CPython to
display, which can make it difficult to diagnose.

This tool uses not-quite-documented performance events to report on the
intermediate steps of importing an extension module. These events are
undocumented and unsupported, so the format has been inferred by example and may
change, but until it does it will report on the loads that _actually occur_.
However, because it can't report on loads that _never_ occur, you'll still need
to do some work to diagnose the root cause of the failure.

The most useful static analysis tool is
[dumpbin](https://docs.microsoft.com/cpp/build/reference/dumpbin-reference),
which is included with Visual Studio. When passed a DLL or PYD file and the
`/imports` option, it will list all dependencies that _should be_ loaded. It
shows them by name, that is, before path resolution occurs.

`dlltracer` performs dynamic analysis, which shows the DLLs that are loaded at
runtime with their full paths. Combined with understanding the dependency
graph of your module, it is easier to diagnose why the overall import fails.


# Install

```
pip install dlltracer
```

Where the `pip` command may be replaced by a more appropriate command for your
environment, such as `python -m pip` or `pip3.9`.


# Use

*Note:* Regardless of how output is collected, this tool *must be run as
Administrator*. Otherwise, starting a trace will fail with a `PermissionError`.
Only one thread may be tracing across your entire machine. Because the state
of traces is not well managed by Windows, this tool will attempt to stop any
other running traces.

A basic trace that prints messages to standard output is:

```python
import dlltracer
import sys

with dlltracer.Trace(out=sys.stdout):
    import module_to_trace
```

The output may look like this (for `import ssl`):

```
LoadLibrary \Device\HarddiskVolume3\Windows\System32\kernel.appcore.dll
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\_ssl.pyd
LoadLibrary \Device\HarddiskVolume3\Windows\System32\crypt32.dll
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\libcrypto-1_1.dll
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\libssl-1_1.dll
LoadLibrary \Device\HarddiskVolume3\Windows\System32\user32.dll
LoadLibrary \Device\HarddiskVolume3\Windows\System32\win32u.dll
LoadLibrary \Device\HarddiskVolume3\Windows\System32\gdi32.dll
LoadLibrary \Device\HarddiskVolume3\Windows\System32\gdi32full.dll
LoadLibrary \Device\HarddiskVolume3\Windows\System32\msvcp_win.dll
LoadLibrary \Device\HarddiskVolume3\Windows\System32\imm32.dll
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\_socket.pyd
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\select.pyd
```

A failed import may look like this (for `import ssl` but with `libcrypto-1_1.dll`
missing):

```
LoadLibrary \Device\HarddiskVolume3\Windows\System32\kernel.appcore.dll
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\_ssl.pyd
LoadLibrary \Device\HarddiskVolume3\Windows\System32\crypt32.dll
LoadLibrary \Device\HarddiskVolume3\Program Files\Python39\DLLs\libssl-1_1.dll
Failed \Device\HarddiskVolume3\Windows\System32\crypt32.dll
Failed \Device\HarddiskVolume3\Program Files\Python39\DLLs\libssl-1_1.dll
Failed \Device\HarddiskVolume3\Program Files\Python39\DLLs\_ssl.pyd
Traceback (most recent call last):
  File "C:\Projects\test-script.py", line 28, in <module>
    import ssl
  File "C:\Program Files\Python39\lib\ssl.py", line 98, in <module>
    import _ssl             # if we can't import it, let the error propagate
ImportError: DLL load failed while importing _ssl: The specified module could not be found.
```

Notice that the missing DLL is never mentioned, and so human analysis is
necessary to diagnose the root cause.

## Write to file

To write output to a file-like object (anything that can be passed to the
`file=` argument of `print`), pass it as the `out=` argument of `Trace`.

```python
import dlltracer

with open("log.txt", "w") as log:
    with dlltracer.Trace(out=log):
        import module_to_trace
```


## Collect to list

To collect events to an iterable object, pass `collect=True` to `Trace` and
bind the context manager. The result will be a list containing event objects,
typically `dlltracer.LoadEvent` and `dlltracer.LoadFailedEvent`.

```python
import dlltracer

with dlltracer.Trace(collect=True) as events:
    try:
        import module_to_trace
    except ImportError:
        # If we don't handle the error, program will exit before
        # we get to inspect the events.
        pass

# Inspect the events after ending the trace
all_loaded = {e.path for e in events if isinstance(e, dlltracer.LoadEvent)}
all_failed = {e.path for e in events if isinstance(e, dlltracer.LoadFailedEvent)}
```

## Raise audit events

To raise audit events for DLL loads, pass `audit=True` to `Trace`. The events
raised are `dlltracer.load` and `dlltracer.failed`, and both only include the
path as an argument.

```python
import dlltracer
import sys

def hook(event, args):
    if event == "dlltracer.load":
        # args = (path,)
        print("Loaded", args[0])
    elif event == "dlltracer.failed":
        # args = (path,)
        print("Failed", args[0])

sys.add_audit_hook(hook)

with dlltracer.Trace(audit=True):
    import module_to_trace
```


## Additional events

*Note:* This is mainly intended for development of `dlltracer`.

Because event formats may change, and additional events may be of interest but
are not yet handled, passing the `debug=True` option to `Trace` enables all
events to be collected, written, or audited. Regular events are suppressed.

```python
import dlltracer
import sys

def hook(event, args):
    if event != "dlltracer.debug":
        return

    # args schema:
    #   provider is a UUID representing the event source
    #   opcode is an int representing the operation
    #   header is bytes taken directly from the event header
    #   data is bytes taken directly from the event data
    provider, opcode, header, data = args

sys.add_audit_hook(hook)

with dlltracer.Trace(debug=True, audit=True, collect=True, out=sys.stderr) as events:
    try:
        import module_to_trace
    except ImportError:
        pass

for e in events:
    assert isinstance(e, dlltracer.DebugEvent)
    # DebugEvent contains provider, opcode, header and data as for the audit event
```


# Contribute

This project welcomes contributions and suggestions.  Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.


# Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 
trademarks or logos is subject to and must follow 
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/microsoft/dlltracer-python",
    "name": "dlltracer",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "Windows,Win32,DLL",
    "author": "Microsoft Corporation",
    "author_email": "python@microsoft.com",
    "download_url": "https://files.pythonhosted.org/packages/20/e5/e3d0809e0a6c7f1518ebc9a7a917201349287794280d908ab6b5b487dec9/dlltracer-1.0.2.tar.gz",
    "platform": null,
    "description": "# dlltracer\n\nThe `dlltracer` tool is an assistive tool for diagnosing import errors in\nCPython when they are caused by DLL resolution failures on Windows.\n\nIn general, any DLL load error is reported as an `ImportError` of the top-level\nextension module. No more specific information is available for CPython to\ndisplay, which can make it difficult to diagnose.\n\nThis tool uses not-quite-documented performance events to report on the\nintermediate steps of importing an extension module. These events are\nundocumented and unsupported, so the format has been inferred by example and may\nchange, but until it does it will report on the loads that _actually occur_.\nHowever, because it can't report on loads that _never_ occur, you'll still need\nto do some work to diagnose the root cause of the failure.\n\nThe most useful static analysis tool is\n[dumpbin](https://docs.microsoft.com/cpp/build/reference/dumpbin-reference),\nwhich is included with Visual Studio. When passed a DLL or PYD file and the\n`/imports` option, it will list all dependencies that _should be_ loaded. It\nshows them by name, that is, before path resolution occurs.\n\n`dlltracer` performs dynamic analysis, which shows the DLLs that are loaded at\nruntime with their full paths. Combined with understanding the dependency\ngraph of your module, it is easier to diagnose why the overall import fails.\n\n\n# Install\n\n```\npip install dlltracer\n```\n\nWhere the `pip` command may be replaced by a more appropriate command for your\nenvironment, such as `python -m pip` or `pip3.9`.\n\n\n# Use\n\n*Note:* Regardless of how output is collected, this tool *must be run as\nAdministrator*. Otherwise, starting a trace will fail with a `PermissionError`.\nOnly one thread may be tracing across your entire machine. Because the state\nof traces is not well managed by Windows, this tool will attempt to stop any\nother running traces.\n\nA basic trace that prints messages to standard output is:\n\n```python\nimport dlltracer\nimport sys\n\nwith dlltracer.Trace(out=sys.stdout):\n    import module_to_trace\n```\n\nThe output may look like this (for `import ssl`):\n\n```\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\kernel.appcore.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\_ssl.pyd\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\crypt32.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\libcrypto-1_1.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\libssl-1_1.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\user32.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\win32u.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\gdi32.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\gdi32full.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\msvcp_win.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\imm32.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\_socket.pyd\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\select.pyd\n```\n\nA failed import may look like this (for `import ssl` but with `libcrypto-1_1.dll`\nmissing):\n\n```\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\kernel.appcore.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\_ssl.pyd\nLoadLibrary \\Device\\HarddiskVolume3\\Windows\\System32\\crypt32.dll\nLoadLibrary \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\libssl-1_1.dll\nFailed \\Device\\HarddiskVolume3\\Windows\\System32\\crypt32.dll\nFailed \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\libssl-1_1.dll\nFailed \\Device\\HarddiskVolume3\\Program Files\\Python39\\DLLs\\_ssl.pyd\nTraceback (most recent call last):\n  File \"C:\\Projects\\test-script.py\", line 28, in <module>\n    import ssl\n  File \"C:\\Program Files\\Python39\\lib\\ssl.py\", line 98, in <module>\n    import _ssl             # if we can't import it, let the error propagate\nImportError: DLL load failed while importing _ssl: The specified module could not be found.\n```\n\nNotice that the missing DLL is never mentioned, and so human analysis is\nnecessary to diagnose the root cause.\n\n## Write to file\n\nTo write output to a file-like object (anything that can be passed to the\n`file=` argument of `print`), pass it as the `out=` argument of `Trace`.\n\n```python\nimport dlltracer\n\nwith open(\"log.txt\", \"w\") as log:\n    with dlltracer.Trace(out=log):\n        import module_to_trace\n```\n\n\n## Collect to list\n\nTo collect events to an iterable object, pass `collect=True` to `Trace` and\nbind the context manager. The result will be a list containing event objects,\ntypically `dlltracer.LoadEvent` and `dlltracer.LoadFailedEvent`.\n\n```python\nimport dlltracer\n\nwith dlltracer.Trace(collect=True) as events:\n    try:\n        import module_to_trace\n    except ImportError:\n        # If we don't handle the error, program will exit before\n        # we get to inspect the events.\n        pass\n\n# Inspect the events after ending the trace\nall_loaded = {e.path for e in events if isinstance(e, dlltracer.LoadEvent)}\nall_failed = {e.path for e in events if isinstance(e, dlltracer.LoadFailedEvent)}\n```\n\n## Raise audit events\n\nTo raise audit events for DLL loads, pass `audit=True` to `Trace`. The events\nraised are `dlltracer.load` and `dlltracer.failed`, and both only include the\npath as an argument.\n\n```python\nimport dlltracer\nimport sys\n\ndef hook(event, args):\n    if event == \"dlltracer.load\":\n        # args = (path,)\n        print(\"Loaded\", args[0])\n    elif event == \"dlltracer.failed\":\n        # args = (path,)\n        print(\"Failed\", args[0])\n\nsys.add_audit_hook(hook)\n\nwith dlltracer.Trace(audit=True):\n    import module_to_trace\n```\n\n\n## Additional events\n\n*Note:* This is mainly intended for development of `dlltracer`.\n\nBecause event formats may change, and additional events may be of interest but\nare not yet handled, passing the `debug=True` option to `Trace` enables all\nevents to be collected, written, or audited. Regular events are suppressed.\n\n```python\nimport dlltracer\nimport sys\n\ndef hook(event, args):\n    if event != \"dlltracer.debug\":\n        return\n\n    # args schema:\n    #   provider is a UUID representing the event source\n    #   opcode is an int representing the operation\n    #   header is bytes taken directly from the event header\n    #   data is bytes taken directly from the event data\n    provider, opcode, header, data = args\n\nsys.add_audit_hook(hook)\n\nwith dlltracer.Trace(debug=True, audit=True, collect=True, out=sys.stderr) as events:\n    try:\n        import module_to_trace\n    except ImportError:\n        pass\n\nfor e in events:\n    assert isinstance(e, dlltracer.DebugEvent)\n    # DebugEvent contains provider, opcode, header and data as for the audit event\n```\n\n\n# Contribute\n\nThis project welcomes contributions and suggestions.  Most contributions require you to agree to a\nContributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us\nthe rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.\n\nWhen you submit a pull request, a CLA bot will automatically determine whether you need to provide\na CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions\nprovided by the bot. You will only need to do this once across all repos using our CLA.\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\nFor more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n\n\n# Trademarks\n\nThis project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft \ntrademarks or logos is subject to and must follow \n[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).\nUse of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.\nAny use of third-party trademarks or logos are subject to those third-party's policies.\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Python module for tracing Windows DLL loads",
    "version": "1.0.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/microsoft/dlltracer-python/issues",
        "Homepage": "https://github.com/microsoft/dlltracer-python"
    },
    "split_keywords": [
        "windows",
        "win32",
        "dll"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "26c78e72185e2fb68fb421a2ac0111d217357039699a7bedd39183bea42485ba",
                "md5": "b09611c15d108d77b2ca597e85747ba8",
                "sha256": "0a6468533a58553d7a8ff1874c2d9c4de473a83e9c12b550cc60c7a6e65b6302"
            },
            "downloads": -1,
            "filename": "dlltracer-1.0.2-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "b09611c15d108d77b2ca597e85747ba8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 87532,
            "upload_time": "2023-10-02T11:53:31",
            "upload_time_iso_8601": "2023-10-02T11:53:31.832723Z",
            "url": "https://files.pythonhosted.org/packages/26/c7/8e72185e2fb68fb421a2ac0111d217357039699a7bedd39183bea42485ba/dlltracer-1.0.2-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c00bcee377cdcb1caea26768e2a8131e285c26ffb091f8ecf66b93688679c1f3",
                "md5": "94e56f684d4bd6e17c3a5406e593066c",
                "sha256": "d75f0923f44f115a94e396d4ddde01b46733296cd18a5e14151f937cf96b7139"
            },
            "downloads": -1,
            "filename": "dlltracer-1.0.2-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "94e56f684d4bd6e17c3a5406e593066c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 84120,
            "upload_time": "2023-10-02T11:53:33",
            "upload_time_iso_8601": "2023-10-02T11:53:33.175760Z",
            "url": "https://files.pythonhosted.org/packages/c0/0b/cee377cdcb1caea26768e2a8131e285c26ffb091f8ecf66b93688679c1f3/dlltracer-1.0.2-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "05ad89e2a98dd71cf41cdf4b5dfd412d246e1d5d03164e50e084c7ade48527e8",
                "md5": "cc131cd8777d1f62662ebd1661fc9163",
                "sha256": "cef14f1390b9b85c25277a4798ce6653650005908267296f3b4db153d5842e66"
            },
            "downloads": -1,
            "filename": "dlltracer-1.0.2-cp37-cp37-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "cc131cd8777d1f62662ebd1661fc9163",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 85027,
            "upload_time": "2023-10-02T11:53:35",
            "upload_time_iso_8601": "2023-10-02T11:53:35.334845Z",
            "url": "https://files.pythonhosted.org/packages/05/ad/89e2a98dd71cf41cdf4b5dfd412d246e1d5d03164e50e084c7ade48527e8/dlltracer-1.0.2-cp37-cp37-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8409c660b592b84c392ae57e527b8f39a0b3fc8ea84783856836ecd242ef53f7",
                "md5": "b6373afe5d51567a577f5f14bb52bffe",
                "sha256": "36d705fdd8bcc29b21045c3eceec75831099b95d14c547166a16635297b6e0e4"
            },
            "downloads": -1,
            "filename": "dlltracer-1.0.2-cp38-cp38-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "b6373afe5d51567a577f5f14bb52bffe",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 87624,
            "upload_time": "2023-10-02T11:53:37",
            "upload_time_iso_8601": "2023-10-02T11:53:37.341328Z",
            "url": "https://files.pythonhosted.org/packages/84/09/c660b592b84c392ae57e527b8f39a0b3fc8ea84783856836ecd242ef53f7/dlltracer-1.0.2-cp38-cp38-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "642ffe85b65bdfe53d0eeaa259d644136388c512df9355b65e409278eb156ab4",
                "md5": "f779f6cf067c0b1a88c1486965901618",
                "sha256": "92f382b11f76fd75f87e2d3dcc8f22c27f7f765c56251fc1c970bb403bb2334c"
            },
            "downloads": -1,
            "filename": "dlltracer-1.0.2-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "f779f6cf067c0b1a88c1486965901618",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 87551,
            "upload_time": "2023-10-02T11:53:38",
            "upload_time_iso_8601": "2023-10-02T11:53:38.789931Z",
            "url": "https://files.pythonhosted.org/packages/64/2f/fe85b65bdfe53d0eeaa259d644136388c512df9355b65e409278eb156ab4/dlltracer-1.0.2-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "20e5e3d0809e0a6c7f1518ebc9a7a917201349287794280d908ab6b5b487dec9",
                "md5": "afee2c66c34596154273172f912a8f73",
                "sha256": "7749c30d6372bfb3e5c1d624b0d5d05580b7fc3de92dfaa4f41ef1e5180d219c"
            },
            "downloads": -1,
            "filename": "dlltracer-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "afee2c66c34596154273172f912a8f73",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 109939,
            "upload_time": "2023-10-02T11:53:30",
            "upload_time_iso_8601": "2023-10-02T11:53:30.481109Z",
            "url": "https://files.pythonhosted.org/packages/20/e5/e3d0809e0a6c7f1518ebc9a7a917201349287794280d908ab6b5b487dec9/dlltracer-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-02 11:53:30",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "microsoft",
    "github_project": "dlltracer-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "dlltracer"
}
        
Elapsed time: 0.12577s