mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-09 00:46:12 +00:00
82 lines
1.8 KiB
C
82 lines
1.8 KiB
C
|
|
/* Check that the main thread's stack, on Linux, is automatically
|
|
extended down to the lowest valid address when a syscall happens.
|
|
Failure to do so was causing this test to fail on Linux amd64. */
|
|
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#include <sys/syscall.h>
|
|
#include <unistd.h>
|
|
|
|
#define VG_STRINGIFZ(__str) #__str
|
|
#define VG_STRINGIFY(__str) VG_STRINGIFZ(__str)
|
|
|
|
#if defined(VGO_linux) || defined(VGO_darwin)
|
|
#define __NR_READLINK VG_STRINGIFY(__NR_readlink)
|
|
|
|
extern long my_readlink ( const char* path );
|
|
asm(
|
|
".text\n"
|
|
".globl my_readlink\n"
|
|
"my_readlink:\n"
|
|
"\tsubq $0x1008,%rsp\n"
|
|
"\tmovq %rdi,%rdi\n" // path is in rdi
|
|
"\tmovq %rsp,%rsi\n" // &buf[0] -> rsi
|
|
"\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx
|
|
"\tmovl $"__NR_READLINK",%eax\n" // syscall number
|
|
"\tsyscall\n"
|
|
"\taddq $0x1008,%rsp\n"
|
|
"\tret\n"
|
|
".previous\n"
|
|
);
|
|
|
|
#elif defined(VGO_solaris)
|
|
#define __NR_READLINKAT VG_STRINGIFY(SYS_readlinkat)
|
|
|
|
extern long my_readlink ( const char* path );
|
|
asm(
|
|
".text\n"
|
|
".globl my_readlink\n"
|
|
"my_readlink:\n"
|
|
"\tsubq $0x1008,%rsp\n"
|
|
"\tmovq %rdi,%rsi\n"
|
|
"\txorq %rdi,%rdi\n"
|
|
"\tmovq %rsp,%rdx\n"
|
|
"\tmovq $0x1000,%r10\n"
|
|
"\tmovl $"__NR_READLINKAT",%eax\n"
|
|
"\tsyscall\n"
|
|
"\taddq $0x1008,%rsp\n"
|
|
"\tret\n"
|
|
".previous\n"
|
|
);
|
|
|
|
#else
|
|
#error "Unknown OS"
|
|
#endif
|
|
|
|
long recurse ( const char* path, long count )
|
|
{
|
|
if (count <= 0) {
|
|
return my_readlink(path);
|
|
} else {
|
|
long r = recurse(path, count-1);
|
|
return r;
|
|
}
|
|
}
|
|
|
|
int main ( void )
|
|
{
|
|
long i, r;
|
|
for (i = 0; i < 2000; i++) {
|
|
printf("depth %ld: ", i );
|
|
r = recurse( "/proc/self", i );
|
|
if (r > 1) r = 1; /* to make the output repeatable */
|
|
assert(r >= 1);
|
|
printf("r = %ld\n", r);
|
|
}
|
|
return 0;
|
|
}
|