先介绍下背景:
我需要将kni移植到l2fwd上,所以将kni里面能用得到的函数都写到一个文件里面,l2fwd在另外一个文件中。共用的东西放到其他文件中。
出现的问题。kni_port_params_array这个在kni里面的全局变量,当我在l2fwd文件中引用的时候,结构体里面的数据总是nil。(kni_port_params_array[p]->kni[i])=nil
解决思路:打开gdb调试,发现内存的内容没有问题
395 nb_kni = kni_port_params_array[p]->nb_kni;
(gdb) x /32ga kni_port_params_array
0x8033a0 <kni_port_params_array>: 0x2aab1e4ee100 0x2aab1e4edf00
0x8033b0 <kni_port_params_array+16>: 0x0 0x0
0x8033c0 <kni_port_params_array+32>: 0x0 0x0
0x8033d0 <kni_port_params_array+48>: 0x0 0x0
0x8033e0 <kni_port_params_array+64>: 0x0 0x0
0x8033f0 <kni_port_params_array+80>: 0x0 0x0
0x803400 <kni_port_params_array+96>: 0x0 0x0
0x803410 <kni_port_params_array+112>: 0x0 0x0
0x803420 <kni_port_params_array+128>: 0x0 0x0
0x803430 <kni_port_params_array+144>: 0x0 0x0
0x803440 <kni_port_params_array+160>: 0x0 0x0
0x803450 <kni_port_params_array+176>: 0x0 0x0
0x803460 <kni_port_params_array+192>: 0x0 0x0
0x803470 <kni_port_params_array+208>: 0x0 0x0
0x803480 <kni_port_params_array+224>: 0x0 0x0
0x803490 <kni_port_params_array+240>: 0x0 0x0
(gdb) x /32ga 0x2aab1e4ee100 这个是kni_port_params_array[p]的地址
0x2aab1e4ee100: 0x100000000 0x2
0x2aab1e4ee110: 0x1 0x0
0x2aab1e4ee120: 0x0 0x0
0x2aab1e4ee130: 0x0 0x0
0x2aab1e4ee140: 0x0 0x0
0x2aab1e4ee150: 0x0 0x0
0x2aab1e4ee160: 0x0 0x0
0x2aab1e4ee170: 0x0 0x0
0x2aab1e4ee180: 0x0 0x0
0x2aab1e4ee190: 0x0 0x2aaab15eb700 这个是kni_port_params_array[p]->kni[i]的地址
0x2aab1e4ee1a0: 0x0 0x0
0x2aab1e4ee1b0: 0x0 0x0
0x2aab1e4ee1c0: 0x0 0x0
0x2aab1e4ee1d0: 0x0 0x0
0x2aab1e4ee1e0: 0x0 0x0
0x2aab1e4ee1f0: 0x0 0x0
没有别的办法,开始一步一步反汇编:
rt = kni_port_params_array[p]->kni[i];
1: x/10i $pc
=> 0x42e11a <lcore_main+795>: mov 0x8043e0(,%rax,8),%rax
0x42e122 <lcore_main+803>: mov -0x278(%rbp),%edx
0x42e128 <lcore_main+809>: add $0x10,%rdx
0x42e12c <lcore_main+813>: mov 0x20(%rax,%rdx,8),%rax
0x42e131 <lcore_main+818>: mov %rax,-0x228(%rbp)
0x42e138 <lcore_main+825>: mov -0x278(%rbp),%esi
0x42e13e <lcore_main+831>: mov -0x27c(%rbp),%ecx
0x42e144 <lcore_main+837>: mov -0x228(%rbp),%rdx
0x42e14b <lcore_main+844>: mov -0x230(%rbp),%rax
0x42e152 <lcore_main+851>: mov %esi,%r8d
上面的0x8043e0这个地址就是 kni_port_params_array在程序中的全局地址,表达式
kni_port_params_array[p]->kni[i];参照上面的汇编发现没有问题,继续。
0x000000000042e12c 400 rt = kni_port_params_array[p]->kni[i];
1: x/10i $pc
=> 0x42e12c <lcore_main+813>: mov 0x20(%rax,%rdx,8),%rax ---> 这一句对应结构体发现问题
struct kni_port_params {
uint8_t port_id;/* Port ID */
unsigned lcore_rx; /* lcore ID for RX */
unsigned lcore_tx; /* lcore ID for TX */
uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */
uint32_t nb_kni; /* Number of KNI devices to be created */
unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */
struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */
} __rte_cache_aligned;
0x42e131 <lcore_main+818>: mov %rax,-0x228(%rbp)
0x42e138 <lcore_main+825>: mov -0x278(%rbp),%esi
0x42e13e <lcore_main+831>: mov -0x27c(%rbp),%ecx
0x42e144 <lcore_main+837>: mov -0x228(%rbp),%rdx
0x42e14b <lcore_main+844>: mov -0x230(%rbp),%rax
0x42e152 <lcore_main+851>: mov %esi,%r8d
0x42e155 <lcore_main+854>: mov %rax,%rsi
0x42e158 <lcore_main+857>: mov $0x55930a,%edi
0x42e15d <lcore_main+862>: mov $0x0,%eax
(gdb) p $rdx
$20 = 16
(gdb) x $rax
0x2aab1e4ee100: 0x0000000100000000
(gdb) x /32g $rax
根据上面的汇编发现kni_port_params_array[p]->kni[i];对应的0x20(%rax,%rdx,8),%rax是取结构体偏移为0x20处的内容,但是结构体为64字节对齐,找到问题。然后对应代码发现头文件中在声明全局变量的时候把变量声明到了结构体的上面,把位置改变一下就可以了。
错误方法:
extern struct kni_port_params *kni_port_params_array[RTE_MAX_ETHPORTS];
struct kni_port_params {
uint8_t port_id;/* Port ID */
unsigned lcore_rx; /* lcore ID for RX */
unsigned lcore_tx; /* lcore ID for TX */
uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */
uint32_t nb_kni; /* Number of KNI devices to be created */
unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */
struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */
} __rte_cache_aligned;
正确方法:
struct kni_port_params {
uint8_t port_id;/* Port ID */
unsigned lcore_rx; /* lcore ID for RX */
unsigned lcore_tx; /* lcore ID for TX */
uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */
uint32_t nb_kni; /* Number of KNI devices to be created */
unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */
struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */
} __rte_cache_aligned;
extern struct kni_port_params *kni_port_params_array[RTE_MAX_ETHPORTS];
0x2aab1e4ee100: 0x0000000100000000 0x0000000000000002
0x2aab1e4ee110: 0x0000000000000001 0x0000000000000000
0x2aab1e4ee120: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee130: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee140: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee150: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee160: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee170: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee180: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee190: 0x0000000000000000 0x00002aaab15eb700
0x2aab1e4ee1a0: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee1b0: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee1c0: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee1d0: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee1e0: 0x0000000000000000 0x0000000000000000
0x2aab1e4ee1f0: 0x0000000000000000 0x0000000000000000
(gdb) si
0x000000000042e131 400 rt = kni_port_params_array[p]->kni[i];
1: x/10i $pc
=> 0x42e131 <lcore_main+818>: mov %rax,-0x228(%rbp)
0x42e138 <lcore_main+825>: mov -0x278(%rbp),%esi
0x42e13e <lcore_main+831>: mov -0x27c(%rbp),%ecx
0x42e144 <lcore_main+837>: mov -0x228(%rbp),%rdx
0x42e14b <lcore_main+844>: mov -0x230(%rbp),%rax
0x42e152 <lcore_main+851>: mov %esi,%r8d
0x42e155 <lcore_main+854>: mov %rax,%rsi
0x42e158 <lcore_main+857>: mov $0x55930a,%edi
0x42e15d <lcore_main+862>: mov $0x0,%eax
0x42e162 <lcore_main+867>: callq 0x41df90 <[email protected]>
(gdb) p $rax
$22 = 0
(gdb) x $rax
0x0: Cannot access memory at address 0x0
(gdb)