fprintf()中的 stderr说明
先看一个小例子:
---------------------------------------------
#include <stdio.h>
void main()
{
fprintf(stderr,"can't open it!");
fprintf(stdout,"can't open it !");
printf("can't open it!");
}
---------------------------------------------
上面程序编译成fprint文件,运行显示如下:
Can't open it! Can't open it! Can't open it!
若将输入重定向到一个temp.txt文件中,运行:./fprint >temp.txt 结果如下:
Can't open it!
查看temp.txt文件内容为:
Can't open it!Can't open it!
说明:
stdout -- 标准输出设备 (printf("..")) 同 stdout。
stderr -- 标准错误输出设备 两者默认向屏幕输出。
但如果用转向标准输出到磁盘文件,则可看出两者区别。stdout输出到磁盘文件,stderr在屏幕。
strerr是作为程序运行过程中的错误显示出来的,若想将它重写向到某文件中,需要运行如下命令:
./fprint 2>temp.txt
这样运行结果就为:
Can't open it!Can't open it!
查看temp.txt文件的内容是:
<SPANstyle="COLOR:#003333;FONT-SIZE:14px">#defineKERN_EMERG"<0>"/*systemisunusable*/
#defineKERN_ALERT"<1>"/*actionmustbetakenimmediately*/
#defineKERN_CRIT"<2>"/*criticalconditions*/
#deinfeKERN_ERR"<3>"/*errorconditions*/
#deinfeKERN_WARNING"<4>"/*warningconditions*/
#deinfeKERN_NOTICE"<5>"/*normalbutsignificantcondition*/
#deinfeKERN_INFO"<6>"/*informational*/
#deinfeKERN_DEBUG"<7>"/*debug-levelmessages*/</SPAN>
2、android中log输出
Android系统在用户空间中提供了轻量级的logger日志系统,它是在内核中实现的一种设备驱动,与用户空间的logcat工具配合使用能够方便地跟踪调试程序。
Android系统中的C/C++日志接口是通过宏来使用的。在system/core/include/android/log.h定义了日志的级别:
/*
*Androidlogpriorityvalues,inascendingpriorityorder.
*/
typedefenumandroid_LogPriority{
ANDROID_LOG_UNKNOWN=0,
ANDROID_LOG_DEFAULT,/*onlyforSetMinPriority()*/
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT,/*onlyforSetMinPriority();mustbelast*/
}android_LogPriority;
为了使用方便,在system/core/include/cutils/log.h定义了相对应的宏:
#defineLOGV(...)((void)LOG(LOG_VERBOSE,LOG_TAG,__VA_ARGS__))
#defineLOGD(...)((void)LOG(LOG_DEBUG,LOG_TAG,__VA_ARGS__))
#defineLOGI(...)((void)LOG(LOG_INFO,LOG_TAG,__VA_ARGS__))
#defineLOGW(...)((void)LOG(LOG_WARN,LOG_TAG,__VA_ARGS__))
#defineLOGE(...)((void)LOG(LOG_ERROR,LOG_TAG,__VA_ARGS__))
因为如果需要使用log输出,包含其头文件:#include<cutils/log.h>并link其动态库:liblog.so即可
#defineLOG_TAG"XX_LOG_TAG"//这里可以定义其输出的TAG
#include<cutils/log.h>
JAVA层打印:
importandroid.util.Log;
privatestaticfinalStringTAG="XX_LOG_TAG";
Log.e(TAG,"ThisistheerrorlogprintedbyLog.iinandroiduserspace.");
3、盒子上如何获取log
a、进入shell获取log
adbkill-server
adbconnectdest-ip
adbshell【登录shell】
mount-oremount/system/system【改变权限】
logcat>>1.log
命令行输入CTRL+C回到cmd命令行,adbpullpath/1.log
b、直接在cmd命令行获取log
adbconnect连上后;
adbshell
adblogcat>>path/1.log
操作完毕后
命令行输入CTRL+C回到cmd命令行,adbpullpath/1.log
c、在terminal终端直接输出log
回车切到shell
logcat[此时即可看到打印]
5、常用技巧
1、logcat中会打印【输出级别+LOG_TAG名字+进程字+打印的信息】可以充分利用这些信息分析问题
I/SystemServer(939):ActivityManager
I/ActivityManager(939):Memoryclass:96
E/AndroidRuntime(939):ErrorreportingWTF
第一列由Log.i(e/w..决定)或者LOGI/LOGE/LOGW...
第二列由LOG_TAG/TAG(JAVA)中决定,可以对于同一组模块前相同的前缀[xxx]funtion这种命名
第三列是系统进程号getpid()这值,打印线程值pthread_slef()
最后的就是自行增加的打印信息
2、调效效率或者执行时间
1、建议重点的打印增加前缀,方便查找。以[######]
2、直接利用logcat输出时间,调试执行速度,分析效率
logcat-vtime【Displaythedate,invocationtime,priority/tag,andPIDoftheoriginatingprocess.】
先看一个小例子:
---------------------------------------------
#include <stdio.h>
void main()
{
fprintf(stderr,"can't open it!");
fprintf(stdout,"can't open it !");
printf("can't open it!");
}
---------------------------------------------
上面程序编译成fprint文件,运行显示如下:
Can't open it! Can't open it! Can't open it!
若将输入重定向到一个temp.txt文件中,运行:./fprint >temp.txt 结果如下:
Can't open it!
查看temp.txt文件内容为:
Can't open it!Can't open it!
说明:
stdout -- 标准输出设备 (printf("..")) 同 stdout。
stderr -- 标准错误输出设备 两者默认向屏幕输出。
但如果用转向标准输出到磁盘文件,则可看出两者区别。stdout输出到磁盘文件,stderr在屏幕。
strerr是作为程序运行过程中的错误显示出来的,若想将它重写向到某文件中,需要运行如下命令:
./fprint 2>temp.txt
这样运行结果就为:
Can't open it!Can't open it!
查看temp.txt文件的内容是:
Can't open it!
- #include <stdio.h>
- #define lU_DEBUG_PREFIX "##########"
- #define LU_DEBUG_CMD 0x01
- #define LU_DEBUG_DATA 0x02
- #define LU_DEBUG_ERROR 0x04
- #define LU_PRINTF_cmd(msg...) do{if(lu_debugs & LU_DEBUG_CMD)printf(lU_DEBUG_PREFIX msg);}while(0)
- #define LU_PRINTF_data(msg...) do{if(lu_debugs & LU_DEBUG_DATA)printf(lU_DEBUG_PREFIX msg);}while(0)
- #define LU_PRINTF_error(msg...) do{if(lu_debugs & LU_DEBUG_ERROR)printf(lU_DEBUG_PREFIX msg);}while(0)
- #define lu_printf(level, msg...) LU_PRINTF_##level(msg)
- #define lu_printf2(...) printf(__VA_ARGS__)
- #define lu_printf3(...) lu_printf(__VA_ARGS__)
- static int lu_printf4_format(int prio, const char *fmt, ...);
- #define lu_printf4(prio, fmt...) lu_printf4_format(prio, fmt)
- int lu_debugs;
- int main(int argc, char *argv[])
- {
- lu_debugs |= LU_DEBUG_CMD | LU_DEBUG_DATA | LU_DEBUG_ERROR;
- printf("lu_debugs = %p\n", lu_debugs);
- lu_printf(cmd,"this is cmd\n");
- lu_printf(data,"this is data\n");
- lu_printf(error,"this is error\n");
- lu_debugs &= ~(LU_DEBUG_CMD | LU_DEBUG_DATA);
- printf("lu_debugs = %p\n", lu_debugs);
- lu_printf(cmd,"this is cmd\n");
- lu_printf(data,"this is data\n");
- lu_printf(error,"this is error\n");
- lu_printf2("aa%d,%s,%dbbbbb\n", 20, "eeeeeee", 100);
- lu_debugs |= LU_DEBUG_CMD | LU_DEBUG_DATA | LU_DEBUG_ERROR;
- printf("lu_debugs = %p\n", lu_debugs);
- lu_printf3(cmd,"this is cmd \n");
- lu_printf3(data,"this is data\n");
- lu_printf3(error,"this is error\n");
- lu_printf4(0,"luther %s ,%d ,%d\n", "gliethttp", 1, 2);
- return 0;
- }
- #include <stdarg.h>
- static int lu_printf4_format(int prio, const char *fmt, ...)
- {
- #define LOG_BUF_SIZE (4096)
- va_list ap;
- char buf[LOG_BUF_SIZE];
- va_start(ap, fmt);
- vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
- va_end(ap);
- printf("<%d>: %s", prio, buf);
- printf("------------------------\n");
- printf(buf);
- }
- #define ENTER() LOGD("enter into %s", __FUNCTION__)
- #define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
- #define LOG(priority, tag, ...) \
- LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
- #define LOG_PRI(priority, tag, ...) \
- android_printLog(priority, tag, __VA_ARGS__)
- #define android_printLog(prio, tag, fmt...) \
- __android_log_print(prio, tag, fmt)
http://www.linuxsir.org/bbs/showthread.php?t=302451
这里有篇不错的文章,[经验分享]程序日志中自动记录所在函数名、文件名、行号
比上面的要好多了:
- #include <stdio.h>
- #define LOG_DEBUG "DEBUG"
- #define LOG_TRACE "TRACE"
- #define LOG_ERROR "ERROR"
- #define LOG_INFO "INFOR"
- #define LOG_CRIT "CRTCL"
- #define LOG(level, format, ...) \
- do { \
- fprintf(stderr, "[%s|%s@%s,%d] " format "\n", \
- level, __func__, __FILE__, __LINE__, ##__VA_ARGS__ ); \
- } while (0)
- int main()
- {
- LOG(LOG_DEBUG, "a=%d", 10);
- return 0;
- }
或者
- #define DBG(format, args...) fprintf(stderr, "[%s|%s@%s,%d] " format "\n", APP_NAME, __FUNCTION__, __FILE__, __LINE__, ## args );
1、linux内核的log输出
在标准的linux内核开发过程中,使用printk,这是一个与printf输出打印齐名的函数,同样提供格式化输出功能,只是其有
打印级别且将信息保存到/proc/kmsg日志中,使用cat命令查看其信息[cat/proc/kmsg]
复制代码 代码如下:
<SPANstyle="COLOR:#003333;FONT-SIZE:14px">#defineKERN_EMERG"<0>"/*systemisunusable*/
#defineKERN_ALERT"<1>"/*actionmustbetakenimmediately*/
#defineKERN_CRIT"<2>"/*criticalconditions*/
#deinfeKERN_ERR"<3>"/*errorconditions*/
#deinfeKERN_WARNING"<4>"/*warningconditions*/
#deinfeKERN_NOTICE"<5>"/*normalbutsignificantcondition*/
#deinfeKERN_INFO"<6>"/*informational*/
#deinfeKERN_DEBUG"<7>"/*debug-levelmessages*/</SPAN>
2、android中log输出
Android系统在用户空间中提供了轻量级的logger日志系统,它是在内核中实现的一种设备驱动,与用户空间的logcat工具配合使用能够方便地跟踪调试程序。
Android系统中的C/C++日志接口是通过宏来使用的。在system/core/include/android/log.h定义了日志的级别:
/*
*Androidlogpriorityvalues,inascendingpriorityorder.
*/
typedefenumandroid_LogPriority{
ANDROID_LOG_UNKNOWN=0,
ANDROID_LOG_DEFAULT,/*onlyforSetMinPriority()*/
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT,/*onlyforSetMinPriority();mustbelast*/
}android_LogPriority;
为了使用方便,在system/core/include/cutils/log.h定义了相对应的宏:
#defineLOGV(...)((void)LOG(LOG_VERBOSE,LOG_TAG,__VA_ARGS__))
#defineLOGD(...)((void)LOG(LOG_DEBUG,LOG_TAG,__VA_ARGS__))
#defineLOGI(...)((void)LOG(LOG_INFO,LOG_TAG,__VA_ARGS__))
#defineLOGW(...)((void)LOG(LOG_WARN,LOG_TAG,__VA_ARGS__))
#defineLOGE(...)((void)LOG(LOG_ERROR,LOG_TAG,__VA_ARGS__))
因为如果需要使用log输出,包含其头文件:#include<cutils/log.h>并link其动态库:liblog.so即可
#defineLOG_TAG"XX_LOG_TAG"//这里可以定义其输出的TAG
#include<cutils/log.h>
JAVA层打印:
importandroid.util.Log;
privatestaticfinalStringTAG="XX_LOG_TAG";
Log.e(TAG,"ThisistheerrorlogprintedbyLog.iinandroiduserspace.");
3、盒子上如何获取log
a、进入shell获取log
adbkill-server
adbconnectdest-ip
adbshell【登录shell】
mount-oremount/system/system【改变权限】
logcat>>1.log
命令行输入CTRL+C回到cmd命令行,adbpullpath/1.log
b、直接在cmd命令行获取log
adbconnect连上后;
adbshell
adblogcat>>path/1.log
操作完毕后
命令行输入CTRL+C回到cmd命令行,adbpullpath/1.log
c、在terminal终端直接输出log
回车切到shell
logcat[此时即可看到打印]
5、常用技巧
1、logcat中会打印【输出级别+LOG_TAG名字+进程字+打印的信息】可以充分利用这些信息分析问题
I/SystemServer(939):ActivityManager
I/ActivityManager(939):Memoryclass:96
E/AndroidRuntime(939):ErrorreportingWTF
第一列由Log.i(e/w..决定)或者LOGI/LOGE/LOGW...
第二列由LOG_TAG/TAG(JAVA)中决定,可以对于同一组模块前相同的前缀[xxx]funtion这种命名
第三列是系统进程号getpid()这值,打印线程值pthread_slef()
最后的就是自行增加的打印信息
2、调效效率或者执行时间
1、建议重点的打印增加前缀,方便查找。以[######]
2、直接利用logcat输出时间,调试执行速度,分析效率
logcat-vtime【Displaythedate,invocationtime,priority/tag,andPIDoftheoriginatingprocess.】