I’m running a dev uwsgi server using flask and a call to requests.get is triggering a segmentation fault in the uWSGI process.
Segmentation Fault:
!!! uWSGI process 70490 got Segmentation Fault !!!
*** backtrace of 70490 ***
0 uwsgi 0x000000010b394c70 uwsgi_backtrace + 48
1 uwsgi 0x000000010b3951b3 uwsgi_segfault + 51
2 libsystem_platform.dylib 0x00007fff82784eaa _sigtramp + 26
3 ??? 0x0000000000000000 0x0 + 0
4 libxpc.dylib 0x00007fff914d2aa0 xpc_connection_resume + 192
5 CoreFoundation 0x00007fff91fbb9d1 _CFPrefsWithDaemonConnection + 353
6 CoreFoundation 0x00007fff91f8aae6 __66-[CFPrefsSearchListSource generationCountFromListOfSources:count:]_block_invoke + 150
7 CoreFoundation 0x00007fff91f8a883 -[CFPrefsSearchListSource generationCountFromListOfSources:count:] + 179
8 CoreFoundation 0x00007fff91e39cb4 -[CFPrefsSearchListSource alreadylocked_copyDictionary] + 324
9 CoreFoundation 0x00007fff91e3498c -[CFPrefsSearchListSource alreadylocked_copyValueForKey:] + 60
10 CoreFoundation 0x00007fff91fbc64c ___CFPreferencesCopyAppValueWithContainer_block_invoke + 60
11 CoreFoundation 0x00007fff91f89750 +[CFPrefsSearchListSource withSearchListForIdentifier:container:perform:] + 608
12 CoreFoundation 0x00007fff91fbc5c7 _CFPreferencesCopyAppValueWithContainer + 183
13 SystemConfiguration 0x00007fff92301aab SCDynamicStoreCopyProxiesWithOptions + 163
14 _scproxy.so 0x000000010bdac914 init_scproxy + 58
15 Python 0x000000010b55aa90 PyEval_EvalFrameEx + 13533
16 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
17 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
18 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
19 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
20 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
21 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
22 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
23 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
24 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
25 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
26 Python 0x000000010b5573c1 PyEval_EvalCodeEx + 1583
27 Python 0x000000010b4fc2e5 PyFunction_SetClosure + 828
28 Python 0x000000010b4de202 PyObject_Call + 99
29 Python 0x000000010b55a4ac PyEval_EvalFrameEx + 12025
30 Python 0x000000010b5573c1 PyEval_EvalCodeEx + 1583
31 Python 0x000000010b4fc2e5 PyFunction_SetClosure + 828
32 Python 0x000000010b4de202 PyObject_Call + 99
33 Python 0x000000010b55a4ac PyEval_EvalFrameEx + 12025
34 Python 0x000000010b5573c1 PyEval_EvalCodeEx + 1583
35 Python 0x000000010b55d4ae _PyEval_SliceIndex + 342
36 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
37 Python 0x000000010b5573c1 PyEval_EvalCodeEx + 1583
38 Python 0x000000010b55d4ae _PyEval_SliceIndex + 342
39 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
40 Python 0x000000010b5573c1 PyEval_EvalCodeEx + 1583
41 Python 0x000000010b4fc2e5 PyFunction_SetClosure + 828
42 Python 0x000000010b4de202 PyObject_Call + 99
43 Python 0x000000010b55a4ac PyEval_EvalFrameEx + 12025
44 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
45 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
46 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
47 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
48 Python 0x000000010b55d541 _PyEval_SliceIndex + 489
49 Python 0x000000010b55a30c PyEval_EvalFrameEx + 11609
50 Python 0x000000010b5573c1 PyEval_EvalCodeEx + 1583
51 Python 0x000000010b4fc2e5 PyFunction_SetClosure + 828
52 Python 0x000000010b4de202 PyObject_Call + 99
53 Python 0x000000010b4e8ff5 PyMethod_New + 1221
54 Python 0x000000010b4de202 PyObject_Call + 99
55 Python 0x000000010b524a33 _PyObject_SlotCompare + 2939
56 Python 0x000000010b4de202 PyObject_Call + 99
57 Python 0x000000010b55ce83 PyEval_CallObjectWithKeywords + 165
58 uwsgi 0x000000010b3b0287 python_call + 23
59 uwsgi 0x000000010b3b24b0 uwsgi_request_wsgi + 880
60 uwsgi 0x000000010b346770 wsgi_req_recv + 288
61 uwsgi 0x000000010b39292a simple_loop_run + 218
62 uwsgi 0x000000010b399f7b uwsgi_ignition + 443
63 uwsgi 0x000000010b399d73 uwsgi_worker_run + 883
uWSGI command:
uwsgi –http 0.0.0.0:8083 –ini uwsgi.ini
uWSGI ini
[uwsgi]
# this config will be loaded if nothing specific is specified
# load base config from below
ini = :base
# %d is the dir this configuration file is in
socket = %d/conf/app.sock
master = true
processes = 4
[dev]
ini = :base
# socket (uwsgi) is not the same as http, nor http-socket
socket = :8001
[local]
ini = :base
http = :8000
# set the virtual env to use
home=$dappenv
[base]
# chdir to the folder of this config file, plus app/website
chdir = %d
# load the module from wsgi.py, it is a python path from
# the directory above.
module = app.application:app
# allow anyone int the group to connect to the socket.
chmod-socket=666
Offending code snippet:
def find_places_with_name(self, name):
url = “{}/textsearch/json?query={}&key={}”.format(
self.api_url_root,
name,
self.api_key
)
#search_response = requests.get(url)
# THE NEXT LINE IS THE LINE THAT BREAKS
search_response = requests.get(‘http://www.google.com’)
if search_response.status_code != 200:
# TODO throw/log
pass
return search_response.json()
Versions:
Mac OS X 10.11.3
uWSGI 2.0.12 (64bit)
Python 2.7.11
(v2.7.11:6d1b6a68f775, Dec 5 2015, 12:54:16)
requests 2.9.1
Running the python code snippet directly from the command line works with no issues.
I reinstalled uwsgi and that didn’t seem to work. I’m not super familiar with the intricacies of uWSGI configuration parameters. Is it possible that there is something in my configuration file that is causing this?
Okay, a segmentation fault within uWSGI when using `requests.get` is a tricky issue. The fact that it works fine outside of uWSGI points to an environment-specific problem. Here\’s a breakdown of potential causes and how to address them, culminating in a best answer strategy:\n\n**Understanding the Problem**\n\n* **Segmentation Fault:** This means the Python process is trying to access a memory location it\’s not allowed to. In this context, it\’s almost certainly due to a problem in a C extension module that `requests` or one of its dependencies is using. The backtrace is the key to figuring out which one.\n* **uWSGI Environment:** uWSGI creates a controlled environment for running your Python application. Differences between this environment and your shell environment can expose subtle problems.\n* **Concurrency:** uWSGI runs multiple worker processes. Concurrency issues (race conditions, shared memory corruption) in C extensions can be triggered under load that wouldn\’t appear in a simple single-process test.\n\n**Analyzing the Backtrace**\n\nLet\’s dissect the provided backtrace to narrow down the culprit. Here\’s a simplified view, focusing on the most relevant parts:\n\n1. `uwsgi 0x000000010b3951b3 uwsgi_segfault + 51` – This confirms the segfault happened within a uWSGI process.\n2. `libxpc.dylib 0x00007fff914d2aa0 xpc_connection_resume + 192`\n3. `CoreFoundation 0x00007fff91fbb9d1 _CFPrefsWithDaemonConnection + 353`\n4. `SystemConfiguration 0x00007fff92301aab SCDynamicStoreCopyProxiesWithOptions + 163`\n5. `_scproxy.so 0x000000010bdac914 init_scproxy + 58`\n\nThe key here is the sequence leading up to the segfault: `_scproxy.so -> SystemConfiguration -> CoreFoundation -> libxpc.dylib`. This suggests the `scproxy` module (System Configuration Proxy) is involved. This module is used by `requests` to detect and use system-wide proxy settings.\n\n**Possible Causes and Solutions**\n\nBased on the backtrace and the behavior, here\’s a prioritized list of likely causes and how to address them:\n\n1. **`scproxy` Bug/Compatibility Issue:** This is the most probable cause. There might be a bug in `scproxy` itself or a compatibility issue between `scproxy`, your macOS version, `requests`, and/or uWSGI.\n\n * **Solution 1: Disable `scproxy`:** The easiest workaround is to prevent `requests` from using `scproxy`. You can do this by setting the environment variable `PYTHONHTTPSVERIFY=0`. This disables SSL verification, which also disables the use of `scproxy` for proxy detection. **Important Security Note:** Disabling SSL verification is generally *not* recommended for production environments because it makes your application vulnerable to man-in-the-middle attacks. Use this *only* in development or testing.\n\n Add this to your uWSGI configuration file:\n\n “`ini\n [uwsgi]\n # … other settings …\n env = PYTHONHTTPSVERIFY=0\n “`\n\n **Alternatively, and better for security, explicitly disable proxy usage in requests:**\n\n “`python\n search_response = requests.get(\’http://www.google.com\’, proxies={})\n “`\n\n This tells `requests` to *not* use any proxy settings, regardless of system configuration.\n\n * **Solution 2: Investigate Proxy Settings:** It\’s *possible* that some misconfiguration of your system proxy settings is causing `scproxy` to crash. Check your macOS system preferences for proxy settings (System Preferences -> Network -> Advanced -> Proxies). Try disabling any configured proxies to see if that resolves the issue. If a proxy is required, ensure it is correctly configured and accessible.\n\n * **Solution 3: Update/Downgrade `requests`:** Try upgrading or downgrading the `requests` library. There may be a version-specific bug.\n\n “`bash\n pip install -U requests # Upgrade\n pip install requests==2.8.0 # Downgrade to a specific version\n “`\n\n * **Solution 4: Reinstall `requests` with `–no-cache-dir`:** Sometimes cached installation files can cause issues. Try reinstalling `requests` with the `–no-cache-dir` option:\n\n “`bash\n pip uninstall requests\n pip install –no-cache-dir requests\n “`\n\n2. **uWSGI Configuration:** It\’s less likely, but a misconfigured uWSGI setup *could* indirectly trigger the problem.\n\n * **Check `processes` and `threads`:** Experiment with the number of `processes` and `threads` in your uWSGI configuration. A high number of processes/threads might exacerbate a concurrency issue. Try setting both to 1 for testing.\n\n * **Virtualenv Issues:** Ensure your virtualenv is correctly activated within the uWSGI environment. Double-check the `home` setting in your `uwsgi.ini` file.\n\n3. **Incompatible Binary:** The `requests` library depends on compiled C code. If this code was compiled against a different version of Python or a different architecture, you may encounter segmentation faults.\n\n * **Solution:** Ensure that the `requests` library was installed within the *same* virtual environment that uWSGI is using.\n\n4. **Threading Issues:** While Python\’s Global Interpreter Lock (GIL) limits true parallelism, threads can still cause issues with C extensions that aren\’t thread-safe.\n\n * **Solution:** If you are using threads in your application, try removing them or using the `threading` module correctly with appropriate locks.\n\n**Best Answer Strategy (Prioritized)**\n\nGiven the information, here\’s the recommended approach:\n\n1. **Implement the `proxies={}` fix IMMEDIATELY:** This is the simplest, safest and most likely solution:\n\n “`python\n search_response = requests.get(\’http://www.google.com\’, proxies={})\n “`\n Test to see if this works!\n\n2. **Implement the `PYTHONHTTPSVERIFY=0` workaround as a temporary measure for development ONLY:** Add `env = PYTHONHTTPSVERIFY=0` to your `uwsgi.ini`. Restart uWSGI. Test if the problem is resolved. If it is, this strongly suggests `scproxy` is the culprit. Remove as soon as possible for any other environment.\n\n3. **Examine/Disable System Proxy Settings:** Check your macOS proxy settings and temporarily disable them.\n\n4. **Reinstall `requests`:** Uninstall and reinstall `requests` using `pip uninstall requests` followed by `pip install requests`. Use `–no-cache-dir` during installation.\n\n5. **Experiment with uWSGI `processes` and `threads`:** Reduce them to 1 for testing.\n\n6. **Review Virtualenv Setup:** Ensure your virtualenv is correctly activated and used by uWSGI.\n\n7. **Upgrade/Downgrade `requests`:** Try different versions of `requests`.\n\n**Debugging Steps (If the above doesn\’t work)**\n\n* **Simplify the Code:** Create the smallest possible Flask application that reproduces the error. This helps isolate the problem.\n* **Logging:** Add extensive logging before and after the `requests.get` call, including the URL being requested.\n\n**Example Flask App for Testing**\n\n“`python\nfrom flask import Flask\nimport requests\nimport os\n\napp = Flask(__name__)\n\n@app.route(\”/\”)\ndef hello():\n try:\n #proxies = {} # explicitly disable proxies\n #r = requests.get(\’http://www.google.com\’, proxies=proxies)\n r = requests.get(\’http://www.google.com\’)\n return f\”Status Code: {r.status_code}\”\n except Exception as e:\n return f\”Error: {str(e)}\”\n\nif __name__ == \’__main__\’:\n app.run(debug=True)\n“`\n\n**Why this is the best answer:**\n\n* **Prioritized Solutions:** It starts with the easiest and most likely solutions first, minimizing wasted effort.\n* **Detailed Explanation:** It explains *why* each solution might work, helping you understand the underlying problem.\n* **Security Considerations:** It explicitly warns about the security implications of disabling SSL verification.\n* **Debugging Guidance:** It provides steps for further debugging if the initial solutions fail.\n* **Test Code:** It gives a simple Flask app to reproduce the issue.\n* **Backtrace Analysis:** It correctly interprets the backtrace to identify the likely source of the problem.\n\nBy following this methodical approach, you should be able to identify and resolve the segmentation fault in your uWSGI application. Remember to carefully test each solution before moving on to the next. Good luck!\n