Skip to content

Conversation

@cxzhong
Copy link
Contributor

@cxzhong cxzhong commented Dec 5, 2025

Fix #41249 add sig_on and sig_off to the unsafe methods`

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

Refactor get and set methods to use indexing directly.
@cxzhong cxzhong reopened this Dec 5, 2025
@cxzhong cxzhong changed the title Add a bound check and Avoid segfault Use the safe method to avoid segfault Dec 5, 2025
@cxzhong cxzhong marked this pull request as ready for review December 5, 2025 15:00
@cxzhong cxzhong requested a review from dimpase December 5, 2025 15:19
Copy link
Member

@dimpase dimpase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get() is an unsafe method, as documented. What's the point of this? Just use __getitem__, which (should be, although I didn't check) is safe

@dimpase
Copy link
Member

dimpase commented Dec 6, 2025

please see my comment in #41249 - the whole point of get is to be as quick as possible. One can wrap the call to get_unsafe in sig_on/sig_off, introducing some overhead, less than your PR. But I don't see much point in it.

Updated the get and set methods to remove bounds checking and added signal handling.
@cxzhong cxzhong changed the title Use the safe method to avoid segfault add sig_on and sig_off to avoid segfault Dec 6, 2025
@cxzhong
Copy link
Contributor Author

cxzhong commented Dec 6, 2025

In some cases, it will not cause a segfault

sage: zero_vector(3).get(5)
0
sage: zero_vector(3).get(8)
---------------------------------------------------------------------------
SignalError                               Traceback (most recent call last)
Cell In[2], line 1
----> 1 zero_vector(Integer(3)).get(Integer(8))

File sage/modules/free_module_element.pyx:1933, in sage.modules.free_module_element.FreeModuleElement.get()

SignalError: Segmentation fault
sage: zero_vector(3).get(10)
0
sage: zero_vector(3).get(19)
---------------------------------------------------------------------------
SignalError                               Traceback (most recent call last)
Cell In[4], line 1
----> 1 zero_vector(Integer(3)).get(Integer(19))

File sage/modules/free_module_element.pyx:1933, in sage.modules.free_module_element.FreeModuleElement.get()

SignalError: Segmentation fault

@dimpase
Copy link
Member

dimpase commented Dec 6, 2025

segfaults are triggered by hardware when you are trying to access memory not allocated for your process. So you can violate the boundaries of your array sometimes, without triggering it, it is normal.

I still wonder whether it's not better just to leave this get() alone. Maybe @nbruin can tell us.

@cxzhong
Copy link
Contributor Author

cxzhong commented Dec 6, 2025

I think the method is strange. like get() and set() methods most people will believe they are safe. But it makes them unsafe.

@dimpase
Copy link
Member

dimpase commented Dec 6, 2025

the naming is unfortunate. perhaps it should be renamed to getunsafe.

@cxzhong
Copy link
Contributor Author

cxzhong commented Dec 6, 2025

the naming is unfortunate. perhaps it should be renamed to getunsafe.

But we already have get_unsafe

@dimpase
Copy link
Member

dimpase commented Dec 6, 2025

get_unsafe is Cython only

PySlice_GetIndicesEx(i, d, &start, &stop, &step, &slicelength)
values = []
for n in range(slicelength):
values.append(self.get_unsafe(start + n*step))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It use get_unsafe in _getitem_

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it certainly does (it's probably the only one "real" array element raw access method). I wonder why this call is not wrapped in sig_on/sig_off - is it a bug?
@nbruin - what would you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like get is slower and with less features than __getitem__, so I suspect it can just be deprecated. In the mean time, slapping on sig_on/sig_off could be OK, but shouldn't we really just be checking bounds and raising an error? As observed, you may not get a segfault for out-of-bounds access. In that case, you'll just get a garbage value. That's even worse! The argument would usually be "but I only use this routine for in-bounds access and then it's faster". We don't seem to have the "faster" part here. So if people want faster code, they should move to __getitem__ anyway (or cython where there's a proper "unsafe").

So it doesn't seem very important what "get" does. It might just be a nuisance. Did anyone look through its blame to see where it's coming from? Sometimes old tickets give insight or it may show that there was a problem before that has somehow been resolved in a different way.

@github-actions
Copy link

github-actions bot commented Dec 7, 2025

Documentation preview for this PR (built with commit 55e08dd; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Segmentation Fault when trying to get out-of-bounds index of vector

3 participants