LINUX.ORG.RU

Проблемма с выделением памяти.


0

0

Уже задавал подобный вопрос но ответа так и не получил, веренее была пара советов, но они не оказали эффекта.

Так что повторюсь. Имеется модуль, в нём реализована функция write ну и конечно же создаётся девайс, который юзается через внешнюю прогу.

Вот код проги:

/*****************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

char *num;	//num of parametrs

//convert int to char
void int_to_char(int n)
{
  ...
}

int main(int argc, char *argv[])
{
	int fd;
	char *end = "$";

	//this is dev for netfw control
	fd = open("/dev/netfw", O_RDWR);
	if(fd == -1){
		printf("open failed\n");
		return -1;
	}
	printf("Device netfw open\nTry to write\n");

	//calc num of parametrs like: from, to, fport, tport
	int ap = argc - 1 - 3;
	printf("ap = %d\n",ap);	//check it
	int i;
	//write control element like: add/del, pass/drop and name of table
	printf("argc = %d\n",argc);	//check it
	if(!argv[1])
	{
		printf("write 1$\n");
		write(fd,end,strlen(end) + 1);
		return 0;
	}
	else write(fd, argv[1], strlen(argv[1]) + 1);
	if(!argv[2])
	{
		printf("wrte 2$\n");
		write(fd,end,strlen(end) + 1);
		return 0;
	}
	else write(fd, argv[2], strlen(argv[2]) + 1);
	if(!argv[3])
	{
		printf("write 3$\n");
		write(fd,end,strlen(end) + 1);
		return 0;
	}
	else write(fd, argv[3], strlen(argv[3]) + 1);
	if(ap > 0)	
	{
		//write num of parametrs
		int_to_char(ap/2);
		write(fd, num, strlen(num) + 1);
	
		//write parametrs
		for(i = argc - ap; i < argc; i++)
		{
			printf(argv[i]);
			printf("\n");
			write(fd, argv[i], strlen(argv[i]) + 1);
		}
	}
	//write symbol to finish transacton, in this case it's "$"
	printf("write 4$\n");
	write(fd,end,strlen(end) + 1);
		
	//close file
	close(fd);
	printf("Device netfw close\n");

	free(num);

	return EXIT_SUCCESS;
}
/*****************************************************************/

А вот та часть кода модуля которая глючит.

/*****************************************************************/
			n_arg++;
		}
		n++;
	}
	if(!strcmp(ch,"$")){
		step = -1;
		n = n_par = n_arg = 0;
		if(act > 0)	{
			struct netfw_table *tab;
			switch(act){
				case NETFW_ADD_RULE:
					/*if(*/netfw_add_rule(to_table,0,it,par,arg,num)/*)*/;
					       break;
				case NETFW_DEL_RULE:
//					tab = netfw_get_table_by_name(to_table)/*)*/;
//					if(tab)/*if(*/tab->set_rule(NETFW_DEL_RULE,0,to_table,-2,it,par,arg,nu
m)/*)*/;
//					else printk("ERROR at del rule for table - %s!!!\n",to_table);
					break;
				case NETFW_SET_POL:
					tab = netfw_get_table_by_name(to_table);
					if(tab)/*if(*/tab->set_rule(NETFW_SET_POL,0,0,0,it,0,0,0)/*)*/;
					else printk("NetFW: ERROR at set new policy for table - %s!!!\n",to_table);
					break;
				case NETFW_SHOW_RULE:
//					tab = netfw_get_table_by_name(to_table);
//					if(tab)/*if(*/tab->set_rule(NETFW_SHOW_RULE,0,0,0,0,0,0,0)/*)*/;
//					else printk("ERROR at show rule for table - %s!!!\n",to_table);
					break;
			}
		}
		if(par) kfree(par);
		if(arg) kfree(arg);
		if(to_table) kfree(to_table);
		if(out) kfree(out);
		to_table = 0;
		num = 0;
	}
	step++;
	switch(step){
		//Action
		case 1:
			if(!strcmp(ch,"add")){
				act = NETFW_ADD_RULE;
			}
			if(!strcmp(ch,"del")){
				act = NETFW_DEL_RULE;
			}
			if(!strcmp(ch,"policy")){
				act = NETFW_SET_POL;
			}
			if(!strcmp(ch,"show")){
				act = NETFW_SHOW_RULE;
			}
			break;
		//Table name
		case 2:
			to_table = kmalloc(sizeof(char[strlen(ch)]),GFP_ATOMIC);
			if(!to_table) return 0;
			to_table = strcpy(to_table,ch);
			break;
		//What to do ( aka "it" )
		case 3:
			if(!strcmp(ch,"accept")){
				it = NETFW_ACCEPT;
			}
			if(!strcmp(ch,"drop")){
				it = NETFW_DROP;
			}
			break;
		//Num of elements
		case 4:
			num = netfw_char_to_int((char*)ch);
			if(par) kfree(par);
			if(arg) kfree(arg);
			par = kmalloc((sizeof(char *) * num),GFP_ATOMIC);
			if(!par) return 0;
			arg = kmalloc((sizeof(char *) * num),GFP_ATOMIC);
			if(!arg) return 0;
			par_accept = 1;
			break;
	}

	return 0;
}

//for device
struct file_operations Fops = 
{
	read:	netfw_read,
	write:	netfw_write,
	ioctl:		netfw_ioctl,
};
/*****************************************************************/

Вообщем ситуация обстоит так. После третьего (а иногда и второго) 
вызова проги, т.е. после того как функция записи вызвана
происходит сегфолт. Вот вывод лога

Aug 19 12:20:24 dell kernel: par[0] = from, ch = from, parg = from
Aug 19 12:20:24 dell kernel: arg[0] = 127.0.0.1, ch = 127.0.0.1, parg = 127.0.0.1
Aug 19 12:20:28 dell kernel: par[0] = from, ch = from, parg = from
Aug 19 12:20:28 dell kernel: c8e954aa
Aug 19 12:20:28 dell kernel: Modules linked in: netfw ipv6 rfcomm hidp l2cap speedstep_lib freq_table thermal processor fan button battery ac hci_usb bluetooth snd_pcm_oss snd_mixer_oss snd_seq_midi snd_seq_midi_event snd_seq evdev joydev sg st sr_mod edd snd_es1968 gameport snd_ac97_codec snd_pcm snd_timer snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_device intel_agp snd agpgart soundcore uhci_hcd usbcore yenta_socket rsrc_nonstatic i2c_piix4 pcmcia_core i2c_core parport_pc lp video1394 ohci1394 parport raw1394 ieee1394 capability subfs sd_mod scsi_mod dm_mod reiserfs ide_cd cdrom ide_disk piix ide_core
Aug 19 12:20:28 dell kernel: CPU:    0
Aug 19 12:20:28 dell kernel: EIP:    0060:[<c8e954aa>]    Tainted: P     U VLI
Aug 19 12:20:28 dell kernel: EFLAGS: 00010246   (2.6.11.4-20a-default)
Aug 19 12:20:28 dell kernel: EIP is at netfw_write+0x16a/0x5c0 [netfw]
Aug 19 12:20:28 dell kernel: eax: 2e373231   ebx: ffffffff   ecx: 00000000   edx: 00000000
Aug 19 12:20:28 dell kernel: esi: c60ec4e1   edi: 2e373231   ebp: c60ec4e0   esp: c4cfff6c
Aug 19 12:20:28 dell kernel: ds: 007b   es: 007b   ss: 0068
Aug 19 12:20:28 dell kernel: Process netfw (pid: 5854, threadinfo=c4cfe000 task=c7211a80)
Aug 19 12:20:28 dell kernel: Stack: c60ec4e0 2e373231 0000000a bffff615 c8e95340 0000000a c60dd880 bffff615
Aug 19 12:20:28 dell kernel:        c0151313 c4cfffac c60dd880 fffffff7 08048fa0 c4cfe000 c015143c c4cfffac
Aug 19 12:20:28 dell kernel:        00000000 00000000 00000000 00000003 40016cc0 c0102c49 00000003 bffff615
Aug 19 12:20:28 dell kernel: Call Trace:
Aug 19 12:20:28 dell kernel:  [<c8e95340>] netfw_write+0x0/0x5c0 [netfw]
Aug 19 12:20:28 dell kernel:  [<c0151313>] vfs_write+0x93/0x110
Aug 19 12:20:28 dell kernel:  [<c015143c>] sys_write+0x3c/0x70
Aug 19 12:20:28 dell kernel:  [<c0102c49>] sysenter_past_esp+0x52/0x79
Aug 19 12:20:28 dell kernel: Code: e8 3c f0 33 f7 85 c0 74 51 68 0f 6f e9 c8 eb db 8b 3d ac 86 e9 c8 8b 15 9c 86 e9 c8 89 3c 24 89 ee 8b 04 97 89 44 24 04 89 c7 ac <aa> 84 c0 75 fa 8b 04 24 8b 4c 24 04 89 0c 90 89 e8 e8 e0 7e 2a

