设置为开发人员模式时,Cygwin不再支持Flask应用

前端之家收集整理的这篇文章主要介绍了设置为开发人员模式时,Cygwin不再支持Flask应用 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

尝试在后台使用以下命令运行我的python flask应用程序后,立即发生了此问题:

$python app.py&

这立即失败了.之后,以后我再也没有问题地尝试运行该应用程序,最终都会出现此错误

 $python app.py
Running on http://127.0.0.1:8050/
Debugger PIN: 962-843-370
 * Serving Flask app "app" (lazy loading)
 * Environment: development
 * Debug mode: on
      2 [main] python3.6m 37104 child_info_fork::abort: unable to remap _lbfgsb.cpython-36m-x86_64-cygwin.dll to same address as parent (0x48E0000) - try running rebaseall
Traceback (most recent call last):
  File "app.py",line 644,in <module>
    app.run_server(debug=util.DEBUG)
  File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/dash/dash.py",line 1293,in run_server
    **flask_run_options)
  File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/flask/app.py",line 943,in run
    run_simple(host,port,self,**options)
  File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/werkzeug/serving.py",line 812,in run_simple
    reloader_type)
  File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/werkzeug/_reloader.py",line 275,in run_with_reloader
    sys.exit(reloader.restart_with_reloader())
  File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/werkzeug/_reloader.py",line 132,in restart_with_reloader
    close_fds=False)
  File "/usr/lib/python3.6/subprocess.py",line 267,in call
    with Popen(*popenargs,**kwargs) as p:
  File "/usr/lib/python3.6/subprocess.py",line 709,in __init__
    restore_signals,start_new_session)
  File "/usr/lib/python3.6/subprocess.py",line 1275,in _execute_child
    restore_signals,start_new_session,preexec_fn)
BlockingIOError: [Errno 11] Resource temporarily unavailable
@H_502_11@

错误似乎源于在开发人员模式下运行,因为当我使用app.run_server(debug = False)运行时(顺便说一句,在我的本地环境中util.DEBUG设置为True),该应用程序运行良好,但随后我没有进行热装,这对我很重要.

我已尝试根据此帖子https://superuser.com/a/194537/276726重新设置cygwin,但这并不能解决任何问题.

我也尝试按照this post中的步骤创建一个特殊的变基文件,但这也无济于事.

该应用程序可从Windows命令行以开发模式运行,因此这是我目前的临时修复程序,但我希望我的Cygwin设置能够再次正常运行.

谢谢您的帮助!

最佳答案
在Cygwin世界中,您遇到了一个非常普遍的问题.有很多提到(处理)URL的URL,但是我将列出遇到的URL:

> [SO]: Cygwin error: “-bash: fork: retry: Resource temporarily unavailable”
> [SO]: Cygwin issue – unable to remap; same address as parent
> [SuperUser]: Cygwin fatal error unable to remap.. What does it mean?
> [WordPress]: Cygwin and Rails – unable to remap to same address as parent; died waiting for dll loading,errno 11
> [SO]: Cygwin error: “child_info_fork::abort: Loaded to different address:”

[Cygwin]: Problems with process creation中很好地解释了“幕后魔术”(重点是我的):

The semantics of fork@H_502_11@ require that a forked child process have exactly the same address space layout as its parent. However,Windows provides no native support for cloning address space between processes and several features actively undermine a reliable fork@H_502_11@ implementation. Three issues are especially prevalent:

  • DLL base address collisions. Unlike *nix shared libraries,which use “position-independent code”,Windows shared libraries assume a fixed base address. Whenever the hard-wired address ranges of two DLLs collide (which occurs quite often),the Windows loader must “rebase” one of them to a different address. However,it may not resolve collisions consistently,and may rebase a different dll and/or move it to a different address every time. Cygwin can usually compensate for this effect when it involves libraries opened dynamically,but collisions among statically-linked dlls (dependencies known at compile time) are resolved before cygwin1.dll@H_502_11@ initializes and cannot be fixed afterward. This problem can only be solved by removing the base address conflicts which cause the problem,usually using the rebaseall@H_502_11@ tool.
  • Address space layout randomization (ASLR). Starting with Vista,Windows implements ASLR,which means that thread stacks,heap,memory-mapped files,and statically-linked dlls are placed at different (random) locations in each process. This behavIoUr interferes with a proper fork@H_502_11@,and if an unmovable object (process heap or system dll) ends up at the wrong location,Cygwin can do nothing to compensate (though it will retry a few times automatically).

