简体   繁体   中英

CLion execution through some GTest TEST_F hangs, step-by-step debugging goes backwards?

I'm debugging an application I wrote with C++ in CLion and am testing it with Google Test. It's an implementation of a computer vision paper I found, and I'm using OpenCV for its Mat class and image manipulation functions.

Three of my test functions was behaving in a very erratic way; here is one.

/**
 * Create a flat point cloud and flip it horizontally
 */
TEST_F(PointCloudTest, FlipHorizontal) {
    // load image & set constants
    cv::Mat image = omar::imreadAsGrayDouble(dirname + "uttower.png");
    cv::Mat flippedImage = omar::imreadAsGrayDouble(dirname + "uttower_horz.png");
    double fLength = 200.0; // for this, the flength is arbitrary as long as it's the same.

    // build point cloud
    omar::PointCloud pc(image, fLength);

    /* Build the other camera pose
     * Specifically, rotated pi over Y
     * and 2 focal lengths out into Z+ space.
     * It's written as 2.001 to test whether small variations affect point placement*/
    omar::Pose otherCamera(0.0, 0.0, 2.001, 0.0, M_PI, 0.0);

    // flip horizontally
    omar::PointCloud newPc = pc.viewPoints(otherCamera);
    cv::Mat newImage = newPc.renderToImage(fLength, image.rows, image.cols);
    omar::assertMatEquals(flippedImage, newImage, 10 * DBL_EPSILON);
}

and the GTest debugging system would provide the output as if it finished:

[ OK ] PointCloudTest.FlipHorizontal (205 ms)

but the icon never changed to something signaling that the test finished.

图像显示 OK 和 !但三个测试的车轮停滞不前

When I went to debug it, if I set a breakpoint at the bottom of the function, it would stop, then for each time I pressed "Step Over," it would jump up the rest of the lines, one by one, then finish. This turns out to be the debugging behavior of all the tests.

The hanging tests are only very slightly different from a different test that passes. Specifically, that line is the viewPoints line. Here is the relevant code:

PointCloud::PointCloud(const PointCloud& other) {
    pointsAndIntensities = other.pointsAndIntensities.clone();
}
PointCloud PointCloud::viewPoints(omar::Pose otherCameraPose) {
    PointCloud otherPointCloud = PointCloud(*this);
    otherPointCloud.transform(otherCameraPose);
    return otherPointCloud;
}

void PointCloud::transform(omar::Pose otherCameraPose) {
    cv::Mat transformedPoints = otherCameraPose.world2camera(pointsAndIntensities(cv::Range(0, 3), cv::Range::all()));
    cv::Mat replaceablePoints(pointsAndIntensities, cv::Range(0, 3));
    transformedPoints.copyTo(replaceablePoints);
}

I'd like to understand the reason for this ordering, but it may or may not be related to the true issue, which is the hanging tests. Technically, all three of the tests pass, but I think this issue will cause a lot of problems down the road. I am at my wit's end. Help and follow up questions are appreciated!

TL;DR: make sure you end your print statements with a new line.

There was a very, very important detail that I left out when I described the problem. I decided to trim out the cout lines that I used to debug some information from my description here. The original code is:

void PointCloud::transform(omar::Pose otherCameraPose) {
    //cv::Mat oldPoints(pointsAndIntensities, cv::Range(0, 3));

    cv::Mat transformedPoints = otherCameraPose.world2camera(pointsAndIntensities(cv::Range(0, 3), cv::Range::all()));
    cv::Mat replaceablePoints(pointsAndIntensities, cv::Range(0, 3));
    std::cout << "Transformed: " << transformedPoints.col(3) << std::endl;
    std::cout << "Original: " << replaceablePoints.col(3) << std::endl;
    transformedPoints.copyTo(replaceablePoints);
    std::cout << "Replaced?: " << pointsAndIntensities.col(3);
}

I decided to dig more into the code to find the exact line that was causing the hanging, in case it was some error in memory. I tracked it down to the transform method above, and it turned out to be the std::cout lines I had in there. I didn't know if using the stream mid-test caused some problem. As it turns out, it was that I hadn't ended my last print statement with an std::endl .

My hunch is that CLion relies on the cout output from GTest in order to find whether a test passes or fails, and because the [ OK ] PointCloudTest.FlipHorizontal (205 ms) was not on a new line, it didn't recognize the test had finished successfully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM