This is an automated email from the ASF dual-hosted git repository.
kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 2aaac072d5 GH-50210: [C++][Gandiva] Replace precompiled std::string to
fix _Unwind_Resume JIT failure on JNI builds (#50214)
2aaac072d5 is described below
commit 2aaac072d521feef8fa424a483917b5709c2eb2a
Author: tadeja <[email protected]>
AuthorDate: Fri Jun 19 04:43:30 2026 +0200
GH-50210: [C++][Gandiva] Replace precompiled std::string to fix
_Unwind_Resume JIT failure on JNI builds (#50214)
### Rationale for this change
See issue #50210. Two JNI CI jobs fail in `gandiva-projector-test` and
`gandiva-projector-test-static` with
```bash
[ RUN ] TestProjector.TestCastBitFunction
JIT session error: Symbols not found: [ _Unwind_Resume ]
/arrow/cpp/src/gandiva/tests/projector_test.cc:1978: Failure
```
then a _Segmentation fault_.
Recent commit 4b64398 introduced a few `std::string` error messages into
Gandiva precompiled functions. These are JIT-compiled to LLVM bitcode, and
`std::string` pulls in `_Unwind_Resume` into bitcode even on error branches
never taken.
The JNI build uses
[ARROW_GANDIVA_STATIC_LIBSTDCPP="ON"](https://github.com/apache/arrow/actions/runs/27745137529/job/82081554816?pr=50214#step:7:644)
(_Include `-static-libstdc++ -static-libgcc...` when linking with Gandiva
libraries._), so `_Unwind_Resume` is not exposed for the JIT to resolve.
### What changes are included in this PR?
Replace `std::string` in precompiled functions with `snprintf` (bounded by
buffer size, cannot overflow regardless of input length).
### Are these changes tested?
Yes, pass on fork CI:
[JNI ubuntu-latest
amd64](https://github.com/tadeja/arrow/actions/runs/27724218930/job/82018788632#step:7:14558)
[JNI ubuntu-24.04-arm
arm64/v8](https://github.com/tadeja/arrow/actions/runs/27724218930/job/82018788669#step:7:14868)
### Are there any user-facing changes?
No.
* GitHub Issue: #50210
Authored-by: Tadeja Kadunc <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
cpp/src/gandiva/precompiled/string_ops.cc | 40 ++++++++++++++++++-------------
cpp/src/gandiva/precompiled/time.cc | 7 +++---
2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/cpp/src/gandiva/precompiled/string_ops.cc
b/cpp/src/gandiva/precompiled/string_ops.cc
index 6c9c392a82..8dc941e28c 100644
--- a/cpp/src/gandiva/precompiled/string_ops.cc
+++ b/cpp/src/gandiva/precompiled/string_ops.cc
@@ -572,10 +572,12 @@ gdv_boolean castBIT_utf8(gdv_int64 context, const char*
data, gdv_int32 data_len
if (compare_lower_strings("false", 5, trimmed_data, trimmed_len)) return
false;
}
// if no 'true', 'false', '0' or '1' value is found, set an error
- std::string err_msg = "CAST_BIT: Invalid value for boolean: '" +
- std::string(data, data_len) +
- "' (expected 0, 1, true, false; case-insensitive)";
- gdv_fn_context_set_error_msg(context, err_msg.c_str());
+ char err_msg[128];
+ snprintf(err_msg, sizeof(err_msg),
+ "CAST_BIT: Invalid value for boolean: '%.*s'"
+ " (expected 0, 1, true, false; case-insensitive)",
+ data_len, data);
+ gdv_fn_context_set_error_msg(context, err_msg);
return false;
}
@@ -2410,20 +2412,22 @@ const char* binary_string(gdv_int64 context, const
char* text, gdv_int32 text_le
OUT_TYPE next = result * 16 - digit;
\
\
if (next > result) {
\
- std::string err_msg =
\
- "CAST_" #TYPE_NAME
\
- "_FROM_HEX: integer overflow while reading hex value '" +
\
- std::string(in_original, in_len_original) + "'";
\
- gdv_fn_context_set_error_msg(context, err_msg.c_str());
\
+ char err_msg[128];
\
+ snprintf(err_msg, sizeof(err_msg),
\
+ "CAST_" #TYPE_NAME
\
+ "_FROM_HEX: integer overflow while reading hex value
'%.*s'", \
+ in_len_original, in_original);
\
+ gdv_fn_context_set_error_msg(context, err_msg);
\
return -1;
\
}
\
result = next;
\
read_index++;
\
} else {
\
- std::string err_msg = "CAST_" #TYPE_NAME
\
- "_FROM_HEX: invalid character in hex value '" +
\
- std::string(in_original, in_len_original) + "'";
\
- gdv_fn_context_set_error_msg(context, err_msg.c_str());
\
+ char err_msg[128];
\
+ snprintf(err_msg, sizeof(err_msg),
\
+ "CAST_" #TYPE_NAME "_FROM_HEX: invalid character in hex value
'%.*s'", \
+ in_len_original, in_original);
\
+ gdv_fn_context_set_error_msg(context, err_msg);
\
return -1;
\
}
\
}
\
@@ -2431,10 +2435,12 @@ const char* binary_string(gdv_int64 context, const
char* text, gdv_int32 text_le
result *= -1;
\
\
if (result < 0) {
\
- std::string err_msg = "CAST_" #TYPE_NAME
\
- "_FROM_HEX: integer overflow while reading hex
value '" + \
- std::string(in_original, in_len_original) + "'";
\
- gdv_fn_context_set_error_msg(context, err_msg.c_str());
\
+ char err_msg[128];
\
+ snprintf(err_msg, sizeof(err_msg),
\
+ "CAST_" #TYPE_NAME
\
+ "_FROM_HEX: integer overflow while reading hex value '%.*s'",
\
+ in_len_original, in_original);
\
+ gdv_fn_context_set_error_msg(context, err_msg);
\
return -1;
\
}
\
}
\
diff --git a/cpp/src/gandiva/precompiled/time.cc
b/cpp/src/gandiva/precompiled/time.cc
index ff3b849ef4..f7028730eb 100644
--- a/cpp/src/gandiva/precompiled/time.cc
+++ b/cpp/src/gandiva/precompiled/time.cc
@@ -270,9 +270,10 @@ static const int WEEK_LEN[] = {6, 6, 7, 9, 8, 6, 8};
}
\
}
\
if (dateSearch == 0) {
\
- std::string err_msg = "NEXT_DAY: '" + std::string(in, in_len) +
\
- "' is not a recognized day of the week";
\
- gdv_fn_context_set_error_msg(context, err_msg.c_str());
\
+ char err_msg[128];
\
+ snprintf(err_msg, sizeof(err_msg),
\
+ "NEXT_DAY: '%.*s' is not a recognized day of the week", in_len,
in); \
+ gdv_fn_context_set_error_msg(context, err_msg);
\
return 0;
\
}
\
\