Project
Loading...
Searching...
No Matches
o2Log.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifdef __APPLE__
12#import <dlfcn.h>
13#include <mach-o/dyld.h>
14#include <mach/host_info.h>
15#include <mach/mach.h>
16#include <mach/mach_host.h>
17#include <sys/mman.h>
18#include <sys/sysctl.h>
19#else
20#include <sys/ptrace.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23#endif
24
25#include <cassert>
26#include <cerrno>
27#include <cstdio>
28#include <cstdlib>
29#include <cstring>
30#include <getopt.h>
31
32#ifdef __APPLE__
33int xnu_write(int pid, void* addr, unsigned char* data, size_t dsize)
34{
35 assert(dsize != 0);
36 assert(addr != nullptr);
37 assert(data != nullptr);
38
39 auto* ptxt = (unsigned char*)malloc(dsize);
40
41 assert(ptxt != nullptr);
42 memcpy(ptxt, data, dsize);
43
44 mach_port_t task;
45 mach_msg_type_number_t dataCunt = dsize;
46
47 kern_return_t kret = task_for_pid(mach_task_self(), pid, &task);
48 if (kret != KERN_SUCCESS) {
49 printf("task_for_pid failed: %s. Are you root?", mach_error_string(kret));
50 return 0;
51 }
52
53 vm_protect(task, (vm_address_t)addr, (vm_size_t)dsize, 0,
54 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_ALL);
55
56 kret = vm_write(task, (vm_address_t)addr, (pointer_t)ptxt, dataCunt);
57
58 return kret;
59}
60#elif __linux__
61int xnu_write(int pid, void* addr, unsigned char* data, size_t dsize)
62{
63 if ((ptrace(PTRACE_ATTACH, pid, NULL, NULL)) < 0) {
64 perror("ptrace(ATTACH)");
65 exit(1);
66 }
67 int waitStat = 0;
68 int waitRes = waitpid(pid, &waitStat, WUNTRACED);
69 if (waitRes != pid || !WIFSTOPPED(waitStat)) {
70 perror("....:");
71 printf("Something went wrong...\n");
72 exit(1);
73 }
74
75 if ((ptrace(PTRACE_POKEDATA, pid, addr, data))) {
76 perror("pokedata");
77 }
78
79 if ((ptrace(PTRACE_DETACH, pid, NULL, NULL) < 0)) {
80 perror("ptrace(DETACH)");
81 exit(1);
82 }
83 return 0;
84}
85#endif
86
87// Writes a 4-byte value to the specified address in the target process
88// If the address in question points to private_o2_log_<signpost>::stacktrace
89// This will have the side effect of enabling the signpost.
90int main(int argc, char** argv)
91{
92 // Use getopt_long to parse command line arguments
93 // -p pid
94 // -a address
95 // -s stacktrace level (default 1, 0 to disable)
96 static struct option long_options[] = {
97 {"pid", required_argument, nullptr, 'p'},
98 {"address", required_argument, nullptr, 'a'},
99 {"stacktrace", required_argument, nullptr, 's'},
100 {nullptr, 0, nullptr, 0}};
101 int opt;
102 pid_t pid;
103 int stacktrace = 1;
104 void* addr;
105 while ((opt = getopt_long(argc, argv, "p:a:", long_options, nullptr)) != -1) {
106 switch (opt) {
107 case 'p':
108 pid = atoi(optarg);
109 break;
110 case 'a':
111 addr = (void*)strtoul(optarg, nullptr, 16);
112 break;
113 case 's':
114 stacktrace = strtol(optarg, nullptr, 10);
115 break;
116 default:
117 printf("Usage: %s -p pid -a address [-s level]\n", argv[0]);
118 exit(EXIT_FAILURE);
119 }
120 }
121 xnu_write(pid, addr, (unsigned char*)&stacktrace, 4);
122 return 0;
123}
uint16_t pid
Definition RawData.h:2
GLboolean * data
Definition glcorearb.h:298
#define main