免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: hello|world
打印 上一主题 下一主题

[C] 请教: 怎样判断一个变量是只读的(const)? [复制链接]

论坛徽章:
0
31 [报告]
发表于 2011-02-16 09:13 |只看该作者
回复 23# hello|world


    错误不是用来屏蔽的。 如果他误传了个常量给你,你不报错,仅仅是什么都不做,以后出现问题他一定会骂你的。

论坛徽章:
0
32 [报告]
发表于 2011-02-16 10:05 |只看该作者
回复  hello|world


    错误不是用来屏蔽的。 如果他误传了个常量给你,你不报错,仅仅是什么都不做, ...
donotblock 发表于 2011-02-16 09:13



    接口应该明确写出输入输出参数的类型和范围,如果你都告诉他要使用char *了,他还非要用const char *,到时候出了问题,他敢骂你?

论坛徽章:
0
33 [报告]
发表于 2011-02-16 10:13 |只看该作者
接口应该明确写出输入输出参数的类型和范围,如果你都告诉他要使用char *了,他还非要用const ch ...
雨夜流星 发表于 2011-02-16 10:05



    我是说该让他出错或崩溃而不让他出错会被骂。。。你完全理解反了我的意思

论坛徽章:
0
34 [报告]
发表于 2011-02-17 10:17 |只看该作者
可能楼主需要的是这个
IsBadWritePtr

论坛徽章:
0
35 [报告]
发表于 2011-02-17 10:52 |只看该作者
用objdump看这个变量符号的存在位置,如果在.rodata则是只读的。
davelv 发表于 2011-02-15 10:38



    看生成可执行文件中这个变量在什么区 如果是RO区 说明是只读的 推荐看一下ELF文件格式

论坛徽章:
0
36 [报告]
发表于 2011-02-17 10:56 |只看该作者
实在想知道的话 就比较地址范围吧

在链接文件中存有RO区地址的范围, 在程序中比较即可


if(&var > 0x08004000 && &var < 0x08006000)

论坛徽章:
1
技术图书徽章
日期:2014-03-06 15:32:30
37 [报告]
发表于 2011-02-17 11:30 |只看该作者
需求是合理的吗?
设计是合理的吗?
是哪里出的错误?
哪里出的错误就在哪里解决。

论坛徽章:
0
38 [报告]
发表于 2011-02-17 15:33 |只看该作者
本帖最后由 hello|world 于 2011-02-17 15:45 编辑

回复 34# rong_bo

