I’ve encountered two errors compiling radiance as a library that occur on Linux but not MacOS. I’ve tried two different linux machines:
Debian GNU/Linux 11 (bullseye) // gcc version 10.2.1 20210110 (Debian 10.2.1-6)
Ubuntu 20.04.3 LTS // gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
my mac is:
10.14.6 // Apple LLVM version 10.0.1 (clang-1001.0.37.9)
Here are the issues:
- when using rtrace as a library, I typically first load the scene without a light source and then add it later (this ensures it is at the end of the object record so I can swap sources). Now, this shouldn’t cause any problems, and typically doesn’t, it is perfectly valid to load a scene in radiance without a source, but in the specific case I compile as a module, under linux, I get a segfault because in marksources() if no sources are found then srccnt and cntord are never allocated. My fix is to simply not return early (commenting near lines 118 in source.c):
/* still need to initialize contribution arrays, because we will load a source in the future - SW*/
// if (!foundsource) {
// error(WARNING, "no light sources found");
// return;
// }
Roland also suggested that if these variables were initialized with a NULL pointer that might also solve the issue, but I have not tried that. Somehow clang is catching this and doing this work for me.
- My other issue is with compiling rcontrib as a library. Similarly, I can make a running executable from the exact same code even under Linux that does not segfault, but if I compile into a module I get a segfault when calling setcontext(). This one is weird, because in this case (compiled as a module) for some reason it is not even calling setcontext() defined in caldefn.c, but instead is using something declared in ucontext.h (which is deprecated on mac). As best I can tell, this file is included in signal.h which is included in multiple places, but probably most relevant is rcmain.c (and likewise in my modified rcontrib initializing source, rcinit.c). I tried linking the libraries in all different orders, but couldn’t figure this one out, other than by patching caldefn.c and func.c to change the name of setcontext() to avoid this issue.
caldefn.h:
extern char *setcontextcal(char *ctx);
I’m using cmake to build, but here are the actual calls to gcc for the linking step (compilation step is identical):
# rcontrib: this is the classic radiance executable
/usr/bin/cc CMakeFiles/rcontrib.dir/Radiance/src/rt/rcmain.c.o CMakeFiles/rcontrib.dir/Radiance/src/rt/rcontrib.c.o CMakeFiles/rcontrib.dir/Radiance/src/rt/rc2.c.o CMakeFiles/rcontrib.dir/Radiance/src/rt/rc3.c.o -o rcontrib libradiance_o.a librtrad_o.a -lm
# raytcontrib: this is similiar to rcontrib, but uses the same code to initialize the scene and call rays as the library (this works without the patch!)
/usr/bin/c++ CMakeFiles/raytcontrib.dir/mainrc.cpp.o CMakeFiles/raytcontrib.dir/render.cpp.o CMakeFiles/raytcontrib.dir/rcontrib.cpp.o -o raytcontrib librcontribcfiles.a librcraycalls.a libradiance.a librtrad.a /usr/lib/x86_64-linux-gnu/libpython3.8.so -lm
# rcontrib_c: here is the linking for the library, it is likely the
# -shared flag (which is needed) that lets the ucontext.h
# symbol leak in somehow, but I do not get duplicate #
# symbol linker errors, it compiles fine, but then segfaults.
# If I get rid of -fPIC it throws linker errors.
/usr/bin/c++ -fPIC -flto -shared -o /home/wasilewski/raytraverse/raytraverse/crenderer/rcontrib_c.cpython-38-x86_64-linux-gnu.so CMakeFiles/rcontrib_c.dir/render.cpp.o CMakeFiles/rcontrib_c.dir/rcontrib.cpp.o librcontribcfiles.a librcraycalls.a libradiance.a librtrad.a -lm
If anyone has any compiler advice I’ll take it, but this seems like a problem most easiily addressed by changing the code.
Thanks!
stephen