1

I'm writing a simple OpenGL program and am currently working on a Camera class. However, trying to initialize the camera class results in a segfault at glm::cross

I've tried initializing with both new and Camera(...) like so:

  1. Camera *c = new Camera(glm::vec3(0, 0, 0), glm::vec2(0, 0), nullptr);
  2. Camera c = Camera(glm::vec3(0, 0, 0), glm::vec2(0, 0), nullptr);
  3. Camera c(glm::vec3(0, 0, 0), glm::vec2(0, 0), nullptr);

However, all 3 of them produce the same result. (the nullptr as an arg has nothing to do with it, as it just gets assigned to an attribute)

My Camera class:

class Camera {
    public:
        glm::vec3 up;
        glm::vec3 right;
        glm::vec3 forward;

        glm::vec3 lookDirection;
        glm::vec3 position;

        float fov = 70, near = 0.1f, far = 100.0f;

        glm::vec2 lookAngle;
        GLFWwindow *win;

        Camera(glm::vec3 pos, glm::vec2 look, GLFWwindow *window) {
            win = window;
            lookAngle = look;
            position = pos;

            lookDirection = glm::vec3(cos(lookAngle.y) * sin(lookAngle.x), sin(lookAngle.y),
                                  cos(lookAngle.y) * cos(lookAngle.x));

            right = glm::vec3(sin(lookAngle.x - pi / 2.0f), 0, cos(lookAngle.x - pi / 2.0f));
            forward = glm::vec3(sin(lookAngle.x), 0, cos(lookAngle.x));
            // I would print `right` and `lookDirection` here.
            up = glm::cross(right, lookDirection);
            std::cout << "After cross" << std::endl;
        }

        ...  // Some irrelevant methods
}

However, on up = glm::cross(right, lookDirection);, it would segfault at

glm::detail::compute_cross<float, (glm::qualifier)0, false>::call(glm::vec<3, float, (glm::qualifier)0> const&, glm::vec<3, float, (glm::qualifier)0> const&):
    pushq  %rbp
    movq   %rsp, %rbp
    subq   $0x20, %rsp
    movq   %rdi, %rax
    movq   %rsi, -0x8(%rbp)
    movq   %rdx, -0x10(%rbp)
    movq   -0x8(%rbp), %rdx
    movss  0x4(%rdx), %xmm0           # xmm0 = mem[0],zero,zero,zero
    movq   -0x10(%rbp), %rdx
    mulss  0x8(%rdx), %xmm0      # <------- IT WOULD SEGFAULT RIGHT HERE
    movq   -0x10(%rbp), %rdx
    movss  0x4(%rdx), %xmm1           # xmm1 = mem[0],zero,zero,zero
    movq   -0x8(%rbp), %rdx

right would be equal to {-1, 0, 6.12323e-17} and lookDirection would equal {0, 0, 1}. "After cross" would never be printed.

Currently, I'm at a loss. Any help would be appreciated.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Rotartsi
  • 527
  • 5
  • 19
  • Ok it seems as if various glm functions and operators (ei `glm::vec3 * glm::vec3` or `+=`) are segfaulting for no apparent reason. However, if i replace these with my own implementation it somehow works? – Rotartsi Sep 01 '19 at 00:00
  • If on linux please use sanitizers. Note that you can mostly enable just one of them at the time. I would start with memory sanitizer, then address sanitizer, then thread sanitizer, then undefined behavior sanitizer. – NoSenseEtAl Sep 01 '19 at 10:42

2 Answers2

2

I suspect that the "irrelevant" methods actually contain a memory corruption bug. There is nothing I see in the code you posted that is obviously wrong.

The way memory corruption works is some part of the program overwrites some data it shouldn't, leaving a little landmine in the program's memory. Then that landmine can be hit by anything at any time, unpredictably. In your comment, you say "glm functions ... are segfaulting for no apparent reason"--that is a common symptom of a memory corruption issue.

To debug this, first, I usually try to stabilize the bug: to make sure it happens reliably before trying to track down the cause so that it doesn't slip away when I make small changes. If your C++ implementation (compiler and library) has a "debug heap", enable that. This answer has a number of related suggestions.

In some cases, a debug heap or similar will pinpoint the problem by itself. But if not, then once you've stabilized the bug, start removing (disabling, commenting, etc.) parts of your program until you find something that makes the bug stop happening. That code is not necessarily the problem! It's merely involved somehow. Put that code back in (so the bug recurs), and look for other things to remove. Do that 2-3 times and you'll have (1) a short list of suspects and (2) created a smaller program with the same problem, making the whole process easier.

I'd say keep doing that until you either find the problem or reduce the program to, say, no more than 50 lines, such that you could post that code on SO. This might seem like busywork, but it's really not; this is a very valuable and general skill to develop.

Scott McPeak
  • 8,803
  • 2
  • 40
  • 79
1

Ok I found the problem. It had nothing to do with the code I posted, but with the way I was building my application. In my CMakeLists.txt is was target_link_libraries the glm_shared.dylib. This somehow confused the glm functions and removing that line from cmake fixed everything.

Rotartsi
  • 527
  • 5
  • 19