어떻게 UBSan 보고서 gdb를 중단하고 계속할 수 있습니까?
( Behavior 으로 합니다.-fsanitize=undefined
런타임 계측 코드를 추가합니다.오류가 발생하면 다음과 같은 경고가 표시됩니다.
packet-ber.c:165:23: 런타임 오류: 54645397829836991의 8자리 왼쪽 이동은 'longint' 유형으로 나타낼 수 없습니다.
이제 저는 이것을 디버그하고 해당 라인에서 디버그 브레이크를 받고 싶습니다.ASA Sanitizer에는 ASA(Address Sanitizer)가 .ASAN_OPTIONS=abort_on_error=1
치명적인 오류가 발생할 수 있습니다.사용 가능한 것으로 보이는 유일한 UBSan 옵션은 보고서에 대한 호출 추적 덤프를 생성하는 것입니다.그러나 이를 통해 로컬 변수를 검사한 다음 프로그램을 계속할 수 없습니다.사용-fsanitize-undefined-trap-on-error
따라서 불가능합니다.
UBSan 보고서에서 gdb를 어떻게 위반해야 합니까?하는 동안에break __sanitizer::SharedPrintfCode
효과가 있는 것 같아요, 이름이 꽤 내부적으로 보입니다.
@Mark Plotnick 및 @I will not exist에 의해 설명된 것처럼 탐지 기능을 중단하는 것도 한 가지 옵션이지만, 탐지 후 이러한 문제를 보고하는 기능을 중단하는 것이 더 나은 접근 방식입니다.이 접근 방식은 또한 ASAN에 사용됩니다. ASAN에서는 다음과 같은 방식을 사용할 수 있습니다.__asan_report_error
.
요약:.또는 의 중단점을 통해 ubsan 보고서에서 중지할 수 있습니다.이러한 세부 사항은 향후 변경될 수도 있는 비공개 구현 세부 사항입니다.GCC 4.9, 5.1.0, 5.2.0 및 Clang 3.3, 3.4, 3.6.2로 테스트했습니다.
ppa:ubuntu-toolchain-r/test의 GCC 4.9.2의 경우 다음이 필요합니다.libubsan0-dbg
위의 중단점을 사용할 수 있도록 합니다. 3및 3 14는 Clang 3.3 버전 3.4 버전 Ubuntu 14.04를 .__ubsan::ScopedReport::~ScopedReport
중단점을 사용하여 메시지를 인쇄하기 전에만 중단할 수 있습니다.
버그 소스 코드 및 agdb 세션의 예:
$ cat undef.c
int main(void) { return 1 << 1000; }
$ clang --version
clang version 3.6.2 (tags/RELEASE_362/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
$ clang -w -fsanitize=undefined undef.c -g
$ gdb -q -ex break\ __ubsan::ScopedReport::~ScopedReport -ex r ./a.out
Reading symbols from ./a.out...done.
Breakpoint 1 at 0x428fb0
Starting program: ./a.out
undef.c:1:27: runtime error: shift exponent 1000 is too large for 32-bit type 'int'
Breakpoint 1, 0x0000000000428fb0 in __ubsan::ScopedReport::~ScopedReport() ()
(gdb) bt
#0 0x0000000000428fb0 in __ubsan::ScopedReport::~ScopedReport() ()
#1 0x000000000042affb in handleShiftOutOfBoundsImpl(__ubsan::ShiftOutOfBoundsData*, unsigned long, unsigned long, __ubsan::ReportOptions) ()
#2 0x000000000042a952 in __ubsan_handle_shift_out_of_bounds ()
#3 0x000000000042d057 in main () at undef.c:1
자세한 분석은 다음과 같습니다.ASA와 ubsan 모두 LLVM 프로젝트인 compiler-rt에서 비롯되었습니다.이것은 Clang에 의해 사용되고 GCC에도 포함됩니다.다음 섹션의 링크는 compiler-rt 프로젝트 코드 릴리스 3.6을 가리킵니다.
ASAN을 .__asan_report_error
문서화된 공용 인터페이스의 일부.이 함수는 위반이 탐지될 때마다 lib/asan/asan_report.c:938에서 해당 흐름이 계속됩니다.
void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
uptr access_size) {
// Determine the error type.
const char *bug_descr = "unknown-crash";
...
ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size,
bug_descr };
ScopedInErrorReport in_report(&report);
Decorator d;
Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: %s on address "
"%p at pc %p bp %p sp %p\n",
bug_descr, (void*)addr, pc, bp, sp);
Printf("%s", d.EndWarning());
u32 curr_tid = GetCurrentTidOrInvalid();
char tname[128];
Printf("%s%s of size %zu at %p thread T%d%s%s\n",
d.Access(),
access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
access_size, (void*)addr, curr_tid,
ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)),
d.EndAccess());
GET_STACK_TRACE_FATAL(pc, bp);
stack.Print();
DescribeAddress(addr, access_size);
ReportErrorSummary(bug_descr, &stack);
PrintShadowMemoryForAddress(addr);
}
반면에 ubsan은 공개 인터페이스가 없지만 현재 구현은 훨씬 간단하고 제한적입니다(옵션이 적습니다).오류가 발생할 경우 스택 추적은 다음과 같이 인쇄될 수 있습니다.UBSAN_OPTIONS=print_stacktrace=1
환경 변수가 설정되었습니다.따라서 소스 코드를 검색하여 다음을 찾습니다.print_stacktrace
ScopeedReport 소멸자를 통해 호출되는 MaybePrintStackTrace 함수를 찾습니다.
ScopedReport::~ScopedReport() {
MaybePrintStackTrace(Opts.pc, Opts.bp);
MaybeReportErrorSummary(SummaryLoc);
CommonSanitizerReportMutex.Unlock();
if (Opts.DieAfterReport || flags()->halt_on_error)
Die();
}
보시다시피 오류가 발생하면 프로그램을 종료하는 방법이 있지만 안타깝게도 디버거 트랩을 트리거하는 내장 메커니즘은 없습니다.그럼 적당한 중단점을 찾아보죠.
GDB 명령어는 다음과 같은 것을 식별하는 것을 가능하게 했습니다.MaybePrintStackTrace
중단점을 설정할 수 있는 함수입니다. info functions ScopedReport::~ScopedReport
는 또 기능을 했습니다: 다른기제니다습공했.__ubsan::ScopedReport::~ScopedReport
디버깅 기호가 설치된 경우에도 이러한 기능을 사용할 수 없는 것 같으면 시도할 수 있습니다.info functions ubsan
또는info functions sanitizer
모두 가져오기(정의되지 않은 동작)살균제 관련 기능입니다.
@Mark Plotnick이 지적했듯이, 그렇게 하는 방법은 UBSan의 핸들러를 중단시키는 것입니다.
UBSan에는 정의되지 않은 동작을 위해 호출되는 여러 핸들러 또는 매직 함수 진입점이 있습니다.컴파일러는 적절한 검사를 주입하여 코드를 인스트루먼트합니다. 검사 코드가 UB를 탐지하면 이러한 처리기를 호출합니다. 그은모시작다니합두로 합니다.__ubsan_handle_
에 정의되어 있습니다.libsanitizer/ubsan/ubsan_handlers.h
여기 GCC의 복사본에 대한 링크가 있습니다.
다음은 UBSan 헤더의 관련 비트입니다(이 중 하나에 대한 중단점).
#define UNRECOVERABLE(checkname, ...) \
extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \
void __ubsan_handle_ ## checkname( __VA_ARGS__ );
#define RECOVERABLE(checkname, ...) \
extern "C" SANITIZER_INTERFACE_ATTRIBUTE \
void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \
extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \
void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ );
/// \brief Handle a runtime type check failure, caused by either a misaligned
/// pointer, a null pointer, or a pointer to insufficient storage for the
/// type.
RECOVERABLE(type_mismatch, TypeMismatchData *Data, ValueHandle Pointer)
/// \brief Handle an integer addition overflow.
RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
/// \brief Handle an integer subtraction overflow.
RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
/// \brief Handle an integer multiplication overflow.
RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
/// \brief Handle a signed integer overflow for a unary negate operator.
RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal)
/// \brief Handle an INT_MIN/-1 overflow or division by zero.
RECOVERABLE(divrem_overflow, OverflowData *Data,
ValueHandle LHS, ValueHandle RHS)
/// \brief Handle a shift where the RHS is out of bounds or a left shift where
/// the LHS is negative or overflows.
RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data,
ValueHandle LHS, ValueHandle RHS)
/// \brief Handle an array index out of bounds error.
RECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index)
/// \brief Handle a __builtin_unreachable which is reached.
UNRECOVERABLE(builtin_unreachable, UnreachableData *Data)
/// \brief Handle reaching the end of a value-returning function.
UNRECOVERABLE(missing_return, UnreachableData *Data)
/// \brief Handle a VLA with a non-positive bound.
RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound)
/// \brief Handle overflow in a conversion to or from a floating-point type.
RECOVERABLE(float_cast_overflow, FloatCastOverflowData *Data, ValueHandle From)
/// \brief Handle a load of an invalid value for the type.
RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val)
RECOVERABLE(function_type_mismatch,
FunctionTypeMismatchData *Data,
ValueHandle Val)
/// \brief Handle returning null from function with returns_nonnull attribute.
RECOVERABLE(nonnull_return, NonNullReturnData *Data)
/// \brief Handle passing null pointer to function with nonnull attribute.
RECOVERABLE(nonnull_arg, NonNullArgData *Data)
산이 훨씬 더 쉽습니다.,libsanitizer/include/sanitizer/asan_interface.h
당신은 여기서 이것을 검색해야 하며, 당신은 댓글의 죽은 증정물을 읽을 수 있습니다.
// This is an internal function that is called to report an error.
// However it is still a part of the interface because users may want to
// set a breakpoint on this function in a debugger.
void __asan_report_error(void *pc, void *bp, void *sp,
void *addr, int is_write, size_t access_size);
이 헤더의 다른 수많은 함수는 디버거에서 호출할 수 있도록 공개된 것으로 명시적으로 설명됩니다.
의 다른 헤더를 살펴보시는 것이 좋습니다.libsanitizer/include/sanitizer
여기. 거기에는 먹을 수 있는 많은 맛있는 것들이 있습니다.
UBSan 및 ASan의 중단점은 다음과 같이 추가할 수 있습니다.
(gdb) rbreak ^__ubsan_handle_ __asan_report_error
(gdb) commands
(gdb) finish
(gdb) end
핸들러의 , " "는 " " 입니다.finish
직에후 하면 할 수 할 수 .이렇게 하면 보고서를 인쇄할 수 있지만 디버거는 인쇄된 직후에 제어할 수 있습니다.
이 단점설시간으로 :__asan_report_error
프로그램은 디버거를 트리거하지 않고 진단을 인쇄한 후에만 존재합니다. __asan::ReportGenericError
및 진을기전에를 __sanitizer::Die
진단을 인쇄한 후 Wiki로 설명된 대로 히트합니다.
언급URL : https://stackoverflow.com/questions/30809022/how-can-i-break-on-ubsan-reports-in-gdb-and-continue
'source' 카테고리의 다른 글
debug=true in web.config = 나쁜 것? (0) | 2023.06.10 |
---|---|
asp.net 회원 자격 이전 비밀번호를 모르고 비밀번호 변경 (0) | 2023.06.10 |
앱 스토어 링크: "이 앱 등급/검토" (0) | 2023.06.10 |
Oracle 12c에서 SQL 쿼리의 결과를 JSON으로 반환합니다. (0) | 2023.06.10 |
C 다중 매크로의 사전 프로세서 테스트 정의 (0) | 2023.06.10 |