#
# Command file for the GNU Debugger, for kernel debugging.
#
# This file can either be put in your home directory as ~/.gdbinit,
# or selected at run time as:
#
#   	'gdb -k -q -x /usr/share/misc/gdbinit ...'
#
set print union
set history expansion on

define pcomm
	printf "%10s\n",$arg0->td_comm
end

define lsvfs
	set $vfc = (struct vfsconf *)vfsconf_list.stqh_first
	printf "\nFilesystem      Refs    Flags\n"
	while ($vfc != 0)
		printf "%-10s %6d       0x%08x\n", $vfc->vfc_name, \
			$vfc->vfc_refcount, $vfc->vfc_flags
		set $vfc = $vfc->vfc_next.stqe_next
	end
end

define lsmount
	set $mnt = (mountlist->tqh_first)
	while ($mnt != 0)
		print *$mnt
		set $mnt = $mnt->mnt_list->tqe_next
	end
end

define lsvfsops
	set $vfc = (struct vfsconf *)vfsconf_list.stqh_first
	while ($vfc != 0)
		printf "Filesystem: %s, Refs: %d, Flags: 0x%08x\n", \
			$vfc->vfc_name, $vfc->vfc_refcount, $vfc->vfc_flags
		printf "VFS ops: \n"
		set print pretty
		print *$vfc->vfc_vfsops
		set print pretty off
		set $vfc = $vfc->vfc_next.stqe_next
	end
end


define kldstat
	set $kld = linker_files.tqh_first
	printf "\nId Refs Address    Size     Name\n"
	while ($kld != 0)
		printf "%2d %4d 0x%08x %-8x %s\n", \
		$kld->id, $kld->refs, $kld->address, $kld->size, $kld->filename
		set $kld = $kld->link.tqe_next
	end
end

define psx
    set $cpu = 0
    printf "\ncpu  pid    thread    flags comm               wchan    wmesg\n"
    while ($cpu < ncpus)
	set $gd = &((struct privatespace *)&CPU_prvspace)[$cpu].mdglobaldata
	set $td = $gd->mi.gd_tdallq.tqh_first
	while ( $td != 0 )
	    if ( $td->td_proc != 0 )
		set $pid = $td->td_proc->p_pid
	    else
		set $pid = -1
	    end
	    if ( $td->td_wmesg != 0 )
		printf "%3d %5d %08x %08x %-18s %08x %s\n",	\
		    $cpu, $pid, $td, $td->td_flags, $td->td_comm, $td->td_wchan, \
		    $td->td_wmesg
	    else
		printf "%3d %5d %08x %08x %-18s %08x\n",	\
		    $cpu, $pid, $td, $td->td_flags, $td->td_comm, $td->td_wchan
	    end
	    set $td = $td->td_allq.tqe_next
	end
	set $cpu = $cpu + 1
    end
end


define running_threads
    set $icpu = 0
	printf "\ncpu    curthread    wchan\n"
	while ($icpu < ncpus)
	    set $ipvspace = (struct privatespace *)&CPU_prvspace
		set $gd = $ipvspace[$icpu].mdglobaldata.mi
		set $td = $gd.gd_curthread
	    printf "%d    %10s    %08x\n", \
			$gd.gd_cpuid, $td->td_comm, $td->td_wchan
	    set $icpu = $icpu + 1
	end
end

define psax
    set $pos = 0
    while $pos < allproc_hsize
	set $proc = allprocs[$pos++]->lh_first
	while $proc != 0
		printf "%p%6d%10s\n",$proc,$proc->p_pid,$proc->p_comm
		set $proc = $proc->p_list.le_next
	end
    end
end

define _infotok
	set $token = ($arg0)
	set $tokref = $token->t_ref
	if ($tokref != 0)
		printf "%-15s %10d 0x%08x\n", $token->t_desc, \
			$token->t_collisions, $tokref->tr_owner
	else
		printf "%-15s %10d not held\n", $token->t_desc, \
			$token->t_collisions
	end
end

define infotok
	printf "\nToken           collisions owner\n"
	_infotok ($arg0)
end

define lstok
	set $tok = 0
	set $obj = 0
	printf "\nToken           collisions owner\n"
	_infotok &pmap_token
	_infotok &dev_token
	_infotok &vm_token
	_infotok &vmspace_token
	_infotok &kvm_token
	while $tok < allproc_hsize
		if (proc_tokens[$tok].t_collisions > 0)
			_infotok &proc_tokens[$tok]
		end
		set $tok = $tok + 1
	end
	_infotok &tty_token
	_infotok &vnode_token
	while $obj < 64
		if (vmobj_tokens[$obj].t_collisions > 0)
			_infotok &vmobj_tokens[$obj]
		end
		set $obj = $obj + 1
	end
end

define lstdtok
	set $mytd=($arg0)
	printf "\nTokens for td  %p (%s)\n", $mytd, $mytd->td_comm
	printf "\nToken           collisions owner\n"
	set $pos = 0
	while (td->td_toks_array[$pos]->tr_tok) != 0
		_infotok &td->td_toks_array[$pos++]->tr_tok
	end
end

define dmesg
	set $bufp = msgbufp->msg_ptr
	set $size = msgbufp->msg_size
	set $rseq = msgbufp->msg_bufr % $size
	set $wseq = msgbufp->msg_bufx % $size
	if ( $bufp != 0 && $size != 0 && $rseq != $wseq )
		while ( $rseq < $wseq )
			set $c = $bufp + $rseq
			printf "%c", *$c
			set $rseq = $rseq + 1
			if ( $rseq == msgbufp->msg_size )
				set $rseq = 0
			end
		end
		if ( *$c == '\n' )
			printf "\n"
		end
		printf "\n"
	end
end

# Documentation, usable within GDB using the 'help' command.
document lsvfs
Output list of loaded file systems, refcount, similar to the
lsvfs(1) utility.
end

document lsmount
Iterate the current list of mount structures loaded from the
memory core, there should be one per loaded VFS.
end

document lsvfsops
Display the VFS operations vector for each file system found in
the memory core, preceded by a summarised header.
end

document kldstat
Output list of loaded kernel modules in kldstat(1) style.
end

document pcomm
Print command name of the given thread pointer (first argument).
end

document psx
Output a list of processes with wait-channel (wchan) information.
end

document running_threads
List the threads which are currently running and their CPU number.
end

document psax
Output a list of processes.
end

document lstok
Display all known global tokens and some information about them.
end

document lstdtok
Display all tokens related to the specified thread.
end

document infotok
Takes one argument, a struct lwkt_token * (pointer) and prints some
information about that token.
end

document dmesg
Shows the unread portion of the kernel message buffer.
end