我第一份C++编码工作,公司里面每次发版本,都会把源代码,PDB文件,dump文件上传到服务器保存。
当时我因为找程序崩溃的时候不会加载符号文件(当时我都没听说过),被我们开发老大鄙视了,调薪也给我调的比别人少。
我就想知道,谁说的是对的,一个说没吊用,一个又因为调试程序的时候我不会加载,直接影响我的钱;
求大神解救,小白退散。
11 个解决方案
#1
没pdb怎么调试。看反汇编看内存raw data么。
#2
传智慧的那个辅导老师说有源代码就可以了,不要搞什么PDB
#3
有源码可以在编译一次啊!这样就有了 .pdb 文件了。
所以 pdb 是很重要的。
这样客户反馈的 Crash report 就可以调试了。
但是可以肯定的你的老师,误人子弟了。
所以 pdb 是很重要的。
这样客户反馈的 Crash report 就可以调试了。
但是可以肯定的你的老师,误人子弟了。
#4
pdb 很有用啊,传智播客那老师太坑了吧
#5
这简直就是降智。
#6
发布产品还用pdb文件?
#7
说的都对,也都不对。
你就问出门旅游,用不用自带牙刷?
老师说,不用带,因为带钱就可以了。还鄙视你。
结果你去的是一个无人区,条件很艰苦,买不到牙刷,你还没带。
#8
当时我问的是怎么加载一个PDB符号文件,我在Vs2013里面没找到那个配置项,教室没网,也百度不了。
然后那个老师就不耐烦的说“你不要搞这种华而不实的东西,没吊用”,然后 “哼”了一声走了,我操
#9
你那辅导老师不行。源代码重新编译一次已经与发布的程序不对应了
#10
个人意见:pdb文件是鸡肋。
我在自己有源码调试release版时,在怀疑有问题的地方临时加一句DebugBreak();
我在自己没源码调试或分析crash dump时,截取一小段最多32个字节的汇编指令码,在相关exe或dll或ocx中搜索,即可很快定位出错的位置。
根本用不着费劲加载、更新、维护庞大臃肿的pdb文件们!
我在自己有源码调试release版时,在怀疑有问题的地方临时加一句DebugBreak();
我在自己没源码调试或分析crash dump时,截取一小段最多32个字节的汇编指令码,在相关exe或dll或ocx中搜索,即可很快定位出错的位置。
根本用不着费劲加载、更新、维护庞大臃肿的pdb文件们!
#11
有时不将“调用函数名字+各参数值,进入函数后各参数值,中间变量值,退出函数前准备返回的值,返回函数到调用处后函数名字+各参数值+返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的,包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行! 写日志到文件参考下面:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define _vsnprintf vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
_vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
int i;
#ifdef WIN32
InitializeCriticalSection(&cs_log);
#else
pthread_mutex_init(&cs_log,NULL);
#endif
for (i=0;i<10000;i++) {
Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
}
#ifdef WIN32
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
//1-78行添加到你带main的.c或.cpp的那个文件的最前面
//81-85行添加到你的main函数开头
//89-93行添加到你的main函数结束前
//在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中
#1
没pdb怎么调试。看反汇编看内存raw data么。
#2
传智慧的那个辅导老师说有源代码就可以了,不要搞什么PDB
#3
有源码可以在编译一次啊!这样就有了 .pdb 文件了。
所以 pdb 是很重要的。
这样客户反馈的 Crash report 就可以调试了。
但是可以肯定的你的老师,误人子弟了。
所以 pdb 是很重要的。
这样客户反馈的 Crash report 就可以调试了。
但是可以肯定的你的老师,误人子弟了。
#4
pdb 很有用啊,传智播客那老师太坑了吧
#5
这简直就是降智。
#6
发布产品还用pdb文件?
#7
说的都对,也都不对。
你就问出门旅游,用不用自带牙刷?
老师说,不用带,因为带钱就可以了。还鄙视你。
结果你去的是一个无人区,条件很艰苦,买不到牙刷,你还没带。
#8
当时我问的是怎么加载一个PDB符号文件,我在Vs2013里面没找到那个配置项,教室没网,也百度不了。
然后那个老师就不耐烦的说“你不要搞这种华而不实的东西,没吊用”,然后 “哼”了一声走了,我操
#9
你那辅导老师不行。源代码重新编译一次已经与发布的程序不对应了
#10
个人意见:pdb文件是鸡肋。
我在自己有源码调试release版时,在怀疑有问题的地方临时加一句DebugBreak();
我在自己没源码调试或分析crash dump时,截取一小段最多32个字节的汇编指令码,在相关exe或dll或ocx中搜索,即可很快定位出错的位置。
根本用不着费劲加载、更新、维护庞大臃肿的pdb文件们!
我在自己有源码调试release版时,在怀疑有问题的地方临时加一句DebugBreak();
我在自己没源码调试或分析crash dump时,截取一小段最多32个字节的汇编指令码,在相关exe或dll或ocx中搜索,即可很快定位出错的位置。
根本用不着费劲加载、更新、维护庞大臃肿的pdb文件们!
#11
有时不将“调用函数名字+各参数值,进入函数后各参数值,中间变量值,退出函数前准备返回的值,返回函数到调用处后函数名字+各参数值+返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的,包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行! 写日志到文件参考下面:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define _vsnprintf vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
_vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
int i;
#ifdef WIN32
InitializeCriticalSection(&cs_log);
#else
pthread_mutex_init(&cs_log,NULL);
#endif
for (i=0;i<10000;i++) {
Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
}
#ifdef WIN32
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
//1-78行添加到你带main的.c或.cpp的那个文件的最前面
//81-85行添加到你的main函数开头
//89-93行添加到你的main函数结束前
//在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中