user-0 提问: 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决

回复:
user: user-1
content: 一群措，gdb，打个断点 然后watch下你的全局变量，当你的全局变量被改时就能抓到凶手了

user: user-2
content: 引用 11 楼 a826632030 的回复:[quote=引用 5 楼 nadleeh123 的回复:] [quote=引用 楼主 a826632030 的回复:] 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现[/quote]  =========================================================== 昨天老大让通宵加班搞这个问题，纠结死了[/quote]  这种错误一般是指针没判断返回值，数组没判断下标，还有异常的同步数据IO，努力吧少年，过渡依赖工具是不行的，还得靠自己。以前调过最难的bug是写测试程序胀满cpu，能跑上1天只死个1-2次，还附带轻微的内存泄露，调了我半个多月

user: user-2
content: 引用 6 楼 zhao4zhong1 的回复:[quote=引用 5 楼 nadleeh123 的回复:] [quote=引用 楼主 a826632030 的回复:] 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现[/quote] 那是因为你不会用数据断点。[/quote]  赵老师 linux 1台机器怎么设置内核debug断点啊 还有内核被飞踩了 如何确定是谁干的坏事啊  如果跟踪到了汇编部分的代码怎么玩啊

user: user-3
content: 不会下数据断点，参考下面：  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成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中

user: user-4
content: 如果可以打数据断点，当然最好。如果没有办法，以下思路供借鉴。 查堆栈，看被覆盖内存的地址，以及内容有没有什么规律。 1. 可以看出是全局变量的值被篡改，但是能否确定被篡改的内存的开始地址就是这个全局变量？ 2. 全局变量位于程序的数据区，可以找一找。看一下这个变量周围有没有什么数组之类的。 3. 看堆栈中，每次被篡改的值是否都一致。有没有可能是某种数据结构。

user: user-5
content: 引用 11 楼 a826632030 的回复:[quote=引用 5 楼 nadleeh123 的回复:] [quote=引用 楼主 a826632030 的回复:] 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现[/quote]  =========================================================== 昨天老大让通宵加班搞这个问题，纠结死了[/quote] 通宵加班，身心疲惫，效率更低

user: user-6
content: 引用 6 楼 zhao4zhong1 的回复:[quote=引用 5 楼 nadleeh123 的回复:] [quote=引用 楼主 a826632030 的回复:] 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现[/quote] 那是因为你不会用数据断点。[/quote]  老师威武，就是数据断点。

user: user-0
content: 引用 5 楼 nadleeh123 的回复:[quote=引用 楼主 a826632030 的回复:] 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现[/quote]  =========================================================== 昨天老大让通宵加班搞这个问题，纠结死了

user: user-0
content: 引用 4 楼 zhao4zhong1 的回复:正解在此！ #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }  =================================================== 的确不是必先的问题，数据断点貌似只可以在调试的时候执行吧？我还是第一次听说数据断点，涨知识了，对我很有帮助以后可能会用到

user: user-0
content: 引用 2 楼 xiaohuh421 的回复:是全局变量的访问越界, 还是其它程序越界访问 , 导致全局变量被修改了? 如果全局变量自己访问越界, 则下每个用到的地方下断排查. 否则就只有下 内存断点.  可知道是哪里改变了这个内存. ================================================= 这个不是很清楚，全局变量是一个数据结构

user: user-7
content: 引用 2 楼 xiaohuh421 的回复:是全局变量的访问越界, 还是其它程序越界访问 , 导致全局变量被修改了? 如果全局变量自己访问越界, 则下每个用到的地方下断排查. 否则就只有下 内存断点.  可知道是哪里改变了这个内存.+1

user: user-8
content: 是全局变量的访问越界, 还是其它程序越界访问 , 导致全局变量被修改了? 如果全局变量自己访问越界, 则下每个用到的地方下断排查. 否则就只有下 内存断点.  可知道是哪里改变了这个内存.

user: user-0
content: 是全局变量被踩了，导致进程退出

user: user-9
content: core dump

user: user-3
content: 引用 5 楼 nadleeh123 的回复:[quote=引用 楼主 a826632030 的回复:] 关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现[/quote] 那是因为你不会用数据断点。

user: user-2
content: 引用 楼主 a826632030 的回复:关于踩内存，有没有比较好的定位问题的方法，最近工作中遇到了两个，还没有解决。 苦于没有比较好的解决思路和办法  这种越界一般就是写代码的时候没做好错误处理，慢慢找吧少年，注释符能帮点忙，设断点神马的不靠谱，除非每次必现

user: user-3
content: 正解在此！ #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }