我会尽力解释这个问题,因为我无法分享很多代码。所以我一方面有这个C程序,另一方面有java程序。 C程序是一个命令行程序,它具有一个可以由java程序(这是一个gui应用程序)调用的函数,以提供可视化结果。以下是从main或java gui调用的方法链:
c code - main / JNI method
|-> first method
|-> second method
|-> third method
|-> fourth method
|-> more methods (not the source of problem though)
c程序本身编译并运行完美,执行其预期的功能。第一个被调用的方法返回一个char *,我们想把它变成一个jstring。通过调试和确定分段故障发生位置的整个过程,我们至少验证了jstring转换是否按预期工作。只有当我通过java调用JNI函数时才会发生seg错误。
所以这里是导致seg错误的代码块(通用代码但尽可能接近和准确),它位于第四个方法中,只有9行并且通过在它之后放置一个return语句找到:
for(i = 0; i < LENGTH; i++){
printf("[%2x]", <unsigned char array>[i]);
}
奇怪的(可能是相关的部分)是如果我在for循环之前放置return语句并调用JNI函数,我们会得到一个不同的错误。 EVP_CIPHER_CTX的未定义符号错误,特别是它表示在我们的.so文件中未定义。
我确实找到了这个问题,但它没有帮助,因为在错误点没有变量被设置为null:
What can cause a Java native function (in C) to segfault upon entry?
编辑:附上更多信息
所以我使用了Valgrind(奇妙的工具BTW,简直不敢相信我从未被告知过这个),但它只指出了所谓的写错误(它们都与sprintf有关),但它们很好,以及使用未初始化变量的条件,但它们也很好,因为在使用它们之前总是会检查if语句以确保它们不为null。
GDB(也是一个很棒的工具,希望我在学校学习C时教会如何使用它)表明错误并没发生在我认为发生的地方。这是奇怪的,因为错误出现的唯一时间是我将return语句放在上面的代码之后。错误的真实位置是for循环之前的代码两行:
memcpy(unsgned_char_array, value, value_size);
我在此行之前放置了printf语句来检查key和key_size实际上是否有值,并且确实如此。至于unsigned char数组,空间被分配给它并用这行代码初始化:
memset(unsgned_char_array, 0, size_of_array);
所以我仍然不确定发生了什么。
这是我记忆中最难忘的细节,因为这是出自工作。我将提供更多详细信息,以便我能够以及在被要求提供更多信息时提供更多信息,但它可能需要等到第二天工作之后。