Skip to content

Commit 589d3fe

Browse files
ahojnneslucasthahn
authored andcommitted
Add Address Sanitizer options and fix reported issues (colmap#1390)
* Add Address Sanitizer options and fix reported issues * Add CI build * Fix * Asan with clang
1 parent 993e57b commit 589d3fe

File tree

12 files changed

+85
-35
lines changed

12 files changed

+85
-35
lines changed

.azure-pipelines/build-ubuntu.yaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ parameters:
22
displayName: 'Ubuntu 18.04'
33
ubuntuVersion: '18.04'
44
cudaEnabled: false
5+
asanEnabled: false
56

67
jobs:
7-
- job: ubuntu_build_${{ replace(parameters.ubuntuVersion, '.', '') }}_cuda_${{ parameters.cudaEnabled }}
8+
- job: ubuntu_build_${{ replace(parameters.ubuntuVersion, '.', '') }}_cuda_${{ parameters.cudaEnabled }}_asa_${{ parameters.asanEnabled }}
89
displayName: '${{ parameters.displayName }}'
910
pool:
1011
vmImage: 'ubuntu-${{ parameters.ubuntuVersion }}'
@@ -41,14 +42,22 @@ jobs:
4142
echo '##vso[task.setvariable variable=CXX]/usr/bin/cuda-g++'
4243
displayName: 'Install CUDA'
4344
45+
- ${{ if eq(parameters.asanEnabled, true) }}:
46+
- script: |
47+
sudo apt-get install -y clang-10
48+
echo '##vso[task.setvariable variable=CC]/usr/bin/clang'
49+
echo '##vso[task.setvariable variable=CXX]/usr/bin/clang++'
50+
displayName: 'Install CUDA'
51+
4452
- script: |
4553
cmake --version
4654
mkdir build
4755
cd build
4856
cmake .. \
4957
-GNinja \
5058
-DTESTS_ENABLED=ON \
51-
-DCUDA_ARCHS=6.0
59+
-DCUDA_ARCHS=6.0 \
60+
-DASAN_ENABLED=${{ parameters.asanEnabled }}
5261
ninja
5362
displayName: 'Configure and build'
5463

.azure-pipelines/build.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ jobs:
1616
displayName: 'Ubuntu 20.04 (CUDA)'
1717
ubuntuVersion: 20.04
1818
cudaEnabled: true
19+
- template: build-ubuntu.yaml
20+
parameters:
21+
displayName: 'Ubuntu 20.04 (ASan)'
22+
ubuntuVersion: 20.04
23+
asanEnabled: true
1924
- template: build-mac.yaml
2025
parameters:
2126
displayName: 'Mac 10.15'

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ option(CUDA_ENABLED "Whether to enable CUDA, if available" ON)
6161
option(GUI_ENABLED "Whether to enable the graphical UI" ON)
6262
option(OPENGL_ENABLED "Whether to enable OpenGL, if available" ON)
6363
option(TESTS_ENABLED "Whether to build test binaries" OFF)
64+
option(ASAN_ENABLED "Whether to enable AddressSanitizer flags" OFF)
6465
option(PROFILING_ENABLED "Whether to enable google-perftools linker flags" OFF)
6566
option(CGAL_ENABLED "Whether to enable the CGAL library" ON)
6667
option(BOOST_STATIC "Whether to enable static boost library linker flags" ON)
@@ -198,6 +199,16 @@ else()
198199
message(STATUS "Disabling interprocedural optimization")
199200
endif()
200201

202+
if(ASAN_ENABLED)
203+
message(STATUS "Enabling ASan flags")
204+
if(IS_CLANG OR IS_GNU)
205+
add_compile_options(-fsanitize=address -fno-omit-frame-pointer -fsanitize-address-use-after-scope)
206+
add_link_options(-fsanitize=address)
207+
else()
208+
message(FATAL_ERROR "Unsupported compiler for ASan mode")
209+
endif()
210+
endif()
211+
201212
if(CUDA_FOUND)
202213
if(CUDA_ENABLED)
203214
add_definitions("-DCUDA_ENABLED")

doc/install.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,22 @@ with the source code ``hello_world.cc``::
316316
}
317317

318318

