/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/* 
 * pg_ltrace.c
 * 	Poor linux's tracing facility.
 *
 */

#include <pg_config.h>
#ifdef ENABLE_LTRACE
#include <sys/types.h>

#include <unistd.h>
#include <pg_trace.h>
#include <stdio.h>

extern int gp_ltrace_flag;

struct pg_trace_data_t
{
	long val[9];
};

/* 
 * Poor linux tracing facility.
 *
 * Unlike dtrace, linux tracing (SystemTap) at this moment
 * does not support user space tracing.  We use the following
 * HACK to get some tracing.
 *
 * The write is strange.  Postgres will redirect fd 0 (stdin) to 
 * read from /dev/null.  We are writing to stdin, a string of 0 bytes.
 * it will fail, as stdin is readonly, but, it is still a system call.
 * In system tap, we can catch at syscall.write and test $fd == 0 and 
 * $count == 0.  The constructed buffer can be accessed by $buf.
 *
 * Note that the $fd = 0 and $count = 0 hack is kind of "Needed".  
 * If the fd is not valid, then actually the systemtap syscalls tapset
 * will not catch it.  Count set to 0 is safe.
 *
 * NOTE: At this moment, SystemTap cannot even display user stack.
 * if we really want the stack, we can construct the stack using backtrace()
 * and put the string as the str arg.
 * 
 * filename and funcname can be used a quick dirty depth 1 stack.
 *
 * The stp script need to match the t.val layout.  Right now, 
 * 	0 	family
 *	1 	filename
 *	2 	funcname
 *	3 	line number
 *	4-9 	5 args
 */

#if 0 
---------------------  BEGIN EXAMPLE STP ---------------------------------
#! /usr/bin/env stap

/* 
 * Example stap.  The stp must be run as root because it uses embeded C.
 *
 * sudo stap -g my.stp
 */

function pgtrace_decode_val:long(pgtrace_data:long, fieldnum:long)
%{
	struct pg_trace_data_t {
		long iv[9];
	};

	struct pg_trace_data_t *p = (struct pg_trace_data_t *) (long) THIS->pgtrace_data;
	if(p && THIS->fieldnum >= 0 && THIS->fieldnum < 9) 
		THIS->__retvalue = kread(&(p->iv[THIS->fieldnum]));
	else
		THIS->__retvalue = 0;

	CATCH_DEREF_FAULT();
%}

probe syscall.write {
	/* We have $fd, $count, and $buf.  Need to access $buf with user_string($buf) */
	if($fd == 0 && $count == 0)
	{
		printf("PGTrace family %d, file %s, func %s line %d: args: %d, %d, %d, %d, %d\n", 
				pgtrace_decode_val($buf, 0),
				user_string(pgtrace_decode_val($buf, 1)),
				user_string(pgtrace_decode_val($buf, 2)),
				pgtrace_decode_val($buf, 3),
				pgtrace_decode_val($buf, 4),
				pgtrace_decode_val($buf, 5),
				pgtrace_decode_val($buf, 6),
				pgtrace_decode_val($buf, 7),
				pgtrace_decode_val($buf, 8)
		      )
	}
}	
--------------------- END EXAMPLE STP -----------------------------------------
#endif

void LTRACE_PROBE_FIRE(long family, 
		const char *filename, const char *funcname, long line,
		long i1, long i2, long i3, long i4, long i5
		)
{
	if(gp_ltrace_flag)
	{
		struct pg_trace_data_t t;
		t.val[0] = family;
		t.val[1] = (long) filename;
		t.val[2] = (long) funcname;
		t.val[3] = line;
		t.val[4] = i1;
		t.val[5] = i2;
		t.val[6] = i3;
		t.val[7] = i4;
		t.val[8] = i5;

		write(0, (char *) &t, 0);
	}
}
#endif
