tools/testing/selftests/x86/sigtrap_loop.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/x86/sigtrap_loop.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/x86/sigtrap_loop.c
Extension
.c
Size
2294 bytes
Lines
102
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (++loop_count_on_same_ip > 10) {
			printf("[FAIL]\tDetected SIGTRAP infinite loop\n");
			exit(1);
		}

		return;
	}

	loop_count_on_same_ip = 0;
	last_trap_ip = ctx->uc_mcontext.gregs[REG_IP];
	printf("\tTrapped at %016lx\n", last_trap_ip);
}

int main(int argc, char *argv[])
{
	sethandler(SIGTRAP, sigtrap, 0);

	/*
	 * Set the Trap Flag (TF) to single-step the test code, therefore to
	 * trigger a SIGTRAP signal after each instruction until the TF is
	 * cleared.
	 *
	 * Because the arithmetic flags are not significant here, the TF is
	 * set by pushing 0x302 onto the stack and then popping it into the
	 * flags register.
	 *
	 * Four instructions in the following asm code are executed with the
	 * TF set, thus the SIGTRAP handler is expected to run four times.
	 */
	printf("[RUN]\tSIGTRAP infinite loop detection\n");
	asm volatile(
#ifdef __x86_64__
		/*
		 * Avoid clobbering the redzone
		 *
		 * Equivalent to "sub $128, %rsp", however -128 can be encoded
		 * in a single byte immediate while 128 uses 4 bytes.
		 */
		"add $-128, %rsp\n\t"
#endif
		"push $0x302\n\t"
		"popf\n\t"
		"nop\n\t"
		"nop\n\t"
		"push $0x202\n\t"
		"popf\n\t"
#ifdef __x86_64__
		"sub $-128, %rsp\n\t"
#endif
	);

	printf("[OK]\tNo SIGTRAP infinite loop detected\n");
	return 0;
}

Annotation

Implementation Notes