⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.c

📁 DSR-UU is a DSR implementation that runs in Linux and in the ns-2 network simulator. DSR-UU imple
💻 C
字号:
/* Copyright (C) Uppsala University * * This file is distributed under the terms of the GNU general Public * License (GPL), see the file LICENSE * * Author: Erik Nordström, <erikn@it.uu.se> */#include <linux/poll.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/spinlock.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/proc_fs.h>#include <linux/module.h>#include <linux/version.h>#include <asm/uaccess.h>#include <asm/io.h>#include "debug.h"#include "dsr.h"#include "timer.h"atomic_t num_pkts = ATOMIC_INIT(0);/* Most of this is shamelessly stolen from the linux kernel log routines */#define DBG_LOG_BUF_LEN	(16384)//#define DBG_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)static spinlock_t dbg_logbuf_lock = SPIN_LOCK_UNLOCKED;static char __dbg_log_buf[DBG_LOG_BUF_LEN];static char *dbg_log_buf = __dbg_log_buf;static int dbg_log_buf_len = DBG_LOG_BUF_LEN;#define DBG_LOG_BUF_MASK	(dbg_log_buf_len-1)#define DBG_LOG_BUF(idx) (dbg_log_buf[(idx) & DBG_LOG_BUF_MASK])static unsigned long dbg_log_start;	/* Index into dbg_log_buf: next char to be read by sysdbg_log() */static unsigned long dbg_log_end;	/* Index into dbg_log_buf: most-recently-written-char + 1 */static unsigned long logged_chars;	/* Number of chars produced since last read+clear operation */DECLARE_WAIT_QUEUE_HEAD(dbg_log_wait);int do_dbglog(int type, char *buf, int len){	unsigned long i, j, limit, count;	int do_clear = 0;	char c;	int error = 0;	/* printk(KERN_DEBUG "do_dbglog\n"); */	switch (type) {	case 0:		/* Close log */		break;	case 1:		/* Open log */		break;	case 2:		/* Read from log */		error = -EINVAL;		if (!buf || len < 0)			goto out;		error = 0;		if (!len)			goto out;#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)		error = verify_area(VERIFY_WRITE, buf, len);#else		error = access_ok(VERIFY_WRITE, buf, len) ? 0 : 1;#endif		if (error)			goto out;		error =		    wait_event_interruptible(dbg_log_wait,					     (dbg_log_start - dbg_log_end));		if (error)			goto out;		i = 0;		/* printk(KERN_DEBUG "read\n"); */		spin_lock_irq(&dbg_logbuf_lock);		while (!error && (dbg_log_start != dbg_log_end) && i < len) {			c = DBG_LOG_BUF(dbg_log_start);			dbg_log_start++;			spin_unlock_irq(&dbg_logbuf_lock);			error = __put_user(c, buf);			buf++;			i++;			cond_resched();			spin_lock_irq(&dbg_logbuf_lock);		}		spin_unlock_irq(&dbg_logbuf_lock);		if (!error)			error = i;		break;	case 4:		/* Read/clear last kernel messages */		do_clear = 1;		/* FALL THRU */	case 3:		/* Read last kernel messages */		error = -EINVAL;		if (!buf || len < 0)			goto out;		error = 0;		if (!len)			goto out;#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)		error = verify_area(VERIFY_WRITE, buf, len);#else		error = access_ok(VERIFY_WRITE, buf, len) ? 0 : 1;#endif		if (error)			goto out;		count = len;		if (count > dbg_log_buf_len)			count = dbg_log_buf_len;		spin_lock_irq(&dbg_logbuf_lock);		if (count > logged_chars)			count = logged_chars;		if (do_clear)			logged_chars = 0;		limit = dbg_log_end;		/*		 * __put_user() could sleep, and while we sleep		 * printk() could overwrite the messages 		 * we try to copy to user space. Therefore		 * the messages are copied in reverse. <manfreds>		 */		for (i = 0; i < count && !error; i++) {			j = limit - 1 - i;			if (j + dbg_log_buf_len < dbg_log_end)				break;			c = DBG_LOG_BUF(j);			spin_unlock_irq(&dbg_logbuf_lock);			error = __put_user(c, &buf[count - 1 - i]);			cond_resched();			spin_lock_irq(&dbg_logbuf_lock);		}		spin_unlock_irq(&dbg_logbuf_lock);		if (error)			break;		error = i;		if (i != count) {			int offset = count - error;			/* buffer overflow during copy, correct user buffer. */			for (i = 0; i < error; i++) {				if (__get_user(c, &buf[i + offset]) ||				    __put_user(c, &buf[i])) {					error = -EFAULT;					break;				}				cond_resched();			}		}		break;	case 5:		/* Clear ring buffer */		logged_chars = 0;		break;	case 6:		/* Number of chars in the log buffer */		error = dbg_log_end - dbg_log_start;		break;	case 7:		/* Size of the log buffer */		error = dbg_log_buf_len;		break;	default:		error = -EINVAL;		break;	}      out:	return error;}static void dsr_emit_log_char(char c){	DBG_LOG_BUF(dbg_log_end) = c;	dbg_log_end++;	if (dbg_log_end - dbg_log_start > dbg_log_buf_len)		dbg_log_start = dbg_log_end - dbg_log_buf_len;	if (logged_chars < dbg_log_buf_len)		logged_chars++;}int dsr_vprintk(const char *func, const char *fmt, va_list args){	unsigned long flags;	int printed_len, prefix_len;	char *p;	static char printk_buf[1024];	struct timeval now;	/* This stops the holder of console_sem just where we want him */	spin_lock_irqsave(&dbg_logbuf_lock, flags);	gettime(&now);	prefix_len = sprintf(printk_buf, "%ld.%03ld: %s: ",			     now.tv_sec, now.tv_usec / 1000, func);	/* Emit the output into the temporary buffer */	printed_len = vsnprintf(printk_buf + prefix_len,				sizeof(printk_buf) - prefix_len, fmt, args);	for (p = printk_buf; *p; p++)		dsr_emit_log_char(*p);	spin_unlock_irqrestore(&dbg_logbuf_lock, flags);	return printed_len;}int trace(const char *func, const char *fmt, ...){	va_list args;	int r;	va_start(args, fmt);	r = dsr_vprintk(func, fmt, args);	va_end(args);	return r;}static int dbg_log_open(struct inode *inode, struct file *file){	return do_dbglog(1, NULL, 0);}static int dbg_log_release(struct inode *inode, struct file *file){	(void)do_dbglog(0, NULL, 0);	return 0;}static ssize_tdbg_log_read(struct file *file, char *buf, size_t count, loff_t * ppos){	/* printk(KERN_DEBUG "dbg_log_read\n"); */	if ((file->f_flags & O_NONBLOCK) && !do_dbglog(6, NULL, 0))		return -EAGAIN;	return do_dbglog(2, buf, count);}static unsigned int dbg_log_poll(struct file *file, poll_table * wait){	poll_wait(file, &dbg_log_wait, wait);	if (do_dbglog(6, NULL, 0))		return POLLIN | POLLRDNORM;	return 0;}struct file_operations proc_dbg_operations = {	.read = dbg_log_read,	.poll = dbg_log_poll,	.open = dbg_log_open,	.release = dbg_log_release,};int __init dbg_init(void){	struct proc_dir_entry *entry;	entry =	    create_proc_entry("dsr_dbg", S_IRUSR | S_IRGRP | S_IROTH, proc_net);	if (entry)		entry->proc_fops = &proc_dbg_operations;	return 0;}void __exit dbg_cleanup(void){	proc_net_remove("dsr_dbg");}/* EXPORT_SYMBOL(trace); *//* EXPORT_SYMBOL(dsr_vprintk); */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -