ubuntu18.04:记一次由引用计数引发的crash_do_error_trap-程序员宅基地

技术标签: ubuntu18.04  linux内核  

[    0.000000] Linux version 4.18.0-15-generic (buildd@lcy01-amd64-029) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #16~18.04.1-Ubuntu SMP Thu Feb 7 14:06:04 UTC 2019 (Ubuntu 4.18.0-15.16~18.04.1-generic 4.18.20)
[  122.189976] IPv4: Attempt to release TCP socket in state 10 00000000b898966d
[  125.157205] ------------[ cut here ]------------
[  125.157211] refcount_t overflow at inet_reqsk_alloc+0x115/0x130 in ksoftirqd/0[9], uid/euid: 0/0
[  125.157214] WARNING: CPU: 0 PID: 9 at /build/linux-hwe-9KJ07q/linux-hwe-4.18.0/kernel/panic.c:648 refcount_error_report+0x9c/0xac
[  125.157215] Kernel panic - not syncing: panic_on_warn set ...
               
[  125.157328] CPU: 0 PID: 9 Comm: ksoftirqd/0 Kdump: loaded Tainted: G           OE     4.18.0-15-generic #16~18.04.1-Ubuntu
[  125.157397] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
[  125.157474] Call Trace:
[  125.157509]  dump_stack+0x63/0x85
[  125.157539]  panic+0xe4/0x244
[  125.157567]  ? refcount_error_report+0x9c/0xac
[  125.157603]  __warn+0x107/0x110
[  125.157632]  ? refcount_error_report+0x9c/0xac
[  125.157668]  report_bug+0xaa/0x120
[  125.157698]  fixup_bug.part.9+0x1c/0x40
[  125.157731]  do_error_trap+0x128/0x160
[  125.157763]  ? down_trylock+0x2e/0x40
[  125.157795]  ? vprintk_emit+0xec/0x290
[  125.157827]  do_invalid_op+0x20/0x30
[  125.157858]  invalid_op+0x14/0x20
[  125.157888] RIP: 0010:refcount_error_report+0x9c/0xac
[  125.157926] Code: 49 8b 94 24 80 00 00 00 41 56 49 8d 8d 50 0a 00 00 45 8b 85 a8 08 00 00 41 89 c1 48 89 de 48 c7 c7 50 d2 6d 86 e8 e4 f9 ff ff <0f> 0b 58 48 8d 65 e0 5b 41 5c 41 5d 41 5e 5d c3 0f 1f 44 00 00 55 
[  125.158066] RSP: 0018:ffffab89c06975b0 EFLAGS: 00010286
[  125.158106] RAX: 0000000000000000 RBX: ffffffff866ed740 RCX: 0000000000000006
[  125.158155] RDX: 0000000000000007 RSI: 0000000000000082 RDI: ffff8b22fac164b0
[  125.158205] RBP: ffffab89c06975d8 R08: 00000000000006a2 R09: 0000000000000004
[  125.158254] R10: 0000000000000000 R11: 0000000000000001 R12: ffffab89c0697738
[  125.158303] R13: ffff8b23405e4500 R14: 0000000000000000 R15: ffffab89c0697738
[  125.158355]  ex_handler_refcount+0x52/0x80
[  125.158389]  fixup_exception+0x3a/0x50
[  125.158420]  do_trap+0x8a/0x140
[  125.158449]  do_error_trap+0xba/0x160
[  125.158481]  ? csum_partial_copy_generic+0x1f6c/0x2b30
[  125.158521]  do_invalid_op+0x20/0x30
[  125.158552]  invalid_op+0x14/0x20
[  125.158581] RIP: 0010:inet_reqsk_alloc+0x115/0x130
[  125.158617] Code: 5d c3 85 c0 74 29 89 c2 8d 48 01 c1 e8 1f 81 fa ff ff ff 7f 41 0f 94 c0 41 08 c0 75 08 39 d1 0f 8d 5a ff ff ff e9 00 7a 0e 00 <e9> 60 ff ff ff 49 8b 7c 24 08 e8 1c 5e 96 ff 31 f6 eb bb 0f 1f 84 
[  125.158753] RSP: 0018:ffffab89c06977e8 EFLAGS: 00010a12
[  125.158792] RAX: ffff8b22efd1e730 RBX: ffff8b22fa7e3180 RCX: ffff8b22fa7e3200
[  125.158841] RDX: 00000000c0000000 RSI: ffff8b22efd1e730 RDI: ffff8b22fa7e3200
[  125.158889] RBP: ffffab89c0697800 R08: ffff8b22fac2a5d0 R09: 0000000000000000
[  125.158938] R10: ffffab89c0697940 R11: 0000000000000000 R12: ffffffff86c90a60
[  125.158986] R13: 0000000000000001 R14: ffff8b2275466000 R15: ffff8b22ed373b62
[  125.159036]  ? inet_reqsk_alloc+0x25/0x130
[  125.159070]  tcp_conn_request+0x1a6/0xc60
[  125.159103]  ? do_invalid_op+0x20/0x30
[  125.159134]  ? invalid_op+0x14/0x20
[  125.159165]  tcp_v4_conn_request+0x51/0x60
[  125.159198]  ? tcp_v4_conn_request+0x51/0x60
[  125.159233]  tcp_rcv_state_process+0x45a/0xe90
[  125.159268]  ? security_sock_rcv_skb+0x2f/0x50
[  125.159304]  tcp_v4_do_rcv+0x111/0x1c0
[  125.159336]  ? tcp_v4_do_rcv+0x111/0x1c0
[  125.159368]  tcp_v4_rcv+0xa77/0xae0
[  125.159399]  ip_local_deliver_finish+0x62/0x200
[  125.159435]  ip_local_deliver+0xdf/0xf0
[  125.159467]  ? ip_rcv_finish+0x420/0x420
[  125.159499]  ip_rcv_finish+0x126/0x420
[  125.159531]  ip_rcv+0x28f/0x360
[  125.159559]  ? inet_del_offload+0x40/0x40
[  125.159593]  __netif_receive_skb_core+0x48c/0xb70
[  125.159630]  ? ktime_get+0x43/0xa0
[  125.159708]  ? tcp4_gro_receive+0x137/0x1a0
[  125.159753]  __netif_receive_skb+0x18/0x60
[  125.159794]  ? __netif_receive_skb+0x18/0x60
[  125.159826]  netif_receive_skb_internal+0x45/0xe0
[  125.159857]  napi_gro_receive+0xc5/0xf0
[  125.159887]  e1000_clean_rx_irq+0x197/0x520 [e1000]
[  125.159921]  e1000_clean+0x27d/0x890 [e1000]
[  125.159953]  ? __switch_to_asm+0x34/0x70
[  125.159989]  net_rx_action+0x140/0x3a0
[  125.160025]  ? __switch_to_asm+0x34/0x70
[  125.160055]  __do_softirq+0xe4/0x2d4
[  125.160083]  run_ksoftirqd+0x2b/0x40
[  125.160109]  smpboot_thread_fn+0xfc/0x170
[  125.160138]  kthread+0x121/0x140
[  125.160162]  ? sort_range+0x30/0x30
[  125.160188]  ? kthread_create_worker_on_cpu+0x70/0x70
[  125.160221]  ret_from_fork+0x35/0x40

 