Пробовал сделать par[] и arg[] в виде списков, не помогло.

Заранее спасибо!!!
★★★★★

А что такое to_table?

Dead ★★★★
()

какой страшненький код.
Не хочу обидеть, но я бы посоветовал сначала потренироваться в user 
space, прежде чем с таким опытом в kernel кодить.

Вот например.
to_table = kmalloc(sizeof(char[strlen(ch)]),GFP_ATOMIC);
if(!to_table) return 0;
to_table = strcpy(to_table,ch);

может быть надо было:
to_table = kmalloc(strlen(ch)+1,GFP_ATOMIC);

??
  

Dead ★★★★
()
Ответ на: комментарий от Dead

Да этой функции уже три месяца, и многое за это время в моих познаниях (о как сказал :) ) изменилось, а содержимое этой функции осталось старым (из старой версии). Вообщем это скорее всего ничего не изменит, но попробую. Просто я уже не знаю что и думать менял многое!!!

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Ну как сказать...
Один байт - это конечно мелочь, но вот такая-вот ошибка в user space привела бы к тому, что прога сигфолтилась через раз и причем в разных местах.

Dead ★★★★
()
Ответ на: комментарий от Dead

Поправил но не помогло. Кстати заметил что сегфолты бывают не только в netfw_write 

Aug 19 19:58:46 dell kernel: par[0] = from, ch = from, parg = from
Aug 19 19:58:46 dell kernel: arg[0] = 127.0.0.1, ch = 127.0.0.1, parg = 127.0.0.1
Aug 19 19:58:46 dell kernel: NetFW: Rule was add successfull
Aug 19 19:58:47 dell kernel: par[0] = from, ch = from, parg = from
Aug 19 19:58:47 dell kernel: arg[0] = 127.0.0.1, ch = 127.0.0.1, parg = 127.0.0.1
Aug 19 19:58:47 dell kernel: Unable to handle kernel paging request at virtual address ffff9370
Aug 19 19:58:47 dell kernel:  printing eip:
Aug 19 19:58:47 dell kernel: c013d3c2
Aug 19 19:58:47 dell kernel: *pde = 00002067
Aug 19 19:58:47 dell kernel: Oops: 0000 [#1]
Aug 19 19:58:47 dell kernel: Modules linked in: netfw ppp_deflate zlib_deflate bsd_comp ppp_async crc_ccitt ppp_generic slhc ipv6 rfcomm hidp l2cap speedstep_lib freq_table thermal processor fan button battery ac hci_usb bluetooth snd_pcm_oss snd_mixer_oss snd_seq_midi snd_seq_midi_event snd_seq evdev joydev sg st sr_mod edd video1394 ohci1394 snd_es1968 gameport snd_ac97_codec snd_pcm snd_timer snd_page_alloc snd_mpu401_uart intel_agp snd_rawmidi agpgart raw1394 snd_seq_device ieee1394 snd i2c_piix4 soundcore i2c_core yenta_socket uhci_hcd rsrc_nonstatic pcmcia_core usbcore capability parport_pc lp parport subfs sd_mod scsi_mod dm_mod reiserfs ide_cd cdrom ide_disk piix ide_core
Aug 19 19:58:47 dell kernel: CPU:    0
Aug 19 19:58:47 dell kernel: EIP:    0060:[<c013d3c2>]    Tainted: P     U VLI
Aug 19 19:58:47 dell kernel: EFLAGS: 00010006   (2.6.11.4-20a-default)
Aug 19 19:58:47 dell kernel: EIP is at kfree+0x22/0x50
Aug 19 19:58:47 dell kernel: eax: ffff9370   ebx: 00000000   ecx: 000000c9   edx: c1000000
Aug 19 19:58:47 dell kernel: esi: 2e373231   edi: 00000202   ebp: c5e562c0   esp: c23d5f3c
Aug 19 19:58:47 dell kernel: ds: 007b   es: 007b   ss: 0068
Aug 19 19:58:47 dell kernel: Process netfw (pid: 8256, threadinfo=c23d4000 task=c6ac9020)
Aug 19 19:58:47 dell kernel: Stack: 00000000 00000001 c76e2980 c8e95031 c8e95340 08049077 c8e96f49 c5e562c0
Aug 19 19:58:47 dell kernel:        c8e958be c5e562c0 c76e2980 00000001 c7be600c 00000009 00000002 08049075
Aug 19 19:58:47 dell kernel:        c8e95340 00000002 c16cc4c0 08049075 c0151313 c23d5fac c16cc4c0 fffffff7
Aug 19 19:58:47 dell kernel: Call Trace:
Aug 19 19:58:47 dell kernel:  [<c8e95031>] netfw_add_rule+0x31/0x70 [netfw]
Aug 19 19:58:47 dell kernel:  [<c8e95340>] netfw_write+0x0/0x5c0 [netfw]
Aug 19 19:58:47 dell kernel:  [<c8e958be>] netfw_write+0x57e/0x5c0 [netfw]
Aug 19 19:58:47 dell kernel:  [<c8e95340>] netfw_write+0x0/0x5c0 [netfw]
Aug 19 19:58:47 dell kernel:  [<c0151313>] vfs_write+0x93/0x110
Aug 19 19:58:47 dell kernel:  [<c015143c>] sys_write+0x3c/0x70
Aug 19 19:58:47 dell kernel:  [<c0102c49>] sysenter_past_esp+0x52/0x79
Aug 19 19:58:47 dell kernel: Code: d0 5b 5e 5f c3 8d 74 26 00 57 85 c0 56 89 c6 53 74 2d 9c 5f fa 8d 80 00 00 00 40 c1 e8 0c 8b 15 70 3b 3e c0 c1 e0 05 8b 44 02 18 <8b> 18 8b 13 3b 53 04 73 0f 89 74 93 10 8b 03 40 89 03 57 9d 5b

а вот ещё одна функция модуля

int netfw_add_rule(char *table_name, int id, int it, char **par, char **arg, int num)
{
	int i;
	for(i = 0; i < num; i++){
		if(par[i]) kfree(par[i]);
		if(arg[i]) kfree(arg[i]);
	}

	printk( KERN_DEBUG "NetFW: Rule was add successfull\n");

	netfw_num_rules++;
	return 1;
}

тут пока что только очистка массивов.

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

cyclon, по твоим двум кусочкам что-то увидеть нельзя в принципе.

Учитывая, что падает случайным образом, и что во втором приведённом выводе segfault есть текст "kernel paging request" заключаю, что ты с куказателями перемудрил. Первое, что приходит в голову - делаешь ли copy_from_user в операции write как полагается (опять же, по кусочку этого не видно)?

erDiZz
()
Ответ на: комментарий от erDiZz

Млин мне показалась там вся функция а вставился кусок, так что мой пардон и вот вся функция

ssize_t netfw_write (struct file *f, const char *ch, size_t size, loff_t *loff)
{
	char *parg;
	if(num > 0)if(n < num*2){
		if(par_accept){
			par[n_par] = kmalloc((sizeof(char) * strlen(ch)) + 1,GFP_KERNEL);
			parg = kmalloc((sizeof(char) * strlen(ch)) + 1,GFP_KERNEL);
			if(!par[n_par]) return 0;
////			par[n_par] = strcpy(par[n_par],ch);
////			get_user(par[n_par], ch);
			if(copy_from_user(parg,ch,size)){
				printk("Error on copy par!!!\n");
				return 0;
			}
			par[n_par] = strcpy(par[n_par],parg);
			kfree(parg);
			if(par[n_par] == 0){
				printk("Error no par!!!\n");
				return 0;
			}
			printk("par[%d] = %s, ch = %s, parg = %s\n",n_par,par[n_par],ch,parg);
			par_accept = 0;
			n_par++;
		}
		else{
			arg[n_arg] = kmalloc((sizeof(char) * strlen(ch)) + 1,GFP_KERNEL);
			parg = kmalloc((sizeof(char) * strlen(ch)) + 1,GFP_KERNEL);
			if(!arg[n_arg]) return 0;
////			arg[n_arg] = strcpy(arg[n_arg],ch);
////			get_user(arg[n_arg], ch);
			if(copy_from_user(parg,ch,size)){
				printk("Error on copy arg!!!\n");
				return 0;
			}
			arg[n_arg] = strcpy(arg[n_arg],parg);
			kfree(parg);
			if(arg[n_arg] == 0){
				printk("Error no arg!!!\n");
				return 0;
			}
			printk("arg[%d] = %s, ch = %s, parg = %s\n",n_arg,arg[n_arg],ch,parg);
			par_accept = 1;
			n_arg++;
		}
		n++;
	}
	if(!strcmp(ch,"$")){
		step = -1;
		n = n_par = n_arg = 0;
		if(act > 0)	{
			struct netfw_table *tab;
			switch(act){
				case NETFW_ADD_RULE:
					/*if(*/netfw_add_rule(to_table,0,it,par,arg,num)/*)*/;
					       break;
				case NETFW_DEL_RULE:
//					tab = netfw_get_table_by_name(to_table)/*)*/;
//					if(tab)/*if(*/tab->set_rule(NETFW_DEL_RULE,0,to_table,-2,it,par,arg,nu
m)/*)*/;
//					else printk("ERROR at del rule for table - %s!!!\n",to_table);
					break;
				case NETFW_SET_POL:
					tab = netfw_get_table_by_name(to_table);
					if(tab)/*if(*/tab->set_rule(NETFW_SET_POL,0,0,0,it,0,0,0)/*)*/;
					else printk("NetFW: ERROR at set new policy for table - %s!!!\n",to_table);
					break;
				case NETFW_SHOW_RULE:
//					tab = netfw_get_table_by_name(to_table);
//					if(tab)/*if(*/tab->set_rule(NETFW_SHOW_RULE,0,0,0,0,0,0,0)/*)*/;
//					else printk("ERROR at show rule for table - %s!!!\n",to_table);
					break;
			}
		}
		if(par) kfree(par);
		if(arg) kfree(arg);
		if(to_table) kfree(to_table);
		if(out) kfree(out);
		to_table = 0;
		num = 0;
	}
	step++;
	switch(step){
		//Action
		case 1:
			if(!strcmp(ch,"add")){
				act = NETFW_ADD_RULE;
			}
			if(!strcmp(ch,"del")){
				act = NETFW_DEL_RULE;
			}
			if(!strcmp(ch,"policy")){
				act = NETFW_SET_POL;
			}
			if(!strcmp(ch,"show")){
				act = NETFW_SHOW_RULE;
			}
			break;
		//Table name
		case 2:
			to_table = kmalloc(strlen(ch) + 1,GFP_ATOMIC);
			if(!to_table) return 0;
			to_table = strcpy(to_table,ch);
			break;
		//What to do ( aka "it" )
		case 3:
			if(!strcmp(ch,"accept")){
				it = NETFW_ACCEPT;
			}
			if(!strcmp(ch,"drop")){
				it = NETFW_DROP;
			}
			break;
		//Num of elements
		case 4:
			num = netfw_char_to_int((char*)ch);
			if(par) kfree(par);
			if(arg) kfree(arg);
			par = kmalloc((sizeof(char *) * num),GFP_ATOMIC);
			if(!par) return 0;
			arg = kmalloc((sizeof(char *) * num),GFP_ATOMIC);
			if(!arg) return 0;
			par_accept = 1;
			break;
	}

	return 0;
}

cyclon ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.