必须感谢下这个回复,不管以后是否能用上,确实也是一种办法~
  1. #include   <setjmp.h>
  2. #include   <signal.h>
  3. #include   <stdlib.h>
  4. #include   <stdio.h>

  5. /*
  6.   ***************************
  7.   *   Global   Variables   
  8.   ***************************
  9. */
  10. static   volatile   sig_atomic_t   segv_flag;
  11. static   jmp_buf   jmp_env;

  12. /*
  13.   ********************************************
  14.   *   Pre:   none   
  15.   *   Post:   restore   the   original   process   state   
  16.   *       and   return   1   to   setjmp
  17.   ********************************************
  18. */
  19. static   void   segv_handler(   int   dummy   )
  20. {
  21. segv_flag   =   1;
  22. longjmp(   jmp_env   ,   1);
  23. }

  24. /*
  25.   ********************************************
  26.   *   Pre:   A   pointer   and   it 's   length
  27.   *   Post:   Return   true   is   the   pointer   is   bad
  28.   *       or   false   if   otherwise
  29.   ********************************************
  30. */

  31. int   IsReadBadPtr(void   *   ptr_buffer,   unsigned   long   buffer_size)
  32. {
  33. struct   sigaction   oldaction,   newaction;
  34. volatile   char   dummy;
  35. char   *ptr   =   (char   *)ptr_buffer;

  36. if   (   !buffer_size   )
  37. return   0;

  38.             /*   storing   the   old   signal   environment   and   trapping   SIGSEGV   */
  39. newaction.sa_handler   =   segv_handler;
  40. newaction.sa_flags   =   0;
  41. sigemptyset(   &newaction.sa_mask);

  42. sigaction(   SIGSEGV,   &newaction,   &oldaction);

  43. segv_flag   =   0;

  44.             /*   Storing   the   process   state   so   if   any   failure   happens   
  45.                   we   can   restore   it   to   the   original   state   */
  46. if   (   setjmp(jmp_env)   ==   0   )
  47. {
  48. /*   testing   the   pointer:   only   the   first   and   the   end   are         needed   here   since   any   failure   to   any   of   this   would           indicate   there   would   an   error   on   the   entire   range   */
  49. dummy   =   ptr[0];
  50. dummy   =   ptr[buffer_size-1];
  51. }

  52.             /*   restoring   the   original   signal   environment   */
  53. sigaction(SIGSEGV,   &oldaction,   NULL);

  54. return   segv_flag;
  55. }

  56. int   main()
  57. {
  58. char   *testptr,c;     //   testptr[10],结果将是Ok   read   Ptr

  59. if   (   IsReadBadPtr(testptr,   10))
  60. printf( "   Bad   read   Ptr\n ");
  61. else
  62. printf( "   Ok   read   Ptr\n ");
  63. fflush(stdout);
  64. return   0;
  65. }
复制代码

论坛徽章:
0
39 [报告]
发表于 2011-02-17 16:04 |只看该作者
这个比较简单,可以通过检查该变量地址是否有可写属性
通过分析/proc/pid/maps文件可以得出

下面是实现:
  1. int check_mem_wrtieable(unsigned long addr, int len)
  2. {
  3.         pid_t pid ;
  4.         char namemaps[64];
  5.         unsigned long ulStartAddr, ulEndAddr, ulLastAddr;
  6.         char access , buff[1024];
  7.         FILE *pmap;
  8.        
  9.         pid = getpid();
  10.         sprintf(namemaps, "/proc/%d/maps", pid);
  11.        
  12.         pmap = fopen(namemaps, "rb");
  13.         if(pmap)
  14.         {
  15.                 while(1)
  16.                 {
  17.                         if(NULL == fgets(buff, sizeof(buff)-1, pmap))
  18.                         {
  19.                                 if(feof(pmap)) break;
  20.                                 else
  21.                                 {
  22.                                         fclose(pmap);
  23.                                         return 0;
  24.                                 }
  25.                         }
  26.                        
  27.                         sscanf(buff, "%x-%x %*c%c", &ulStartAddr, &ulEndAddr, &access);
  28.                        
  29.                         if(addr <= ulEndAddr && addr >= ulStartAddr)
  30.                         {
  31.                                 if('w' != access)
  32.                                 {
  33.                                         fclose(pmap);
  34.                                         return 0;
  35.                                 }
  36.                                
  37.                                 if((addr + len) < ulEndAddr)
  38.                                 {
  39.                                         fclose(pmap);
  40.                                         return 1;
  41.                                 }
  42.                                 else // 检查后面部分地址
  43.                                 {
  44.                                         ulLastAddr = ulEndAddr;
  45.                                         len = len - (ulEndAddr - addr);
  46.                                         addr = ulLastAddr;
  47.                                 }
  48.                         }
  49.                         printf("%#x %#x %c\n", ulStartAddr, ulEndAddr, access);       
  50.                 }
  51.         }
  52.        
  53.         fclose(pmap);
  54.         return 0;
  55. }
复制代码

论坛徽章:
0
40 [报告]
发表于 2011-02-18 09:45 |只看该作者
感觉楼主想错了方向, 这种情况下,程序COREDUMP是最好的。不然,如果指针本身不合法(例如,指向了刚刚释放了的内存),这些判断也白搭。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP