-
-
Notifications
You must be signed in to change notification settings - Fork 18.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable ASAN/UBSAN in pandas CI #55102
Conversation
@@ -25,8 +25,8 @@ runs: | |||
- name: Build Pandas | |||
run: | | |||
if [[ ${{ inputs.editable }} == "true" ]]; then | |||
pip install -e . --no-build-isolation -v | |||
pip install -e . --no-build-isolation -v --config-settings=setup-args="-Db_sanitize=address,undefined" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably don't want to hard code this - is there a way with GHA to only do this for certain action invocations @lithomas1 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can define an input
above in the workflow and pass a variable from the job when you want to enable these flags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can push to your branch if you need any help with this, but it should be as Matt stated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to push
.github/workflows/unit-tests.yml
Outdated
@@ -157,19 +157,25 @@ jobs: | |||
- name: Build Pandas | |||
id: build | |||
uses: ./.github/actions/build_pandas | |||
env: | |||
CFLAGS: "$CFLAGS -fno-sanitize-recover=all" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meson has the config option for b_sanitize=address,undefined
but I don't think it set this. UBSAN has non-fatal errors, so without this things just get printed to stderr and pytest still continues.
Looks like NumPy does something similar with halt_on_error=1
, but that didn't seem to stop pytest from continuing as I tried this locally
.github/workflows/unit-tests.yml
Outdated
@@ -154,22 +154,36 @@ jobs: | |||
with: | |||
environment-file: ci/deps/${{ matrix.env_file }} | |||
|
|||
- name: Set sanitizer flags | |||
run: | | |||
echo "CFLAGS=$CFLAGS -fno-sanitize-recover=all" >> "$GITHUB_ENV" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having trouble setting this with GHA. There may also be a way to pass the flag directly through meson python? @lithomas1 any idea?
.github/workflows/unit-tests.yml
Outdated
- name: Build Pandas | ||
id: build | ||
uses: ./.github/actions/build_pandas | ||
env: | ||
CFLAGS: "$CFLAGS" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, this doesn't set CFLAGS inside of the action. It just makes CFLAGS available under env.CFLAGS
.
Why don't you try setting CFLAGs in action.yml directly if sanitize = true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah great idea - much cleaner
Somewhat working now. Guessing we need a way for pytest-xdist to fail and signal the test it failed on. Right now looks like a worker just crashed |
This looks pretty good to me. Let me Cc @ngoldbaum, who implemented the NumPy CI job and has more experience with these sanitizers than I have. |
Ah that's probably why the |
IMO I would add 1 new testing job in the matrix (e.g. that uses a 3.11 dependency file) that runs the tests with sanitize=True and python xdist with |
In that case are you still planning to run against the entire test base or a subset of modules? I think removing multiple workers would slow down our CI a good deal? But maybe this gets to a state where it only runs when C/Cython files are touched? |
Worth noting I tried |
We should do a minimal run, kind of like the npdev situation. So only us, numpy, and arrow installed. |
Since the GHA Ubuntu runners only have 2 cores, I think running the entire test suite (even with all the dependencies) with FWIW that's how the Windows tests run currently and they take 15ish minutes longer than the non xdist runs |
In theory the average runtime of ASAN would be 2x (see https://github.com/google/sanitizers/wiki/AddressSanitizer), though since we are not detecting leaks but also adding UBSAN I'm not sure how that all evens out |
A lot of the datetime stuff in this PR is hacked together just to appease UBSAN, but there are definitely quite a few code paths where datetime conversions can lead to undefined behavior. The current ASAN failure looks like it comes from matplotlib, so @lithomas1 is probably right in that we need to pare this down to a smaller set of packages that we know can be clean |
Gotcha. Or rather, if we introduce undefined behavior and address violations, this job will hopefully fail correct? Just want to ensure there's a definitive |
Yes exactly - this will fail when either of those are detected |
The error messaging you see in CI is something that could be improved. It just "fails" right now but that feedback gets lost along the way from the crashed process. I think that can be tackled in a follow up |
This is what happens today if either of these pops up: https://github.com/pandas-dev/pandas/actions/runs/7066657149/job/19241456914#step:8:61 |
Ah OK. Could you at least include a |
OK sure. Here is what that looks like: https://github.com/pandas-dev/pandas/actions/runs/7267349987/job/19800967532?pr=55102#step:8:18053 Ends up being too much for GHA to show but if you go to the raw logs you will see the error:
|
Great thanks! |
Hm, I wonder if there's a better way to do this. Do you know if e.g. something like |
Is there anything particular to CI that we know of that does not redirect stderr from pytest-xdist to the logs? If you run things locally you get the error and a stacktrace. While that isn't 1-to-1 to the test name it is pretty helpful to figure out what is going on so might be the best medium |
If I understand your question, this is a pytest xdist limitation: https://pytest-xdist.readthedocs.io/en/stable/known-limitations.html#output-stdout-and-stderr-from-workers I know the |
I agree. I don't mean to block this PR, but maybe we should look into the reporting a little more? At the very least, I think I could settle for a solution where we get pytest to print the filenames of the tests. Would this work? |
OK here is what @lithomas1 suggestion looks like: https://github.com/pandas-dev/pandas/actions/runs/7281808581/job/19843041899?pr=55102#step:8:590 Out of the two options so far I would prefer to go that route. It looks like turning off pytest-xdist for the ASAN build had little to no effect on the overall runtime |
Ok, this looks correct to me, at a first glance. Just to double check, the failing test happens in |
This reverts commit 677da0e.
Yea it does happen in test_common. I suppose the downside to this one is you don't get exactly the test that failed, but the first one I see failing locally is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (pending resolution of Matt's last comment)!
Excited to see this finally go in.
Awesome! Thanks @WillAyd |
* enable ASAN/UBSAN in pandas CI * try input * try removing sanitize * try no CFLAGS * try GH string substituion * change flags in build script * quotes * update script run * single_cpu updates * asan checks for datetime funcs * try smaller config * checkpoint * bool fixup * reverts * known UB marker * Finished marking tests with known UB * dedicated CI job * identifier fix * fixes * more test skip * try quotes * simplify ci * try CFLAGS * preload args * skip single_cpu tests * wording * removed unneeded marker * float set implementations * Revert "float set implementations" This reverts commit 6266422. * change marker name * dedicated actions file * consolidated into matrix * fixup * typos * fixups * add qt? * intentional UB with verbose * disable pytest-xdist * original issue * remove UB * Revert "remove UB" This reverts commit 677da0e. * merge fixup * remove UB --------- Co-authored-by: Thomas Li <[email protected]>
@lithomas1 @rgommers
closes #52990