1.crash定位是refcount引用计数的问题;

2.查看源码,

i.4.18.0-15-generic内核__inet_lookup_listener实现

struct sock *__inet_lookup_listener(struct net *net,
				    struct inet_hashinfo *hashinfo,
				    struct sk_buff *skb, int doff,
				    const __be32 saddr, __be16 sport,
				    const __be32 daddr, const unsigned short hnum,
				    const int dif, const int sdif)
{
	unsigned int hash = inet_lhashfn(net, hnum);
	struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
	bool exact_dif = inet_exact_dif_match(net, skb);
	struct inet_listen_hashbucket *ilb2;
	struct sock *sk, *result = NULL;
	int score, hiscore = 0;
	unsigned int hash2;
	u32 phash = 0;

	if (ilb->count <= 10 || !hashinfo->lhash2)
		goto port_lookup;

	/* Too many sk in the ilb bucket (which is hashed by port alone).
	 * Try lhash2 (which is hashed by port and addr) instead.
	 */

	hash2 = ipv4_portaddr_hash(net, daddr, hnum);
	ilb2 = inet_lhash2_bucket(hashinfo, hash2);
	if (ilb2->count > ilb->count)
		goto port_lookup;

	result = inet_lhash2_lookup(net, ilb2, skb, doff,
				    saddr, sport, daddr, hnum,
				    dif, sdif);
	if (result)
		return result;

	/* Lookup lhash2 with INADDR_ANY */

	hash2 = ipv4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
	ilb2 = inet_lhash2_bucket(hashinfo, hash2);
	if (ilb2->count > ilb->count)
		goto port_lookup;

	return inet_lhash2_lookup(net, ilb2, skb, doff,
				  saddr, sport, daddr, hnum,
				  dif, sdif);

port_lookup:
	sk_for_each_rcu(sk, &ilb->head) {
		score = compute_score(sk, net, hnum, daddr,
				      dif, sdif, exact_dif);
		if (score > hiscore) {
			if (sk->sk_reuseport) {
				phash = inet_ehashfn(net, daddr, hnum,
						     saddr, sport);
				result = reuseport_select_sock(sk, phash,
							       skb, doff);
				if (result)
					return result;
			}
			result = sk;
			hiscore = score;
		}
	}
	return result;
}

ii.3.10.0内核源码中__inet_lookup_listener实现

struct sock *__inet_lookup_listener(struct net *net,
				    struct inet_hashinfo *hashinfo,
				    const __be32 saddr, __be16 sport,
				    const __be32 daddr, const unsigned short hnum,
				    const int dif)
{
	struct sock *sk, *result;
	struct hlist_nulls_node *node;
	unsigned int hash = inet_lhashfn(net, hnum);
	struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
	int score, hiscore, matches = 0, reuseport = 0;
	u32 phash = 0;

	rcu_read_lock();
begin:
	result = NULL;
	hiscore = 0;
	sk_nulls_for_each_rcu(sk, node, &ilb->head) {
		score = compute_score(sk, net, hnum, daddr, dif);
		if (score > hiscore) {
			result = sk;
			hiscore = score;
			reuseport = sk->sk_reuseport;
			if (reuseport) {
				phash = inet_ehashfn(net, daddr, hnum,
						     saddr, sport);
				matches = 1;
			}
		} else if (score == hiscore && reuseport) {
			matches++;
			if (((u64)phash * matches) >> 32 == 0)
				result = sk;
			phash = next_pseudo_random32(phash);
		}
	}
	/*
	 * if the nulls value we got at the end of this lookup is
	 * not the expected one, we must restart lookup.
	 * We probably met an item that was moved to another chain.
	 */
	if (get_nulls_value(node) != hash + LISTENING_NULLS_BASE)
		goto begin;
	if (result) {
		if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
			result = NULL;
		else if (unlikely(compute_score(result, net, hnum, daddr,
				  dif) < hiscore)) {
			sock_put(result);
			goto begin;
		}
	}
	rcu_read_unlock();
	return result;
}

 

3.分析原因:

3.10.0内核代码__inet_lookup_listener实现中查找到sock会进行引用加1,“if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))”,但是新内核代码中已经去掉了引用加.

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pengcheng123456/article/details/97494586

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法