尝试在[Cygwin.FAQ]: 4.45. How do I fix fork() failures?中进行故障排除(重点仍然存在).冒着散布答案的风险,我将其粘贴在这里:

Unfortunately,Windows does not use the fork/exec model of process creation found in UNIX-like OSes,so it is difficult for Cygwin to implement a reliable and correct fork()@H_502_11@,which can lead to error messages such as:

  • unable to remap somedll to same address as parent
  • couldn’t allocate heap
  • died waiting for dll loading
  • child -1 – died waiting for longjmp before initialization
  • STATUS_ACCESS_VIOLATION
  • resource temporarily unavailable

Potential solutions for the above errors:

  • Restart whatever process is trying (and failing) to use fork()@H_502_11@. Sometimes Windows sets up a process environment that is even more hostile to fork()@H_502_11@ than usual.
  • Ensure that you have eliminated (not just disabled) all software on the 07007.
  • Switch from 32-bit Cygwin to 64-bit Cygwin,if your OS and cpu support that. With the bigger address space fork() is less likely to fail.
  • Try setting the environment variable CYGWIN to “detect_bloda”,which enables some extra debugging,which may indicate what other software is causing the problem.

    See 07008 for more information.

  • Force a full rebase: Run rebase-trigger fullrebase,exit all Cygwin programs and run Cygwin setup.

    By default,Cygwin’s setup program automatically performs an incremental rebase of newly installed files. Forcing a full rebase causes the rebase map to be cleared before doing the rebase.

    See /usr/share/doc/rebase/README and /usr/share/doc/Cygwin/_autorebase.README for more details.

    Please note that installing new packages or updating existing ones undoes the effects of rebase and often causes fork()@H_502_11@ failures to reappear.

See the 07009 section of the User’s Guide for the technical reasons it is so difficult to make fork()@H_502_11@ work reliably.

为了重现该问题,我使用了:

> Cygwin 32:

>遇到问题的机会要高得多
>这不是我的主要Cygwin环境

> Python 3.6.4 VEnv

>位于/home/cfati/Work/Dev/VEnvs/py_032_03.06.04_test0

我尝试重现您的确切行为(使用_lbfgsb * .dll),但是pip -v install scipy无法构建它.由于[SciPy]: Installing SciPy on Windows描述了一个相当复杂的过程,并且我无法保证最后我能够重现该问题,因此我尝试使用numpy的.dll(numpy已成功安装为scipy依赖项),但我没有这样做.能够(作为副作用,import numpy加载了一堆.dll),但是(通过subprocess.Popen)调用fork并没有失败.然后,我决定亲自处理这个问题,并创建一个加载一些.dll的小程序,然后分叉自身(同样,通过subprocess.Popen),以使问题尽可能重现.

dll.c:

#include <stdio.h>

#if defined(_WIN32)
#  define DLL_EXPORT __declspec(dllexport)
#else
#  define DLL_EXPORT
#endif


DLL_EXPORT int test() {
    printf("[%s] (%d) - [%s]\n",__FILE__,__LINE__,__FUNCTION__);
}
@H_502_11@

code.py:

#!/usr/bin/env python3

import sys
import os
import subprocess
import time
import select
import random
import ctypes


DLLS = [os.path.join(os.path.dirname(__file__),"dll{:d}.dll".format(item)) for item in range(2)]


