大佬教程收集整理的这篇文章主要介绍了memcpy 和源和目标上的 SegFault 被定义和初始化,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我通过复制到初始化的指针来获取 segFault。这是相关代码
*pay = (char *)malloc(sizeof(t1) + 1020 /*1000=payload*/);
memset(*pay,sizeof(t1) + 1020);
struct ethhdr *eth = (struct ethhdr *) *pay;
struct iphdr *ip = (struct iphdr *) (*pay + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *) (*pay + sizeof(struct ethhdr) + sizeof(struct iphdr));
我做到了
memcpy(eth->h_dest,p->h_source,sizeof(eth->h_sourcE));
但上面的行导致了段错误。我在其他线程 h_source
h_source
在结构体 struct packets *p
内
这就是它的定义 struct packets *p
我在其他线程中初始化和分配的方式,见上文。所以 struct packets *p
不是一个未初始化的指针。而且我确定它是在发生 segFault 时分配的。
unsigned char h_source[ETH_ALEN]; /* source ether addr */
感谢您的帮助
更新这是函数的完整代码
voID get_payload_to_send(struct packets *p,char **pay)
{
printf("%s --->>> %s",p->ip_source,p->ip_dest);
int t1;
*pay = (char *)malloc(sizeof(t1) + 1020 /*1000=payload*/);
memset(*pay,sizeof(t1) + 1020);
struct ethhdr *eth = (struct ethhdr *) *pay;
struct iphdr *ip = (struct iphdr *) (*pay + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *) (*pay + sizeof(struct ethhdr) + sizeof(struct iphdr));
//if (p->h_proto == ntohs(p->h_proto) == ETH_P_Ip)
{
if (p->syn == 1 && p->ack == 0 && p->fin == 0)
{
///Ethernet
//memcpy(eth->h_dest,sizeof(eth->h_sourcE));
eth->h_proto = htonl(ETH_P_Ip);
//memcpy(eth->h_source,p->h_dest,sizeof(eth->h_dest));
////IP
// memcpy(ip->saddr,inet_addr(p->ip_dest),sizeof(ip->saddr));
struct sockaddr_in s1,s2;
s1.sin_family = AF_INET;
s1.sin_port = htons(80);
s1.sin_addr.s_addr = inet_addr(p->ip_sourcE);
s2.sin_family = AF_INET;
s2.sin_port = htons(5009);
s2.sin_addr.s_addr = inet_addr(p->ip_dest);
//ip->saddr = s1.sin_addr.s_addr;
sleep(2);
ip->daddr = s2.sin_addr.s_addr;
char c[20];
memcpy(ip->saddr,sizeof(C) - 1);
ip->ihl = 5;
ip->version = 4;
ip->tos = 0;
ip->tot_len = sizeof(t1) + 1020;
srand(1001);
ip->ID = htonl(rand());
ip->frag_off = 0;
ip->ttl = 225;
ip->protocol = IPPROTO_TCP;
ip->check = 0;
tcp->syn = 1;
tcp->ack = 1;
memcpy(ip->daddr,inet_addr(p->ip_sourcE),sizeof(C) - 1);
//ip->check = csum((unsigned short *)*pay,ip->tot_len);
}
else if (p->syn == 0 && p->ack == 1)
{
}
}
//printf("%saddr %s -->>",p->ip_sourcE);
//printf("daddr %s\n",p->ip_dest);
//populate eth
}
这是对上述函数进行函数调用的代码
void *task_sender(void *args) {
struct struct_super_struct *super = (struct struct_super_struct *)args;
struct packets *p = super->p; //(struct packets *)args;
printf("Sender\n");
while (1)
{
//printf("got uppder loop SENDER\n");
pthread_mutex_lock(&muteX);
while (nop == 0)
{
pthread_cond_wait(&cond,&muteX);
//printf("finished waiTing in SENDER\n");
}
int i = 0;
printf("nop is greater than 2 in SENDER %d\n");
while (nop > 0)
{
// check_and_process_connection(super,(p+i));
//if (p == NulL) break;
if (strcmp("192.168.10.25",(p+i)->ip_dest) == 0 && (p+i)->syn == 1 && (p+i)->ack == 0)
{
//sleep(1);
//printf("%s\n",(p+i)->ip_dest);
//if (strcmp((p+i)->ip_dest,"192.168.10.25") == 0)
{
char *pac;
struct packets *pt = (p+i);
get_payload_to_send((p+i),&pac);
struct sockaddr_in temp;
struct ethhdr *eth = (struct ethhdr *)pac;
struct iphdr *ip = (struct iphdr *)(pac + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *)(pac + sizeof(struct ethhdr) + sizeof(struct iphdr));
temp.sin_addr.s_addr = ip->saddr;
char *source = inet_ntoa(temp.sin_addr);
struct sockaddr_in temp1;
temp1.sin_addr.s_addr = ip->daddr;
char *dest = inet_ntoa(temp1.sin_addr);
printf("%s >> %s \n",(p+i)->ip_source,(p+i)->ip_dest);
//if (strcmp("192.168.10.25",dest) == 0 && strcmp("192.168.10.25",sourcE) == 0)
{
///temp1.sin_addr.s_addr = ip->daddr;
printf("should be\n");
printf("frm %s to %s syc:%d ack:%d \n",inet_ntoa(temp.sin_addr),inet_ntoa(temp1.sin_addr),tcp->syn,tcp->ack);
}
/*
printf("__________________________________________________\n");
printf("lastop: %d\n",(p+i)->lastop);
printf("source: %s %d\n",(p+i)->tcp_sourcE);
printf("dest: %s %d\n",(p+i)->ip_dest,(p+i)->tcp_dest);
printf("syc: %d\n",(p+i)->syn);
printf("ack: %d\n",(p+i)->ack);
printf("seq: %d\n",(p+i)->seq);
printf("ack seq: %d\n",(p+i)->ack_seq);
(p+i)->lastop = 0;
printf("lastop: %d\n",(p+i)->lastop);
*/
}
//printf("dest port: %d\n",(p+i)->tcp_dest);
}
//else { printf("source ip: %s\n",(p+i)->ip_sourcE); printf("dest ip: %s\n",(p+i)->ip_dest); }
//p++;
nop--;
i++;
//printf("just processed packet SENDER\n");
}
//p = NulL;
pthread_mutex_unlock(&muteX);
nop = 0;
int s = pthread_cond_signal(&cond);
}
}
更新 2
struct packets {
int syn;
char payload[1000];
// pthread_mutex_t mutex;
int lastop;
unsigned char h_dest[ETH_ALEN]; /* desTination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto;
char ip_source[20];
char ip_dest[20];
int tcp_source;
int tcp_dest;
int seq;
int ack_seq;
int ack;
int fin;
int rst;
int window;
int nop;
struct ethhdr *eth;
struct iphdr *ip;
struct tcphdr *tcp;
}; // *p=NulL;
注意我发现用 gdb 调试的是,在 @H_731_5@memcpy(eth->h_dest,sizeof(eth->h_sourcE)); 行 eth->hdest
是 NulL
您报告说,鉴于此设置...
void get_payload_to_send(struct packets *p,char **pay)
{
printf("%s --->>> %s",p->ip_source,p->ip_dest);
int t1;
*pay=(char *) malloc(sizeof(t1)+1020/*1000=payload*/);
memset (*pay,sizeof(t1)+1020);
struct ethhdr *eth = (struct ethhdr *) *pay;
struct iphdr *ip = (struct iphdr *) (*pay + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *) (*pay + sizeof(struct ethhdr) + sizeof(struct iphdr));
...您发现此 @H_731_5@memcpy() 引发了段错误:
@H_731_5@memcpy(eth->h_dest,p->h_source,sizeof(eth->h_sourcE));
,gdb 向您显示 eth->h_dest
在调用时为空。
嗯,目标指针为空完全解释了段错误。如果 eth->h_dest
是一个指针并且所有位为零是其类型的空指针表示,那么当然它是空的。您可以通过 @H_731_5@memset() 调用将其设置为零。
在复制数据之前,您需要为 eth->h_dest
分配足够的(额外的)空间来指向它,或者使用指针赋值将其指向现有对象。上下文不够清楚,我无法判断哪些更合适。
这行有两个市长错误:
struct ethhdr *eth = (struct ethhdr *) *pay;
struct iphdr *ip = (struct iphdr *) (*pay + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *) (*pay + sizeof(struct ethhdr) + sizeof(struct iphdr));
pay*
指向的内存是使用幻数分配的,ethhdr
、iphdr
和 tcphdr
的大小可能相同,但我不会不喜欢处理该代码,可能会越界访问。
关于对齐,可能会发生 ethhdr
必须落在 X 的倍数上,但 pay
不是。这将触发一个错误(@H_731_5@malloc 将返回一个对齐至少为 max_align_t 的地址,但一切都可能随着额外的添加而发生)。
问题在于您没有提供指向 @H_731_5@memset() 的正确指针:
char *pay=(char *) malloc(sizeof(t1)+1020);
memset (*pay,sizeof(t1)+1020);
使用动态分配的数组char
中的第一个pay
作为目标地址清除内存。
正确的形式是
char *pay = malloc(sizeof(t1)+1020);
memset (pay,sizeof(t1)+1020);
这是因为 pay
是指向动态分配数组的指针,而 *pay
是指它的第一个元素的值,就像 pay[0]
一样。
(在 C 中,不需要从 void * 显式转换,例如 malloc() 的返回值。)
多次重复相同的错误:
struct ethhdr *eth = (struct ethhdr *) *pay;
struct iphdr *ip = (struct iphdr *) (*pay + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *) (*pay + sizeof(struct ethhdr) + sizeof(struct iphdr));
这些声明并初始化指向从动态分配的数组 pay
中的第一个字符派生的地址的指针,而不是相对于数组开头的地址。
同样,它们的正确形式是
struct ethhdr *eth = (struct ethhdr *) pay;
struct iphdr *ip = (struct iphdr *) (pay + sizeof(struct ethhdr));
struct tcphdr *tcp = (struct tcphdr *) (pay + sizeof(struct ethhdr) + sizeof(struct iphdr));
因为 *pay
指的是 pay
数组中第一个元素的值,而 pay
指的是数组的地址。
显然,实际代码是
char **pay;
*pay = malloc(sizeof (t1) + 1020);
memset (*pay,sizeof (t1) + 1020);
这缺少两项基本检查:
那个 pay
不是 NULL
那个@H_731_5@malloc()成功了
代码可能会因上述症状而失败。在最小值,将其重写为
assert(pay != null);
*pay = malloc(sizeof (t1) + 1020);
assert(*pay != null);
memset(*pay,sizeof (t1) + 1020);
eth
、ip
和 tcp
变量定义保持其原始形式(即使用 *pay
)。
以上是大佬教程为你收集整理的memcpy 和源和目标上的 SegFault 被定义和初始化全部内容,希望文章能够帮你解决memcpy 和源和目标上的 SegFault 被定义和初始化所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。