1 1.1 christos #!/bin/sh 2 1.1 christos # 3 1.1 christos # dtruss - print process system call time details. 4 1.1 christos # Written using DTrace (Solaris 10 3/05). 5 1.1 christos # 6 1.1 christos # $Id: dtruss,v 1.1.1.1 2015/09/30 22:01:07 christos Exp $ 7 1.1 christos # 8 1.1 christos # USAGE: dtruss [-acdeflhoLs] [-t syscall] { -p PID | -n name | command } 9 1.1 christos # 10 1.1 christos # -p PID # examine this PID 11 1.1 christos # -n name # examine this process name 12 1.1 christos # -t syscall # examine this syscall only 13 1.1 christos # -a # print all details 14 1.1 christos # -c # print system call counts 15 1.1 christos # -d # print relative timestamps (us) 16 1.1 christos # -e # print elapsed times (us) 17 1.1 christos # -f # follow children as they are forked 18 1.1 christos # -l # force printing of pid/lwpid per line 19 1.1 christos # -o # print on cpu times (us) 20 1.1 christos # -s # print stack backtraces 21 1.1 christos # -L # don't print pid/lwpid per line 22 1.1 christos # -b bufsize # dynamic variable buf size (default is "4m") 23 1.1 christos # eg, 24 1.1 christos # dtruss df -h # run and examine the "df -h" command 25 1.1 christos # dtruss -p 1871 # examine PID 1871 26 1.1 christos # dtruss -n tar # examine all processes called "tar" 27 1.1 christos # dtruss -f test.sh # run test.sh and follow children 28 1.1 christos # 29 1.1 christos # See the man page dtruss(1M) for further details. 30 1.1 christos # 31 1.1 christos # SEE ALSO: procsystime # DTraceToolkit 32 1.1 christos # dapptrace # DTraceToolkit 33 1.1 christos # truss 34 1.1 christos # 35 1.1 christos # COPYRIGHT: Copyright (c) 2005, 2006, 2007 Brendan Gregg. 36 1.1 christos # 37 1.1 christos # CDDL HEADER START 38 1.1 christos # 39 1.1 christos # The contents of this file are subject to the terms of the 40 1.1 christos # Common Development and Distribution License, Version 1.0 only 41 1.1 christos # (the "License"). You may not use this file except in compliance 42 1.1 christos # with the License. 43 1.1 christos # 44 1.1 christos # You can obtain a copy of the license at Docs/cddl1.txt 45 1.1 christos # or http://www.opensolaris.org/os/licensing. 46 1.1 christos # See the License for the specific language governing permissions 47 1.1 christos # and limitations under the License. 48 1.1 christos # 49 1.1 christos # CDDL HEADER END 50 1.1 christos # 51 1.1 christos # TODO: Track signals, more output formatting. 52 1.1 christos # 53 1.1 christos # 29-Apr-2005 Brendan Gregg Created this. 54 1.1 christos # 09-May-2005 " " Fixed evaltime (thanks Adam L.) 55 1.1 christos # 16-May-2005 " " Added -t syscall tracing. 56 1.1 christos # 17-Jun-2005 " " Added -s stack backtraces. 57 1.1 christos # 17-Jun-2005 " " Last update. 58 1.1 christos # 29-Jun-2007 " " Used progenyof() (thanks Aaron Gutman). 59 1.1 christos # 06-Aug-2007 " " Various updates. 60 1.1 christos # 61 1.1 christos 62 1.1 christos 63 1.1 christos ############################## 64 1.1 christos # --- Process Arguments --- 65 1.1 christos # 66 1.1 christos 67 1.1 christos ### Default variables 68 1.1 christos opt_pid=0; opt_name=0; pid=0; pname="."; opt_elapsed=0; opt_cpu=0 69 1.1 christos opt_counts=0; opt_relative=0; opt_printid=0; opt_follow=0; opt_command=0 70 1.1 christos command=""; opt_buf=0; buf="4m"; opt_trace=0; trace="."; opt_stack=0 71 1.1 christos 72 1.1 christos ### Process options 73 1.1 christos while getopts ab:cdefhln:op:st:L name 74 1.1 christos do 75 1.1 christos case $name in 76 1.1 christos b) opt_buf=1; buf=$OPTARG ;; 77 1.1 christos p) opt_pid=1; pid=$OPTARG ;; 78 1.1 christos n) opt_name=1; pname=$OPTARG ;; 79 1.1 christos t) opt_trace=1; trace=$OPTARG ;; 80 1.1 christos a) opt_counts=1; opt_relative=1; opt_elapsed=1; opt_follow=1 81 1.1 christos opt_printid=1; opt_cpu=1 ;; 82 1.1 christos c) opt_counts=1 ;; 83 1.1 christos d) opt_relative=1 ;; 84 1.1 christos e) opt_elapsed=1 ;; 85 1.1 christos f) opt_follow=1 ;; 86 1.1 christos l) opt_printid=1 ;; 87 1.1 christos o) opt_cpu=1 ;; 88 1.1 christos L) opt_printid=-1 ;; 89 1.1 christos s) opt_stack=-1 ;; 90 1.1 christos h|?) cat <<-END >&2 91 1.1 christos USAGE: dtruss [-acdefholLs] [-t syscall] { -p PID | -n name | command } 92 1.1 christos 93 1.1 christos -p PID # examine this PID 94 1.1 christos -n name # examine this process name 95 1.1 christos -t syscall # examine this syscall only 96 1.1 christos -a # print all details 97 1.1 christos -c # print syscall counts 98 1.1 christos -d # print relative times (us) 99 1.1 christos -e # print elapsed times (us) 100 1.1 christos -f # follow children (-p or cmd only) 101 1.1 christos -l # force printing pid/lwpid 102 1.1 christos -o # print on cpu times 103 1.1 christos -s # print stack backtraces 104 1.1 christos -L # don't print pid/lwpid 105 1.1 christos -b bufsize # dynamic variable buf size 106 1.1 christos eg, 107 1.1 christos dtruss df -h # run and examine "df -h" 108 1.1 christos dtruss -p 1871 # examine PID 1871 109 1.1 christos dtruss -n tar # examine all processes called "tar" 110 1.1 christos dtruss -f test.sh # run test.sh and follow children 111 1.1 christos END 112 1.1 christos exit 1 113 1.1 christos esac 114 1.1 christos done 115 1.1 christos shift `expr $OPTIND - 1` 116 1.1 christos 117 1.1 christos ### Option logic 118 1.1 christos if [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then 119 1.1 christos opt_command=1 120 1.1 christos if [ "$*" = "" ]; then 121 1.1 christos $0 -h 122 1.1 christos exit 123 1.1 christos fi 124 1.1 christos command="$*" # yes, I meant $*! 125 1.1 christos fi 126 1.1 christos if [ $opt_follow -eq 1 -o $opt_name -eq 1 ]; then 127 1.1 christos if [ $opt_printid -ne -1 ]; then 128 1.1 christos opt_printid=1 129 1.1 christos else 130 1.1 christos opt_printid=0 131 1.1 christos fi 132 1.1 christos fi 133 1.1 christos if [ $opt_follow -eq 1 -a $opt_name -eq 1 ]; then 134 1.1 christos echo "ERROR: -f option cannot be used with -n (use -p or cmd instead)." 135 1.1 christos exit 1 136 1.1 christos fi 137 1.1 christos 138 1.1 christos ### Option translation 139 1.1 christos if [ "$trace" = "exec" ]; then trace="exece"; fi 140 1.1 christos if [ "$trace" = "time" ]; then trace="gtime"; fi 141 1.1 christos if [ "$trace" = "exit" ]; then trace="rexit"; fi 142 1.1 christos 143 1.1 christos 144 1.1 christos ################################# 145 1.1 christos # --- Main Program, DTrace --- 146 1.1 christos # 147 1.1 christos 148 1.1 christos ### Define D Script 149 1.1 christos dtrace=' 150 1.1 christos #pragma D option quiet 151 1.1 christos #pragma D option switchrate=10 152 1.1 christos 153 1.1 christos /* 154 1.1 christos * Command line arguments 155 1.1 christos */ 156 1.1 christos inline int OPT_command = '$opt_command'; 157 1.1 christos inline int OPT_follow = '$opt_follow'; 158 1.1 christos inline int OPT_printid = '$opt_printid'; 159 1.1 christos inline int OPT_relative = '$opt_relative'; 160 1.1 christos inline int OPT_elapsed = '$opt_elapsed'; 161 1.1 christos inline int OPT_cpu = '$opt_cpu'; 162 1.1 christos inline int OPT_counts = '$opt_counts'; 163 1.1 christos inline int OPT_pid = '$opt_pid'; 164 1.1 christos inline int OPT_name = '$opt_name'; 165 1.1 christos inline int OPT_trace = '$opt_trace'; 166 1.1 christos inline int OPT_stack = '$opt_stack'; 167 1.1 christos inline string NAME = "'$pname'"; 168 1.1 christos inline string TRACE = "'$trace'"; 169 1.1 christos 170 1.1 christos dtrace:::BEGIN 171 1.1 christos { 172 1.1 christos /* print header */ 173 1.1 christos OPT_printid ? printf("%-9s ", "PID/LWP") : 1; 174 1.1 christos OPT_relative ? printf("%8s ", "RELATIVE") : 1; 175 1.1 christos OPT_elapsed ? printf("%7s ", "ELAPSD") : 1; 176 1.1 christos OPT_cpu ? printf("%6s ", "CPU") : 1; 177 1.1 christos printf("SYSCALL(args) \t\t = return\n"); 178 1.1 christos } 179 1.1 christos 180 1.1 christos /* 181 1.1 christos * Save syscall entry info 182 1.1 christos */ 183 1.1 christos syscall:::entry 184 1.1 christos /((OPT_command || OPT_pid) && pid == $target) || 185 1.1 christos (OPT_name && execname == NAME) || 186 1.1 christos (OPT_follow && progenyof($target))/ 187 1.1 christos { 188 1.1 christos /* set start details */ 189 1.1 christos self->start = timestamp; 190 1.1 christos self->vstart = vtimestamp; 191 1.1 christos self->arg0 = arg0; 192 1.1 christos self->arg1 = arg1; 193 1.1 christos self->arg2 = arg2; 194 1.1 christos 195 1.1 christos /* count occurances */ 196 1.1 christos OPT_counts == 1 ? @Counts[probefunc] = count() : 1; 197 1.1 christos } 198 1.1 christos 199 1.1 christos /* 200 1.1 christos * Follow children 201 1.1 christos */ 202 1.1 christos syscall::fork*:return 203 1.1 christos /(OPT_follow && progenyof($target)) && (!OPT_trace || (TRACE == probefunc))/ 204 1.1 christos { 205 1.1 christos /* print output */ 206 1.1 christos self->code = errno == 0 ? "" : "Err#"; 207 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 208 1.1 christos OPT_relative ? printf("%8d: ", vtimestamp/1000) : 1; 209 1.1 christos OPT_elapsed ? printf("%7d: ", 0) : 1; 210 1.1 christos OPT_cpu ? printf("%6d ", 0) : 1; 211 1.1 christos printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, 212 1.1 christos self->arg0, self->arg1, self->arg2, (int)arg0, self->code, 213 1.1 christos (int)errno); 214 1.1 christos } 215 1.1 christos 216 1.1 christos /* 217 1.1 christos * Check for syscall tracing 218 1.1 christos */ 219 1.1 christos syscall:::entry 220 1.1 christos /OPT_trace && probefunc != TRACE/ 221 1.1 christos { 222 1.1 christos /* drop info */ 223 1.1 christos self->start = 0; 224 1.1 christos self->vstart = 0; 225 1.1 christos self->arg0 = 0; 226 1.1 christos self->arg1 = 0; 227 1.1 christos self->arg2 = 0; 228 1.1 christos } 229 1.1 christos 230 1.1 christos /* 231 1.1 christos * Print return data 232 1.1 christos */ 233 1.1 christos 234 1.1 christos /* 235 1.1 christos * The following code is written in an intentionally repetative way. 236 1.1 christos * The first versions had no code redundancies, but performed badly during 237 1.1 christos * benchmarking. The priority here is speed, not cleverness. I know there 238 1.1 christos * are many obvious shortcuts to this code, I have tried them. This style has 239 1.1 christos * shown in benchmarks to be the fastest (fewest probes fired, fewest actions). 240 1.1 christos */ 241 1.1 christos 242 1.1 christos /* print 3 args, return as hex */ 243 1.1 christos syscall::sigprocmask:return 244 1.1 christos /self->start/ 245 1.1 christos { 246 1.1 christos /* calculate elapsed time */ 247 1.1 christos this->elapsed = timestamp - self->start; 248 1.1 christos self->start = 0; 249 1.1 christos this->cpu = vtimestamp - self->vstart; 250 1.1 christos self->vstart = 0; 251 1.1 christos self->code = errno == 0 ? "" : "Err#"; 252 1.1 christos 253 1.1 christos /* print optional fields */ 254 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 255 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 256 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 257 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 258 1.1 christos 259 1.1 christos /* print main data */ 260 1.1 christos printf("%s(0x%X, 0x%X, 0x%X)\t\t = 0x%X %s%d\n", probefunc, 261 1.1 christos (int)self->arg0, self->arg1, self->arg2, (int)arg0, 262 1.1 christos self->code, (int)errno); 263 1.1 christos OPT_stack ? ustack() : 1; 264 1.1 christos OPT_stack ? trace("\n") : 1; 265 1.1 christos self->arg0 = 0; 266 1.1 christos self->arg1 = 0; 267 1.1 christos self->arg2 = 0; 268 1.1 christos } 269 1.1 christos 270 1.1 christos /* print 3 args, arg0 as a string */ 271 1.1 christos syscall::access*:return, 272 1.1 christos syscall::stat*:return, 273 1.1 christos syscall::lstat*:return, 274 1.1 christos syscall::readlink*:return, 275 1.1 christos syscall::open*:return 276 1.1 christos /self->start/ 277 1.1 christos { 278 1.1 christos /* calculate elapsed time */ 279 1.1 christos this->elapsed = timestamp - self->start; 280 1.1 christos self->start = 0; 281 1.1 christos this->cpu = vtimestamp - self->vstart; 282 1.1 christos self->vstart = 0; 283 1.1 christos self->code = errno == 0 ? "" : "Err#"; 284 1.1 christos 285 1.1 christos /* print optional fields */ 286 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 287 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 288 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 289 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 290 1.1 christos 291 1.1 christos /* print main data */ 292 1.1 christos printf("%s(\"%S\", 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, 293 1.1 christos copyinstr(self->arg0), self->arg1, self->arg2, (int)arg0, 294 1.1 christos self->code, (int)errno); 295 1.1 christos OPT_stack ? ustack() : 1; 296 1.1 christos OPT_stack ? trace("\n") : 1; 297 1.1 christos self->arg0 = 0; 298 1.1 christos self->arg1 = 0; 299 1.1 christos self->arg2 = 0; 300 1.1 christos } 301 1.1 christos 302 1.1 christos /* print 3 args, arg1 as a string */ 303 1.1 christos syscall::write:return, 304 1.1 christos syscall::pwrite:return, 305 1.1 christos syscall::*read*:return 306 1.1 christos /self->start/ 307 1.1 christos { 308 1.1 christos /* calculate elapsed time */ 309 1.1 christos this->elapsed = timestamp - self->start; 310 1.1 christos self->start = 0; 311 1.1 christos this->cpu = vtimestamp - self->vstart; 312 1.1 christos self->vstart = 0; 313 1.1 christos self->code = errno == 0 ? "" : "Err#"; 314 1.1 christos 315 1.1 christos /* print optional fields */ 316 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 317 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 318 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 319 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 320 1.1 christos 321 1.1 christos /* print main data */ 322 1.1 christos printf("%s(0x%X, \"%S\", 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 323 1.1 christos stringof(copyin(self->arg1, self->arg2)), self->arg2, (int)arg0, 324 1.1 christos self->code, (int)errno); 325 1.1 christos OPT_stack ? ustack() : 1; 326 1.1 christos OPT_stack ? trace("\n") : 1; 327 1.1 christos self->arg0 = 0; 328 1.1 christos self->arg1 = 0; 329 1.1 christos self->arg2 = 0; 330 1.1 christos } 331 1.1 christos 332 1.1 christos /* print 0 arg output */ 333 1.1 christos syscall::*fork*:return 334 1.1 christos /self->start/ 335 1.1 christos { 336 1.1 christos /* calculate elapsed time */ 337 1.1 christos this->elapsed = timestamp - self->start; 338 1.1 christos self->start = 0; 339 1.1 christos this->cpu = vtimestamp - self->vstart; 340 1.1 christos self->vstart = 0; 341 1.1 christos self->code = errno == 0 ? "" : "Err#"; 342 1.1 christos 343 1.1 christos /* print optional fields */ 344 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 345 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 346 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 347 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 348 1.1 christos 349 1.1 christos /* print main data */ 350 1.1 christos printf("%s()\t\t = %d %s%d\n", probefunc, 351 1.1 christos (int)arg0, self->code, (int)errno); 352 1.1 christos OPT_stack ? ustack() : 1; 353 1.1 christos OPT_stack ? trace("\n") : 1; 354 1.1 christos self->arg0 = 0; 355 1.1 christos self->arg1 = 0; 356 1.1 christos self->arg2 = 0; 357 1.1 christos } 358 1.1 christos 359 1.1 christos /* print 1 arg output */ 360 1.1 christos syscall::close:return 361 1.1 christos /self->start/ 362 1.1 christos { 363 1.1 christos /* calculate elapsed time */ 364 1.1 christos this->elapsed = timestamp - self->start; 365 1.1 christos self->start = 0; 366 1.1 christos this->cpu = vtimestamp - self->vstart; 367 1.1 christos self->vstart = 0; 368 1.1 christos self->code = errno == 0 ? "" : "Err#"; 369 1.1 christos 370 1.1 christos /* print optional fields */ 371 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 372 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 373 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 374 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 375 1.1 christos 376 1.1 christos /* print main data */ 377 1.1 christos printf("%s(0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 378 1.1 christos (int)arg0, self->code, (int)errno); 379 1.1 christos OPT_stack ? ustack() : 1; 380 1.1 christos OPT_stack ? trace("\n") : 1; 381 1.1 christos self->arg0 = 0; 382 1.1 christos self->arg1 = 0; 383 1.1 christos self->arg2 = 0; 384 1.1 christos } 385 1.1 christos 386 1.1 christos /* print 2 arg output */ 387 1.1 christos syscall::utimes:return, 388 1.1 christos syscall::munmap:return 389 1.1 christos /self->start/ 390 1.1 christos { 391 1.1 christos /* calculate elapsed time */ 392 1.1 christos this->elapsed = timestamp - self->start; 393 1.1 christos self->start = 0; 394 1.1 christos this->cpu = vtimestamp - self->vstart; 395 1.1 christos self->vstart = 0; 396 1.1 christos self->code = errno == 0 ? "" : "Err#"; 397 1.1 christos 398 1.1 christos /* print optional fields */ 399 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 400 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 401 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 402 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 403 1.1 christos 404 1.1 christos /* print main data */ 405 1.1 christos printf("%s(0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 406 1.1 christos self->arg1, (int)arg0, self->code, (int)errno); 407 1.1 christos OPT_stack ? ustack() : 1; 408 1.1 christos OPT_stack ? trace("\n") : 1; 409 1.1 christos self->arg0 = 0; 410 1.1 christos self->arg1 = 0; 411 1.1 christos self->arg2 = 0; 412 1.1 christos } 413 1.1 christos 414 1.1 christos /* print 3 arg output - default */ 415 1.1 christos syscall:::return 416 1.1 christos /self->start/ 417 1.1 christos { 418 1.1 christos /* calculate elapsed time */ 419 1.1 christos this->elapsed = timestamp - self->start; 420 1.1 christos self->start = 0; 421 1.1 christos this->cpu = vtimestamp - self->vstart; 422 1.1 christos self->vstart = 0; 423 1.1 christos self->code = errno == 0 ? "" : "Err#"; 424 1.1 christos 425 1.1 christos /* print optional fields */ 426 1.1 christos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 427 1.1 christos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 428 1.1 christos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 429 1.1 christos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 430 1.1 christos 431 1.1 christos /* print main data */ 432 1.1 christos printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 433 1.1 christos self->arg1, self->arg2, (int)arg0, self->code, (int)errno); 434 1.1 christos OPT_stack ? ustack() : 1; 435 1.1 christos OPT_stack ? trace("\n") : 1; 436 1.1 christos self->arg0 = 0; 437 1.1 christos self->arg1 = 0; 438 1.1 christos self->arg2 = 0; 439 1.1 christos } 440 1.1 christos 441 1.1 christos /* program exited */ 442 1.1 christos proc:::exit 443 1.1 christos /(OPT_command || OPT_pid) && pid == $target/ 444 1.1 christos { 445 1.1 christos exit(0); 446 1.1 christos } 447 1.1 christos 448 1.1 christos /* print counts */ 449 1.1 christos dtrace:::END 450 1.1 christos { 451 1.1 christos OPT_counts == 1 ? printf("\n%-32s %16s\n", "CALL", "COUNT") : 1; 452 1.1 christos OPT_counts == 1 ? printa("%-32s %@16d\n", @Counts) : 1; 453 1.1 christos } 454 1.1 christos ' 455 1.1 christos 456 1.1 christos ### Run DTrace 457 1.1 christos if [ $opt_command -eq 1 ]; then 458 1.1 christos /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \ 459 1.1 christos -c "$command" >&2 460 1.1 christos elif [ $opt_pid -eq 1 ]; then 461 1.1 christos /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2 462 1.1 christos else 463 1.1 christos /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" >&2 464 1.1 christos fi 465