的printk会导致错误的内核模块中

问题描述:

说明:我建立一个IPC kernel module。上的Ubuntu系统,它可以传输IPC-数据到运行Ubuntu另一台计算机。我使用的模块kernel_recvmsgkernel_sendmsg通过网络传送IPC-数据。的printk会导致错误的内核模块中

问题:当我发表意见printk消息(我printk代码printk("this is IPC-data");),并使用kernel_sendmsg发送IPC-数据将出现以下情况的另一台计算机。

kernel_sendmsg API返回-95。

#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 

谁能告诉我发生了什么如何调试呢?

我的环境:

Ubuntu 12.04.3 LTS  
Linux ubuntu 3.9.0-030900-generiC#201304291257 SMP Mon Apr 29 17:06:25 UTC 
2013 i686 i686 i386 GNU/Linux 

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 

当前代码:

// Save get_service transaction, 
// when the service is in the remote, 
// send this transaction to the remote 

     if(target_proc->pid==smg_pid && tr->code!=3) 
     { 

      proc->temp_t.data.reply= reply;   
      proc->temp_t.data.ref_add= 0; 
      if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { 
       binder_user_error("binder: %d:%d got transaction with " 
        "invalid offsets size, %zd\n", 
        proc->pid, thread->pid, tr->offsets_size); 
       return_error = BR_FAILED_REPLY; 
       goto err_temp_copy_data_failed; 
      } 

      proc->temp_t.tr=*tr; 

      if (copy_from_user(tr_data, tr->data.ptr.buffer, tr->data_size)) { 
       binder_user_error("binder: %d:%d got transaction with invalid " 
        "data ptr\n", proc->pid, thread->pid); 
       return_error = BR_FAILED_REPLY; 
       goto err_temp_copy_data_failed; 
      } 
      if (copy_from_user(tr_off, tr->data.ptr.offsets, tr->offsets_size)) { 
       binder_user_error("binder: %d:%d got transaction with invalid " 
        "data ptr\n", proc->pid, thread->pid); 
       return_error = BR_FAILED_REPLY; 
       goto err_temp_copy_data_failed; 
      } 
      proc->temp_t.tr.data.ptr.buffer = tr_data;   
      proc->temp_t.tr.data.ptr.offsets = tr_off; 
      binder_debug(BINDER_DEBUG_SOCKET, "proc->temp_t set tr.data_size=%d tr.offsets_size=%d", proc->temp_t.tr.data_size,proc->temp_t.tr.offsets_size); 
     } 


     if((proc->for_ip && tr->code==3 && target_proc->pid==smg_pid)|| (target_proc->ip && proc->pid!=smg_pid)) 
     {  

      binder_debug(SOCKET_DEBUG_REQ, "this is ipc data"); 

//    sock_t=kzalloc(sizeof(*sock_t), GFP_KERNEL); 
      sock_t.reply= reply; 


      if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { 
       binder_user_error("binder: %d:%d got transaction with " 
        "invalid offsets size, %zd\n", 
        proc->pid, thread->pid, tr->offsets_size); 
       return_error = BR_FAILED_REPLY; 
       goto err_temp_copy_data_failed; 
      } 



      if(target_proc->ip) 
       success=send_add_t(proc,&sock_t,tr,target_proc->ip); 
      else     
       success=send_add_t(proc,&sock_t,tr,proc->for_ip); 

//    kfree(sock_t); 
      if(success<0){ 
       return_error = BR_FAILED_REPLY; 
       goto err_send_remote_failed;     
      } 
      target_proc->rcomplete=1;   

     } 

int send_add_t(struct binder_proc *proc,struct tr_ref *rref,struct binder_transaction_data *tr ,int tget_ip) 
{ 
    int count; 
    struct remote_tr remote_tr; 

      remote_tr.fops = add_t_remote; 
      remote_tr.pid=proc->pid; 
      remote_tr.rref=*rref; 
      remote_tr.tr=*tr; 

      count=send(newsock[tget_ip],&remote_tr,sizeof(remote_tr)); 


      binder_debug(SOCKET_DEBUG_REQ, "Send tr.data_size=%d tr.offsets_size=%d count=%d", tr->data_size,tr->offsets_size,count); 
      count=send(newsock[tget_ip],(void *) tr->data.ptr.buffer,tr->data_size); 
      send(newsock[tget_ip],(void *) tr->data.ptr.offsets,tr->offsets_size); 
      proc->r_has=tget_ip; 
//    do_gettimeofday(&tv2); 
//    binder_debug(SOCKET_TIME,"can recv time =%ld.%ldus\n",tv2.tv_sec,tv2.tv_usec); 
//    binder_debug(SOCKET_TIME,"recv to send finish=%ldus",(tv2.tv_sec-tv3.tv_sec)*1000000L+tv2.tv_usec-tv3.tv_usec); 
//    binder_debug(SOCKET_DEBUG_REQ, "Send tr->code=%d count=%d", tr->code,count); 
     return count; 

} 

int send(struct socket* send,void* buf, int len) 
{ 
     struct msghdr msg; 
     struct kvec iov={ 
     .iov_base = buf, 
      .iov_len = len, 

     }; 

     int size = 0; 
     if(!send) 
      return 0; 
      size = kernel_sendmsg(send,&msg,&iov,1,len); 
     return size; 
} 
+0

可以在内核代码中使用#pragma GCC优化(“O0”)和用gdb目标远程本地主机QEMU调试内核代码禁用优化:端口。这是你可以找出你让你的ENOTSUPP错误。另一种方式是到Digg的源代码,并使用printks进行调试。 – 2014-10-04 18:46:20

+0

https://www.linkedin.com/groups/Kernel-module-problem-4166059.S.5924154021244854276?view=&gid=4166059&item=5924154021244854276&type=member&commentID=discussion%3A5924154021244854276%3Agroup%3A4166059&trk=hb_ntf_COMMENTED_ON_GROUP_DISCUSSION_YOU_CREATED#commentID_discussion%3A5924154021244854276%3Agroup %3A4166059 – Stan 2014-10-08 03:19:24

我通过修改发送功能,解决了这个问题。

struct msghdr msg = {.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL};

int send(struct socket* send,void* buf, int len) 
{ 
    struct msghdr msg= {.msg_flags= MSG_DONTWAIT+MSG_NOSIGNAL}; 
    struct kvec iov={ 
      .iov_base = buf, 
      .iov_len = len,  
     }; 
    int size = 0; 

     if(!send) 
      return 0; 
      size = kernel_sendmsg(send,&msg,&iov,1,len); 

     return size; 
}