98 static inline int set_hw_br(pid_t tracee, dr7_t *pdr7, void *addr, int dr_index)
99 {
100 errno = 0;
101 printf("LINE = %d <pid> %d, dr_index= %d addr=%u \n",__LINE__, tracee, dr_index, addr);
102 //if (ptrace(PTRACE_POKEUSER, tracee, offsetof(struct user, u_debugreg[dr_index]), addr))
103 if (ptrace(PTRACE_POKEUSER, tracee, offsetof(struct user, u_debugreg[dr_index]), addr))
104 {
105 int ii = errno;
106 printf("MKH: 22 errno = %d\n", ii);
107 ptrace(PTRACE_DETACH, tracee, 0, 0);
108 return -1;
109 }
110 else
111 printf("PTRACE_POKEUSER passed...\n");
Run Code Online (Sandbox Code Playgroud)
上面的代码(主代码的一部分)在GCC编译器中成功编译.但是在通过G ++进行编译时,它会给出填充错误:error: 'dr_index' cannot appear in a constant-expression在第103行.从另一个函数调用set_hw_br.
知道为什么这个g ++失败了吗?
谢谢.
的offsetof宏要求成员指示符具有产生一个地址常量(C11 7.19/3):
Run Code Online (Sandbox Code Playgroud)offsetof(type, member-designator)它从结构的开头(由类型指定)扩展为一个整数常量表达式
size_t,该表达式的类型(其值是以字节为单位的偏移量)到结构成员(由member-designator指定).类型和成员指示符应为给定的Run Code Online (Sandbox Code Playgroud)static type t;然后表达式
&(t.member-designator)求值为地址常量.(如果指定的成员是位字段,则行为未定义.)
在你的代码中,t.u_subreg[dr_index]不是常量,因为dr_index它不是常数.
GCC offsetof使用编译器内在函数实现,因此offsetof表达式中允许的内容取决于GCC内在规则.作为标准的扩展,GCC C前端允许非常量表达式作为输入并产生非常量结果.C++前端不允许它,给出错误告诉你dr_index不能在那里使用它.
您可以将offsetof表达式更改为仅使用常量:
offsetof(struct user, u_debugreg[0])
Run Code Online (Sandbox Code Playgroud)
然后你可以为它添加索引,T数组中的类型在哪里u_debugreg:
offsetof(struct user, u_debugreg[0]) + sizeof(T)*dr_index
Run Code Online (Sandbox Code Playgroud)
(这假定它u_debugreg是一个实际的数组,而不是一个指针).