319+
----------------
320+
AddressSanitizer
321+
----------------
322+
323+
If you want to build COLMAP with address sanitizer flags enabled, you need to
324+
use a recent compiler with ASan support. For example, you can manually install
325+
a recent clang version on your Ubuntu machine and invoke CMake as follows::
326+
327+
CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake .. \
328+
-DASAN_ENABLED=ON \
329+
-DTESTS_ENABLED=ON \
330+
-DCMAKE_BUILD_TYPE=RelWithDebInfo
331+
332+
Note that it is generally useful to combine ASan with debug symbols to get
333+
meaningful traces for reported issues.
334+
319335
-------------
320336
Documentation
321337
-------------

lib/Graclus/multilevelLib/mlkkm.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,12 @@ int MLKKMPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, int chain_le
182182
GraphType *cgraph;
183183
int wgtflag=3, numflag=0, options[10], edgecut;
184184
float ncut;
185-
idxtype *cptr, *cind;
185+
// idxtype *cptr, *cind;
186186
int numcomponents;
187187
char *mlwkkm_fname = "coarse.graph";
188188

189-
cptr = idxmalloc(graph->nvtxs, "MLKKMPartitioning: cptr");
190-
cind = idxmalloc(graph->nvtxs, "MLKKMPartitioning: cind");
189+
// cptr = idxmalloc(graph->nvtxs, "MLKKMPartitioning: cptr");
190+
// cind = idxmalloc(graph->nvtxs, "MLKKMPartitioning: cind");
191191
//printf("Computing the number of connected components.\n");
192192
/*numcomponents = FindComponents(ctrl, graph, cptr, cind);
193193

lib/PBA/pba.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ void ParallelBA::SetFocalMask(const int* fmask, float weight) {
116116
if (_optimizer && weight > 0) _optimizer->SetFocalMask(fmask, weight);
117117
}
118118

119-
void* ParallelBA::operator new(size_t size) {
120-
void* p = malloc(size);
121-
if (p == 0) {
122-
const std::bad_alloc ba;
123-
throw ba;
124-
}
125-
return p;
126-
}
119+
// void* ParallelBA::operator new(size_t size) {
120+
// void* p = malloc(size);
121+
// if (p == 0) {
122+
// const std::bad_alloc ba;
123+
// throw ba;
124+
// }
125+
// return p;
126+
// }
127127

128128
ParallelBA* NewParallelBA(ParallelBA::DeviceT device) {
129129
return new ParallelBA(device);

lib/PBA/pba.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class ParallelBA {
132132
public:
133133
PBA_EXPORT ParallelBA(DeviceT device = PBA_CUDA_DEVICE_DEFAULT,
134134
const int num_threads = -1);
135-
PBA_EXPORT void* operator new(size_t size);
135+
// PBA_EXPORT void* operator new(size_t size);
136136
PBA_EXPORT virtual ~ParallelBA();
137137

138138
public:

src/base/cost_functions_test.cc

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939
using namespace colmap;
4040

4141
BOOST_AUTO_TEST_CASE(TestBundleAdjustmentCostFunction) {
42-
ceres::CostFunction* cost_function =
42+
std::unique_ptr<ceres::CostFunction> cost_function(
4343
BundleAdjustmentCostFunction<SimplePinholeCameraModel>::Create(
44-
Eigen::Vector2d::Zero());
44+
Eigen::Vector2d::Zero()));
4545
double qvec[4] = {1, 0, 0, 0};
4646
double tvec[3] = {0, 0, 0};
4747
double point3D[3] = {0, 0, 1};
@@ -69,10 +69,11 @@ BOOST_AUTO_TEST_CASE(TestBundleAdjustmentCostFunction) {
6969
}
7070

7171
BOOST_AUTO_TEST_CASE(TestBundleAdjustmentConstantPoseCostFunction) {
72-
ceres::CostFunction* cost_function = BundleAdjustmentConstantPoseCostFunction<
73-
SimplePinholeCameraModel>::Create(ComposeIdentityQuaternion(),
74-
Eigen::Vector3d::Zero(),
75-
Eigen::Vector2d::Zero());
72+
std::unique_ptr<ceres::CostFunction> cost_function(
73+
BundleAdjustmentConstantPoseCostFunction<
74+
SimplePinholeCameraModel>::Create(ComposeIdentityQuaternion(),
75+
Eigen::Vector3d::Zero(),
76+
Eigen::Vector2d::Zero()));
7677
double point3D[3] = {0, 0, 1};
7778
double camera_params[3] = {1, 0, 0};
7879
double residuals[2];
@@ -134,9 +135,9 @@ BOOST_AUTO_TEST_CASE(TestBundleAdjustmentConstantPoint3DCostFunction) {
134135
}
135136

136137
BOOST_AUTO_TEST_CASE(TestRigBundleAdjustmentCostFunction) {
137-
ceres::CostFunction* cost_function =
138+
std::unique_ptr<ceres::CostFunction> cost_function(
138139
RigBundleAdjustmentCostFunction<SimplePinholeCameraModel>::Create(
139-
Eigen::Vector2d::Zero());
140+
Eigen::Vector2d::Zero()));
140141
double rig_qvec[4] = {1, 0, 0, 0};
141142
double rig_tvec[3] = {0, 0, -1};
142143
double rel_qvec[4] = {1, 0, 0, 0};
@@ -167,22 +168,23 @@ BOOST_AUTO_TEST_CASE(TestRigBundleAdjustmentCostFunction) {
167168
}
168169

169170
BOOST_AUTO_TEST_CASE(TestRelativePoseCostFunction) {
170-
ceres::CostFunction* cost_function = RelativePoseCostFunction::Create(
171-
Eigen::Vector2d(0, 0), Eigen::Vector2d(0, 0));
171+
std::unique_ptr<ceres::CostFunction> cost_function(
172+
RelativePoseCostFunction::Create(Eigen::Vector2d(0, 0),
173+
Eigen::Vector2d(0, 0)));
172174
double qvec[4] = {1, 0, 0, 0};
173175
double tvec[3] = {0, 1, 0};
174176
double residuals[1];
175177
const double* parameters[2] = {qvec, tvec};
176178
BOOST_CHECK(cost_function->Evaluate(parameters, residuals, nullptr));
177179
BOOST_CHECK_EQUAL(residuals[0], 0);
178180

179-
cost_function = RelativePoseCostFunction::Create(Eigen::Vector2d(0, 0),
180-
Eigen::Vector2d(1, 0));
181+
cost_function.reset(RelativePoseCostFunction::Create(Eigen::Vector2d(0, 0),
182+
Eigen::Vector2d(1, 0)));
181183
BOOST_CHECK(cost_function->Evaluate(parameters, residuals, nullptr));
182184
BOOST_CHECK_EQUAL(residuals[0], 0.5);
183185

184-
cost_function = RelativePoseCostFunction::Create(Eigen::Vector2d(0, 0),
185-
Eigen::Vector2d(1, 1));
186+
cost_function.reset(RelativePoseCostFunction::Create(Eigen::Vector2d(0, 0),
187+
Eigen::Vector2d(1, 1)));
186188
BOOST_CHECK(cost_function->Evaluate(parameters, residuals, nullptr));
187189
BOOST_CHECK_EQUAL(residuals[0], 0.5);
188190
}

src/base/line.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ extern "C" {
3838
}
3939

4040
namespace colmap {
41+
namespace {
42+
43+
struct RawDeleter {
44+
void operator()(double* p) { free(p); }
45+
};
46+
47+
} // namespace
4148

4249
std::vector<LineSegment> DetectLineSegments(const Bitmap& bitmap,
4350
const double min_length) {
@@ -55,9 +62,9 @@ std::vector<LineSegment> DetectLineSegments(const Bitmap& bitmap,
5562
bitmap_data.end());
5663

5764
int num_segments;
58-
std::unique_ptr<double> segments_data(lsd(&num_segments,
59-
bitmap_data_double.data(),
60-
bitmap.Width(), bitmap.Height()));
65+
std::unique_ptr<double, RawDeleter> segments_data(
66+
lsd(&num_segments, bitmap_data_double.data(), bitmap.Width(),
67+
bitmap.Height()));
6168

6269
std::vector<LineSegment> segments;
6370
segments.reserve(num_segments);

src/base/reconstruction.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1487,8 +1487,8 @@ size_t Reconstruction::FilterPoints3DWithLargeReprojectionError(
14871487
class Point3D& point3D = Point3D(point3D_id);
14881488

14891489
if (point3D.Track().Length() < 2) {
1490-
DeletePoint3D(point3D_id);
14911490
num_filtered += point3D.Track().Length();
1491+
DeletePoint3D(point3D_id);
14921492
continue;
14931493
}
14941494

0 commit comments

Comments
 (0)