cs01 / gdbgui

Browser-based frontend to gdb (gnu debugger). Add breakpoints, view the stack, visualize data structures, and more in C, C++, Go, Rust, and Fortran. Run gdbgui from the terminal and a new tab will open in your browser.
https://gdbgui.com
GNU General Public License v3.0
9.9k stars 499 forks source link

Fails to start with `KeyError: WERKZEUG_SERVER_FD` #425

Closed hunger closed 2 years ago

hunger commented 2 years ago

Describe the bug

gdbgui does not start. It fails with KeyError: WERKZEUG_SERVER_FD.

To Reproduce

  1. pipx install gdbgui
  2. gdbgui

I get this output:

1โžœ gdbgui
Opening gdbgui with default browser at http://127.0.0.1:5000
View gdbgui dashboard at http://127.0.0.1:5000/dashboard
exit gdbgui by pressing CTRL+C
Traceback (most recent call last):
  File "/home/dev/.local/bin/gdbgui", line 8, in <module>
    sys.exit(main())
  File "/home/dev/.local/pipx/venvs/gdbgui/lib/python3.10/site-packages/gdbgui/cli.py", line 249, in main
    run_server(
  File "/home/dev/.local/pipx/venvs/gdbgui/lib/python3.10/site-packages/gdbgui/server/server.py", line 95, in run_server
    socketio.run(
  File "/home/dev/.local/pipx/venvs/gdbgui/lib/python3.10/site-packages/flask_socketio/__init__.py", line 596, in run
    app.run(host=host, port=port, threaded=True,
  File "/home/dev/.local/pipx/venvs/gdbgui/lib/python3.10/site-packages/flask/app.py", line 920, in run
    run_simple(t.cast(str, host), port, self, **options)
  File "/home/dev/.local/pipx/venvs/gdbgui/lib/python3.10/site-packages/werkzeug/serving.py", line 1047, in run_simple
    fd = int(os.environ["WERKZEUG_SERVER_FD"])
  File "/usr/lib/python3.10/os.py", line 679, in __getitem__
    raise KeyError(key) from None
KeyError: 'WERKZEUG_SERVER_FD'

The firefox browser pops up before this output shows up but only shows an empty page.

Expected behavior

Gbdgui starts up and does something.

Please complete the following information:

Additional context I tried running this inside an systemd-nspawn container, which does cause trouble sometimes. But this does not look like the typical container issue.

saeugetier commented 2 years ago

Try an older version of python library "werkzeug". Version 2.1.0 was faulty for me. Version 2.0.0 does work.

pip install werkzeug==2.0.0

zenbooster commented 2 years ago

Same problem. Werkzeug==2.0.0

hunger commented 2 years ago

Can this be fixed upstream by pinning the expected werkzeug version somehow? This is a pretty bad first-use impression!

saeugetier commented 2 years ago

I think allways the latest version of Werkzeug is used. Werkzeug 2.1.0 is recently released: https://pypi.org/project/Werkzeug/#history Maybe a patch is necessary to fix that problem.

BIAOXYZ commented 2 years ago

I also met this issue, solved by reinstallation of werkzeug 2.0.0

davidism commented 2 years ago

https://github.com/cs01/gdbgui/blob/799d34051419653cfda7d068806f853007d46fac/gdbgui/server/server.py#L93

This line is why it's failing. You're tricking Werkzeug into thinking it's running in the reloader, when it's not. This breaks the environment it expects to find when starting the server. Remove this line.

It seems this might have been done to enable debug=True while disabling the reloader? If that's the case, then the correct way to do that is to do app.run(debug=True, use_reloader=False).

mattans commented 2 years ago

https://github.com/cs01/gdbgui/blob/799d34051419653cfda7d068806f853007d46fac/gdbgui/server/server.py#L93

This line is why it's failing. You're tricking Werkzeug into thinking it's running in the reloader, when it's not. This breaks the environment it expects to find when starting the server. Remove this line.

It seems this might have been done to enable debug=True while disabling the reloader? If that's the case, then the correct way to do that is to do app.run(debug=True, use_reloader=False).

While I agree with you, expliciltly setting os.environ['WERKZEUG_RUN_MAIN'] = 'true' is a widely used trick to hide the console prints:

 * Serving Flask app '' (lazy loading)
 * Environment: development
 * Debug mode: off

Do you have an idea how to hide these prints in werkzeug 2.1.0? Because this will probably prevent many people from upgrading from werkzeug 2.0.0

davidism commented 2 years ago

You don't. That output is there for a reason, we want to very strongly make people aware that they are running a development server, and that it is not meant for production. The fact that setting an internal setup variable happened to suppress it was unintentional and never guaranteed to work.

"Production" means "not developing the application itself", even if it's a local application. The development server is not particularly secure, stable, or efficient. One way is to use a production server, such as waitress, which you can also import and run from Python code.

If you're really, really sure it's ok to run the development server and also don't want the output, then you can use make_server to create a server and call s.serve_forever() instead (possibly in a thread). This allows you to manually set up the server without all the other stuff that run_simple does. Again, be very very sure that running the development server is what you want for your users.

mattans commented 2 years ago

Thanks for the answer.

scotter1995 commented 2 years ago

Installing werkzeug 2.0 hasn't actually solved the issue for me.

otinkyad commented 2 years ago

I get the same error as the OP, and installing werkzeug 2.0 does not solve the issue for me. Not sure if this is relevant: I'm running everything from within anaconda, on Xubuntu 20.04.

gdbgui with no customization did work for me about five days ago, but since that time I've reinstalled the OS and anaconda, pipx, and gdbgui, which seems consistent with something having changed in the last few days.

ElectricLab commented 2 years ago

Downgrading to 2.0.0 worked for me, on a newly installed Debian 11 system.

sunyiynus commented 2 years ago

I get the same error as the OP, and installing werkzeug 2.0 does not solve the issue for me. Not sure if this is relevant: I'm running everything from within anaconda, on Xubuntu 20.04.

gdbgui with no customization did work for me about five days ago, but since that time I've reinstalled the OS and anaconda, pipx, and gdbgui, which seems consistent with something having changed in the last few days.

Me too

sunyiynus commented 2 years ago

I reinstall werkzeug 2.0.0. It does fix this issue for me. My env: ubuntu 20.4 LTS

rempas commented 2 years ago

Installing werkzeug 2.0 hasn't actually solved the issue for me.

You still having problems dude?

otinkyad commented 2 years ago

Not sure about @scotter1995, but werkzeug 2.0.0 has still not solved the issue for me. I've tried a number of times.

But I am using in what may be a somewhat unusual environment (from Anaconda3, on Xubuntu 20.04 LTS). So I'm currently setting up Ubuntu 20.4 LTS in a VM and will install on that directly, andd without Anaconda. Will report back...

UPDATE: Nope, not working for me. Installed gdbgui in Ubuntu 20.04 LTS VM (no Anaconda mediation). Reverted werkzeug to 2.0.0. Still the same error: verbatim with the error listing from OP.

Moving on to a different GUI debugger...

otinkyad commented 2 years ago

FURTHER UPDATE:

Decided to try one last thing. Following the suggestion made by @davidism I commented out line 93 in server.py.

Now it works for me.

[AND, LAST BUT NOT LEAST]: gdbgui is terrific! Many thanks and kudos to dev!

cs01 commented 2 years ago

Hi everyone, sorry for all the hassle with this issue. Looks like something needs to be adjusted in gdbgui's dependencies. I'll try to get to this but unfortunately have been extremely busy and unable to carve out time. You may have luck with a prebuilt binary or a pex from the releases page.

MykolaMoshak commented 2 years ago

Hi everyone, I had the same issue with the werkzeug. I installed the gdbgui by following the instructions (Method 1) from here: https://www.gdbgui.com/installation/ and I was not able to start the tool due to the werkzeug, even with werkzeug==2.0.0. Afterwards I uninstalled the tool and installed it again but this time I used the second method and it worked for me.

mconigliaro commented 2 years ago

You don't

Challenge accepted.

import flask.cli
flask.cli.show_server_banner = lambda *args: None

No more annoying console text. Enjoy!

Update with hilarious comment @davidism posted and deleted for some reason:

I didn't say you can't, I said you don't. Don't do that. You're doing yourself and your users a disservice by hiding the security related message saying not to use the development server outside development.

  1. Trying to dictate your use of open source software.
  2. Assuming he knows better than you about who your users are and/or what your software does.

God I love the internet. ๐Ÿ˜‚

sethmlarson commented 2 years ago

Assuming he knows better than you about who your users are and/or what your software does.

As the maintainer of the framework dependencies in your software I'd say that puts David in a position to know a good deal about what's best for your users. It's unfortunate for them that you're not listening.

cs01 commented 2 years ago

to know a good deal about what's best for your users

I am the owner/maintainer of this project, not @mconigliaro or anyone else. I unfortunately have not had time to work on anything open source lately, though there are plenty of things I'd like to improve on here.

davidism commented 2 years ago

Sorry this turned into a weird discussion in your tracker, that's not what I intended when I originally commented. I think you can actually solve this in a fairly straightforward way: remove the env var line, and add eventlet or gevent as a requirement. Flask-SocketIO's run should pick that up and use it instead of the dev server. I've submitted a PR for that.

mconigliaro commented 2 years ago

This is just one of the first things that came up when I searched for "WERKZEUG_SERVER_FD," so I thought I'd share my solution. Sorry if you don't like it. Have a good day everyone. ๐Ÿ˜

laoshaw commented 2 years ago

same issue here, downgrade werkzeug to 2.0.0 worked

zhztheplayer commented 2 years ago

In my case pip install werkzeug==2.0.0 solved this issue for a pip installation of gdbgui.

The same doesn't work for a pipx installation of gdbgui.

peterbone-bo commented 2 years ago

Had the same error after installing using pipx.

Solution

pipx uninstall gdbgui pip install gdbgui pip install werkzeug==2.0.0

vxlcoder commented 2 years ago

I ran into the same issues. @peterbone-bo's workaround worked for me: installing gdbgui and werkzeug version 2.0.0 using pip, not pipx.

marcellodesales commented 2 years ago

Had the same error after installing using pipx.

Solution

pipx uninstall gdbgui pip install gdbgui pip install werkzeug==2.0.0

This helped me run AWS SAM SERVER on a docker container! Thank you!

damentz commented 2 years ago

It looks like the werkzeug code can be changed itself. Not sure if this is smart, but the hint was here:

  File "/usr/lib/python3.10/site-packages/werkzeug/serving.py", line 1063, in run_simple
    fd = int(os.environ["WERKZEUG_SERVER_FD"])
  File "/usr/lib/python3.10/os.py", line 679, in __getitem__
    raise KeyError(key) from None

In serving.py, it's a conditional that looks like so:

    if not is_running_from_reloader():
        s = prepare_socket(hostname, port)
        fd = s.fileno()
        os.environ["WERKZEUG_SERVER_FD"] = str(fd)
    else:
        fd = int(os.environ["WERKZEUG_SERVER_FD"])

Modifying the code so the not is_running_from_reloader() section always runs fixed my use case invoking sam local start-api for AWS's SAM CLI:

--- serving.py.orig 2022-08-30 06:29:39.000000000 -0500
+++ serving.py  2022-08-30 16:53:56.760826087 -0500
@@ -1055,12 +1055,9 @@ def run_simple(

         application = DebuggedApplication(application, evalex=use_evalex)

-    if not is_running_from_reloader():
-        s = prepare_socket(hostname, port)
-        fd = s.fileno()
-        os.environ["WERKZEUG_SERVER_FD"] = str(fd)
-    else:
-        fd = int(os.environ["WERKZEUG_SERVER_FD"])
+    s = prepare_socket(hostname, port)
+    fd = s.fileno()
+    os.environ["WERKZEUG_SERVER_FD"] = str(fd)

     srv = make_server(
         hostname,

Not sure if this is a bug in werkzeug or a bug with the code invoking it. Either way, this change got me past the error.

davidism commented 2 years ago

I'm unsubscribing from this issue, which is about gdbgui specifically and is fixed. This is not the place to report other libraries issues with using the Werkzeug development server properly, nor is it a good idea to make any of the patches suggested here. @cs01 I suggest you lock this issue to avoid further off topic discussion.