これは、これを行うことが「良い」かどうかという質問には答えませんが、これがその方法です。私のアプリケーションでは、カスタムハードウェア、巨大なページ、共有メモリ、NUMAロックメモリなどの間で複雑な相互作用があり、適切に割り当てられているように見えるメモリを持つことができますが、それに触れると(この場合は書き込み)、アプリケーションの途中でBUSエラーまたはSEGV障害をスローします。共有メモリが十分なメモリを持たないノードにノードロックされていないことを確認するためにメモリアドレスをテストする方法を考え出しました。これにより、プログラムは正常なエラーメッセージで早期に失敗します。したがって、これらのシグナルハンドラーは、この1つのコード(5バイトの小さなmemcpy)にのみ使用され、使用中のアプリをレスキューするためには使用されません。ここは安全だと思います。
これが「正しくない」場合はお詫び申し上げます。コメントしてください。修正します。ヒントと機能しなかったサンプルコードに基づいて、それをまとめました。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
sigjmp_buf JumpBuffer;
void handler(int);
int count = 0;
int main(void)
{
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&(sa.sa_mask));
sigaddset(&(sa.sa_mask), SIGSEGV);
sigaction(SIGSEGV, &sa, NULL);
while (1) {
int r = sigsetjmp(JumpBuffer,1);
if (r == 0) {
printf("Ready for memcpy, count=%d\n",count);
usleep(1000000);
char buffer[10];
#if 1
char* dst = buffer; // this won't do bad
#else
char* dst = nullptr; // this will cause a segfault
#endif
memcpy(dst,"12345",5); // trigger seg fault here
longjmp(JumpBuffer,2);
}
else if (r == 1)
{
printf("SEGV. count %d\n",count);
}
else if (r == 2)
{
printf("No segv. count %d\n",count);
}
}
return 0;
}
void handler(int sig)
{
count++;
siglongjmp(JumpBuffer, 1);
}
参考文献