Skip to content

Commit f87d7a6

Browse files
authored
Embed __FILE__ as C-string for prefix replacement (#1858)
Recently PR ( #1844 ) changed how error messages were generated when pointing to a particular file and line number. In particular they changed from using the typical C-string (`const char*`), which is `\0` terminated, to a C++ `std::string` object, which is not `\0` terminated. This change in turn was picked up when RMM headers are used to compile libraries (like cuDF) including file paths in strings that are not `\0` terminated. Conda in turn would detect the paths in these error messages and attempt to fix them as part of the prefix replacement process. When Conda did the prefix replacement would add an additional `\0` terminating character to string. However as the strings are now `std::string` based which lack `\0` terminating characters the final string written out by Conda would be one byte longer. This could mean overwriting other text data in the library or writing outside the text block. This is known bug in Conda ( conda/conda-build#1674 ). Thus when cuDF started building with the aforementioned RMM change last week, the packages it created lacked had file paths in error messages lacking the `\0` terminating character. These in turn would be inadvertently corrupted by Conda when installing the packages in an environment. This led to a quite hairy bug detailed in issue ( rapidsai/cudf#18251 ). To correct this issue, we drop the `std::string` constructor that was added in the aforementioned PR. More specifically we adapted the following code from cuDF's [`CUDF_EXPECTS_3`]( https://github.com/rapidsai/cudf/blob/8041ac8e370b092229841508fdfd1efb88fef034/cpp/include/cudf/utilities/error.hpp#L186-L192 ) and [`CUDF_FAIL_2`]( https://github.com/rapidsai/cudf/blob/86eb82399f0e056731e2062dc95a4583c26e9af1/cpp/include/cudf/utilities/error.hpp#L225-L227 ), which still uses a C-style string. Also to address the need for runtime generation of some errors. We use `std::string` for only an initial snippet of the string and add other contents like the `__FILE__` after. This keeps the latter bits as C-style strings. Authors: - https://github.com/jakirkham Approvers: - Bradley Dice (https://github.com/bdice) - Paul Mattione (https://github.com/pmattione-nvidia) - Vyas Ramasubramani (https://github.com/vyasr) URL: #1858
1 parent 9432761 commit f87d7a6

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

include/rmm/detail/error.hpp

+16-10
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
#include <cuda_runtime_api.h>
2222

2323
#include <cassert>
24+
#include <exception>
2425
#include <iostream>
2526
#include <string>
27+
#include <type_traits>
2628

2729
#define STRINGIFY_DETAIL(x) #x
2830
#define RMM_STRINGIFY(x) STRINGIFY_DETAIL(x)
@@ -55,12 +57,14 @@
5557
GET_RMM_EXPECTS_MACRO(__VA_ARGS__, RMM_EXPECTS_3, RMM_EXPECTS_2) \
5658
(__VA_ARGS__)
5759
#define GET_RMM_EXPECTS_MACRO(_1, _2, _3, NAME, ...) NAME
58-
#define RMM_EXPECTS_3(_condition, _reason, _exception_type) \
59-
(!!(_condition)) ? static_cast<void>(0) \
60-
: throw _exception_type /*NOLINT(bugprone-macro-parentheses)*/ \
61-
{ \
62-
std::string("RMM failure at: " __FILE__ ":" RMM_STRINGIFY(__LINE__) ": ") + _reason \
63-
}
60+
#define RMM_EXPECTS_3(_condition, _reason, _exception_type) \
61+
do { \
62+
static_assert(std::is_base_of_v<std::exception, _exception_type>); \
63+
/*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
64+
(!!(_condition)) ? static_cast<void>(0) \
65+
: throw _exception_type{std::string{"RMM failure at: "} + __FILE__ + ":" + \
66+
RMM_STRINGIFY(__LINE__) + ": " + _reason}; \
67+
} while (0)
6468
#define RMM_EXPECTS_2(_condition, _reason) RMM_EXPECTS_3(_condition, _reason, rmm::logic_error)
6569

6670
/**
@@ -79,10 +83,12 @@
7983
GET_RMM_FAIL_MACRO(__VA_ARGS__, RMM_FAIL_2, RMM_FAIL_1) \
8084
(__VA_ARGS__)
8185
#define GET_RMM_FAIL_MACRO(_1, _2, NAME, ...) NAME
82-
#define RMM_FAIL_2(_what, _exception_type) \
83-
/*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
84-
throw _exception_type{std::string{"RMM failure at:" __FILE__ ":" RMM_STRINGIFY(__LINE__) ": "} + \
85-
_what};
86+
#define RMM_FAIL_2(_what, _exception_type) \
87+
/*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
88+
throw _exception_type \
89+
{ \
90+
std::string{"RMM failure at:"} + __FILE__ + ":" + RMM_STRINGIFY(__LINE__) + ": " + _what \
91+
}
8692
#define RMM_FAIL_1(_what) RMM_FAIL_2(_what, rmm::logic_error)
8793

8894
/**

0 commit comments

Comments
 (0)