1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
/*
* SPDX-FileCopyrightText: 2017 Francis Deslauriers <francis.deslauriers@efficios.com>
*
* SPDX-License-Identifier: LGPL-2.1-only
*
*/
#include "utils.h"
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
/*
* The process waits for the creation of a file passed as argument from an
* external processes to execute a syscall and exiting. This is useful for tests
* in combinaison with LTTng's PID tracker feature where we can trace the kernel
* events generated by our test process only.
*/
#if defined(__clang__)
#define nooptimization __attribute__((noinline)) __attribute__((optnone))
#else
#define nooptimization __attribute__((noinline)) __attribute__((optimize(0)))
#endif
volatile int val = 0;
long nooptimization my_gettid(void);
long nooptimization my_gettid(void)
{
long ret;
#ifdef __x86_64
asm volatile("syscall" : "=a"(ret) : "0"(__NR_gettid) : "cc", "rcx", "r11", "memory");
#elif defined(__i386)
asm volatile("int $0x80" : "=a"(ret) : "0"(__NR_gettid) : "cc", "edi", "esi", "memory");
#else
#error "Userspace callstack test not supported for this architecture."
#endif
return ret;
}
int nooptimization fct_c(void);
int nooptimization fct_c(void)
{
return my_gettid();
}
int nooptimization fct_b(void);
int nooptimization fct_b(void)
{
val += fct_c();
return val;
}
int nooptimization fct_a(void);
int nooptimization fct_a(void)
{
val += fct_b();
return val;
}
int main(int argc, char **argv)
{
int ret = 0;
char *start_file;
if (argc != 2) {
fprintf(stderr, "Error: Missing argument\n");
fprintf(stderr, "USAGE: %s PATH_WAIT_FILE\n", argv[0]);
ret = -1;
goto error;
}
start_file = argv[1];
/*
* Wait for the start_file to be created by an external process
* (typically the test script) before executing the syscall
*/
ret = wait_on_file(start_file);
if (ret != 0) {
goto error;
}
/* Start the callchain to the syscall */
ret = fct_a();
/* Return success */
if (ret >= 0) {
ret = 0;
}
error:
return ret;
}
|