def main():
    random.seed(os.getpid())
    random.shuffle(DLLS)
    if len(sys.argv) == 1:
        print("Python {:s} on {:s}\n".format(sys.version.replace("\n",""),sys.platform))
        print("Process 0x{:08X}".format(os.getpid()))
        for dll in DLLS:
            ctypes.cdll.LoadLibrary(dll)
        idx = 0
        while sys.stdin not in select.select([sys.stdin],[],1)[0]:
            p = subprocess.Popen([sys.executable] + sys.argv + [str(idx)])
            #p.communicate()
            time.sleep(1)
            idx += 1

    else:
        sleep_time = 3
        print("Process 0x{:08X} (inner) will end in {:d} seconds".format(os.getpid(),sleep_time))
        time.sleep(sleep_time)


if __name__ == "__main__":
    main()
@H_502_11@

笔记:

>情况有所不同,我有一个常规的(虚拟).dll,而不是Python扩展模块,我尝试通过[Python 3.Docs]: ctypes – A foreign function library for Python加载它.无论Python如何看待它(作为一个模块),这都没有区别.,或作为外部.dll),仍然必须将其加载到进程中(以相同的方式)
>场景是:

>我加载了2个这样的.dll(实际上是相同的.dll以不同的名称复制,因此它们都具有相同的首选基址),因此第一个.dll可能会加载到该地址,而下一个.dll将装在另一个
>然后我分叉该过程,并在子级中基于随机因素切换.dll加载顺序
>当第二个.dll将在首选库中加载时,将与父进程不一致,从而产生错误

>最初,所有内容都在我的cwd中,然后(为了更贴近您的问题),我用文件创建了一个Python包.请注意,我没有采取正确的方式(通过setup.py文件安装),而是手动复制了所有内容

06002

因此,该错误是非常可重现的.我还要在此添加.dll详细信息(Dependency Walker):

Img0

定期重新设置基准(rebaseall)为什么不能解决问题?

> Cygwin软件包具有一个安装后脚本,该脚本在其.dll上调用重新设置
>在标准库路径(/ lib,/usr/lib,…)中重新搜索.可以根据/usr/share/doc/Cygwin/_autorebase.README进行调整:

Packages can make the potential locations of such dynamic objects
known by dropping a file (named after the package) in
/var/lib/rebase/dynpath.d/. If any dynamic objects are installed by
users,these locations should be advertised in /var/lib/rebase/user.d/
(the file name should be identical to the user name if there are
multiple users on this system)

由于包可能包含.dll,因此Python需要进行此类调整.
>点子一样的软件包没有安装后脚本(该脚本会重新设置其.dll)
> VEnv位于用户的主路径中,而不位于标准库路径中(因此,即使是rebaseall也会忽略它们)

请注意,所有重新基于基础的.dll文件都存储在DB:/etc/rebase.db(.${ARCH})中.

06003

为了使.dll被变基工具拾取,需要对它们进行公告.这可以通过两种方式完成:

>在其中一个自定义位置中指定它们,因此在下一次完全重新配置时,它们将不再被忽略(只需添加VEnv目录以及其他(如果有的话)):

06004

>手动重新建立.dll的基准

他们两个都为我工作,但是我将仅以第二变体为例(因为它更简单).该过程包括2个步骤:

>创建所有需要重新建立基础的.dll的列表

06005

>执行基准

>必须关闭所有Cygwin进程(包括服务:例如sshd)
>我从dash.exe(从Win,从Cygwin bin dir直接启动)启动命令,而不是从Mintty(注意提示)启动命令

06006

更新后的Dependency Walker窗口(检查其“首选基础”,并将其与上一张图像进行比较):

Img1

以及重新设置数据库的“查询”(现在从Mintty返回):

06007

更重要的是,运行代码

06008

如图所示,它能够多次分叉(它只是因为按Enter才停止).

猜你在找的Python相关文章