Hi folks, I've been trying to debug a segfault I have been getting in a python c extension that statically links to Embree. The program does not crash on Linux. The crash happens in the Windows deployment of the c extension, though I haven't been able to reproduce the crash in a C++ only test script. That said, stepping through with the debugger shows an out of bounds index is generated, even if it isn't read from. I think it might have to do with the size of the grid and how far out of bounds I need to be for the error to be generated, but I'm not sure.
I get Exception: Exception 0xc0000005 encountered at address 0x7ff77e978b48: Access violation reading location 0x1fcf232e068 at
|
const vfloat<N> p2 = mem<vfloat<N>>::loadu(valid,(float*)&src[(idx1+1)*stride+ofs]); |
This to be because Embree always reads the row and then the row after it to get the two corners of the interpolation in that direction. When passing a V coordinate of 1.0, which is supposed to be valid based on the comment on line 74
|
/* clamp input u,v to [0;1] range */ |
|
U = max(min(U,1.0f),0.0f); |
|
V = max(min(V,1.0f),0.0f); |
The resulting index is past the end of the of the array.
|
const unsigned int idx1 = grid.startVtxID + (iv+1)*grid.lineVtxOffset + iu; |
I can think of two solutions. The simplest solution is to make the maximum V value nextowards(1.0f, 0.0f) so that 1 is not included, but the resulting values might be slightly off, and it involves the full bilinear interpolation. The correct approach would be switching to a linear interpolation when V is identically equal to 1.0f.
Here is a test snippet. On my machine, it does not segfault, but the debugger shows the invalid index.
#include <array>
#include <print>
#include <limits>
#include "embree4/rtcore.h"
int main() {
RTCDevice device = rtcNewDevice(nullptr);
RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_GRID);
std::array<float, 3 * 5 * 5 + 1> vertices{
0.0f, 0.0f, 0.0f,
0.25f, 0.0f, 0.0f,
0.50f, 0.0f, 0.0f,
0.75f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.25f, 0.0f,
0.25f, 0.25f, 0.0f,
0.50f, 0.25f, 0.0f,
0.75f, 0.25f, 0.0f,
1.0f, 0.25f, 0.0f,
0.0f, 0.50f, 0.0f,
0.25f, 0.50f, 0.0f,
0.50f, 0.50f, 0.0f,
0.75f, 0.50f, 0.0f,
1.0f, 0.50f, 0.0f,
0.0f, 0.75f, 0.0f,
0.25f, 0.75f, 0.0f,
0.50f, 0.75f, 0.0f,
0.75f, 0.75f, 0.0f,
1.0f, 0.75f, 0.0f,
0.0f, 1.00f, 0.0f,
0.25f, 1.00f, 0.0f,
0.50f, 1.00f, 0.0f,
0.75f, 1.00f, 0.0f,
1.0f, 1.00f, 0.0f,
std::numeric_limits<float>::quiet_NaN()
};
rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3,
vertices.data(), 0, sizeof(float) * 3, 25);
auto& grid = *reinterpret_cast<RTCGrid*>(rtcSetNewGeometryBuffer(geom,
RTC_BUFFER_TYPE_GRID, 0, RTC_FORMAT_GRID, sizeof(RTCGrid), 1));
grid.startVertexID = 0;
grid.stride = 5;
grid.width = 5;
grid.height = 5;
rtcCommitGeometry(geom);
std::array<float, 3> result{};
RTCInterpolateArguments args{
.geometry = geom,
.primID = 0,
.u = 1.0,
.v = 1.0,
.bufferType = RTC_BUFFER_TYPE_VERTEX,
.bufferSlot = 0,
.P = result.data(),
.dPdu = nullptr,
.dPdv = nullptr,
.ddPdudu = nullptr,
.ddPdvdv = nullptr,
.ddPdudv = nullptr,
.valueCount = 3,
};
rtcInterpolate(&args);
std::println("Result: {}, {}, {}", result[0], result[1], result[2]);
rtcReleaseGeometry(geom);
rtcReleaseDevice(device);
return 0;
}
Hi folks, I've been trying to debug a segfault I have been getting in a python c extension that statically links to Embree. The program does not crash on Linux. The crash happens in the Windows deployment of the c extension, though I haven't been able to reproduce the crash in a C++ only test script. That said, stepping through with the debugger shows an out of bounds index is generated, even if it isn't read from. I think it might have to do with the size of the grid and how far out of bounds I need to be for the error to be generated, but I'm not sure.
I get
Exception: Exception 0xc0000005 encountered at address 0x7ff77e978b48: Access violation reading location 0x1fcf232e068atembree/kernels/common/scene_grid_mesh.h
Line 120 in 3d9cb89
This to be because Embree always reads the row and then the row after it to get the two corners of the interpolation in that direction. When passing a V coordinate of 1.0, which is supposed to be valid based on the comment on line 74
embree/kernels/common/scene_grid_mesh.h
Lines 74 to 76 in 3d9cb89
The resulting index is past the end of the of the array.
embree/kernels/common/scene_grid_mesh.h
Line 115 in 3d9cb89
I can think of two solutions. The simplest solution is to make the maximum V value
nextowards(1.0f, 0.0f)so that 1 is not included, but the resulting values might be slightly off, and it involves the full bilinear interpolation. The correct approach would be switching to a linear interpolation when V is identically equal to 1.0f.Here is a test snippet. On my machine, it does not segfault, but the debugger shows the invalid index.