程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了memcpy 和源和目标上的 SegFault 被定义和初始化大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决memcpy 和源和目标上的 SegFault 被定义和初始化?

开发过程中遇到memcpy 和源和目标上的 SegFault 被定义和初始化的问题如何解决?下面主要结合日常开发的经验,给出你关于memcpy 和源和目标上的 SegFault 被定义和初始化的解决方法建议,希望对你解决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_731_5@memcpy((p)->h_source,received_packet_eth->h_source,sizeof(eth->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->hdestNulL

解决方法

您报告说,鉴于此设置...

    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* 指向的内存是使用幻数分配的,ethhdriphdrtcphdr 的大小可能相同,但我不会不喜欢处理该代码,可能会越界访问。

  • 关于对齐,可能会发生 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);

这缺少两项基本检查:

  1. 那个 pay 不是 NULL

  2. 那个@H_731_5@malloc()成功了

代码可能会因上述症状而失败。在最小值,将其重写为


assert(pay != null);
*pay = malloc(sizeof (t1) + 1020);
assert(*pay != null);
memset(*pay,sizeof (t1) + 1020);

ethiptcp 变量定义保持其原始形式(即使用 *pay)。

大佬总结

以上是大佬教程为你收集整理的memcpy 和源和目标上的 SegFault 被定义和初始化全部内容,希望文章能够帮你解决memcpy 和源和目标上的 SegFault 被定义和初始化所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:memcpy