cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gdbmacros.txt (8793B)


      1#
      2# This file contains a few gdb macros (user defined commands) to extract
      3# useful information from kernel crashdump (kdump) like stack traces of
      4# all the processes or a particular process and trapinfo.
      5#
      6# These macros can be used by copying this file in .gdbinit (put in home
      7# directory or current directory) or by invoking gdb command with
      8# --command=<command-file-name> option
      9#
     10# Credits:
     11# Alexander Nyberg <alexn@telia.com>
     12# V Srivatsa <vatsa@in.ibm.com>
     13# Maneesh Soni <maneesh@in.ibm.com>
     14#
     15
     16define bttnobp
     17	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
     18	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
     19	set $init_t=&init_task
     20	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
     21	set var $stacksize = sizeof(union thread_union)
     22	while ($next_t != $init_t)
     23		set $next_t=(struct task_struct *)$next_t
     24		printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
     25		printf "===================\n"
     26		set var $stackp = $next_t.thread.sp
     27		set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
     28
     29		while ($stackp < $stack_top)
     30			if (*($stackp) > _stext && *($stackp) < _sinittext)
     31				info symbol *($stackp)
     32			end
     33			set $stackp += 4
     34		end
     35		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
     36		while ($next_th != $next_t)
     37			set $next_th=(struct task_struct *)$next_th
     38			printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
     39			printf "===================\n"
     40			set var $stackp = $next_t.thread.sp
     41			set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize
     42
     43			while ($stackp < $stack_top)
     44				if (*($stackp) > _stext && *($stackp) < _sinittext)
     45					info symbol *($stackp)
     46				end
     47				set $stackp += 4
     48			end
     49			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
     50		end
     51		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
     52	end
     53end
     54document bttnobp
     55	dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
     56end
     57
     58define btthreadstack
     59	set var $pid_task = $arg0
     60
     61	printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
     62	printf "task struct: "
     63	print $pid_task
     64	printf "===================\n"
     65	set var $stackp = $pid_task.thread.sp
     66	set var $stacksize = sizeof(union thread_union)
     67	set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
     68	set var $stack_bot = ($stackp & ~($stacksize - 1))
     69
     70	set $stackp = *((unsigned long *) $stackp)
     71	while (($stackp < $stack_top) && ($stackp > $stack_bot))
     72		set var $addr = *(((unsigned long *) $stackp) + 1)
     73		info symbol $addr
     74		set $stackp = *((unsigned long *) $stackp)
     75	end
     76end
     77document btthreadstack
     78	 dump a thread stack using the given task structure pointer
     79end
     80
     81
     82define btt
     83	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
     84	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
     85	set $init_t=&init_task
     86	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
     87	while ($next_t != $init_t)
     88		set $next_t=(struct task_struct *)$next_t
     89		btthreadstack $next_t
     90
     91		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
     92		while ($next_th != $next_t)
     93			set $next_th=(struct task_struct *)$next_th
     94			btthreadstack $next_th
     95			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
     96		end
     97		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
     98	end
     99end
    100document btt
    101	dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
    102end
    103
    104define btpid
    105	set var $pid = $arg0
    106	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
    107	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
    108	set $init_t=&init_task
    109	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
    110	set var $pid_task = 0
    111
    112	while ($next_t != $init_t)
    113		set $next_t=(struct task_struct *)$next_t
    114
    115		if ($next_t.pid == $pid)
    116			set $pid_task = $next_t
    117		end
    118
    119		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
    120		while ($next_th != $next_t)
    121			set $next_th=(struct task_struct *)$next_th
    122			if ($next_th.pid == $pid)
    123				set $pid_task = $next_th
    124			end
    125			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
    126		end
    127		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
    128	end
    129
    130	btthreadstack $pid_task
    131end
    132document btpid
    133	backtrace of pid
    134end
    135
    136
    137define trapinfo
    138	set var $pid = $arg0
    139	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
    140	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
    141	set $init_t=&init_task
    142	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
    143	set var $pid_task = 0
    144
    145	while ($next_t != $init_t)
    146		set $next_t=(struct task_struct *)$next_t
    147
    148		if ($next_t.pid == $pid)
    149			set $pid_task = $next_t
    150		end
    151
    152		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
    153		while ($next_th != $next_t)
    154			set $next_th=(struct task_struct *)$next_th
    155			if ($next_th.pid == $pid)
    156				set $pid_task = $next_th
    157			end
    158			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
    159		end
    160		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
    161	end
    162
    163	printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
    164				$pid_task.thread.cr2, $pid_task.thread.error_code
    165
    166end
    167document trapinfo
    168	Run info threads and lookup pid of thread #1
    169	'trapinfo <pid>' will tell you by which trap & possibly
    170	address the kernel panicked.
    171end
    172
    173define dump_record
    174	set var $desc = $arg0
    175	set var $info = $arg1
    176	if ($argc > 2)
    177		set var $prev_flags = $arg2
    178	else
    179		set var $prev_flags = 0
    180	end
    181
    182	set var $prefix = 1
    183	set var $newline = 1
    184
    185	set var $begin = $desc->text_blk_lpos.begin % (1U << prb->text_data_ring.size_bits)
    186	set var $next = $desc->text_blk_lpos.next % (1U << prb->text_data_ring.size_bits)
    187
    188	# handle data-less record
    189	if ($begin & 1)
    190		set var $text_len = 0
    191		set var $log = ""
    192	else
    193		# handle wrapping data block
    194		if ($begin > $next)
    195			set var $begin = 0
    196		end
    197
    198		# skip over descriptor id
    199		set var $begin = $begin + sizeof(long)
    200
    201		# handle truncated message
    202		if ($next - $begin < $info->text_len)
    203			set var $text_len = $next - $begin
    204		else
    205			set var $text_len = $info->text_len
    206		end
    207
    208		set var $log = &prb->text_data_ring.data[$begin]
    209	end
    210
    211	# prev & LOG_CONT && !(info->flags & LOG_PREIX)
    212	if (($prev_flags & 8) && !($info->flags & 4))
    213		set var $prefix = 0
    214	end
    215
    216	# info->flags & LOG_CONT
    217	if ($info->flags & 8)
    218		# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
    219		if (($prev_flags & 8) && !($prev_flags & 2))
    220			set var $prefix = 0
    221		end
    222		# (!(info->flags & LOG_NEWLINE))
    223		if (!($info->flags & 2))
    224			set var $newline = 0
    225		end
    226	end
    227
    228	if ($prefix)
    229		printf "[%5lu.%06lu] ", $info->ts_nsec / 1000000000, $info->ts_nsec % 1000000000
    230	end
    231	if ($text_len)
    232		eval "printf \"%%%d.%ds\", $log", $text_len, $text_len
    233	end
    234	if ($newline)
    235		printf "\n"
    236	end
    237
    238	# handle dictionary data
    239
    240	set var $dict = &$info->dev_info.subsystem[0]
    241	set var $dict_len = sizeof($info->dev_info.subsystem)
    242	if ($dict[0] != '\0')
    243		printf " SUBSYSTEM="
    244		set var $idx = 0
    245		while ($idx < $dict_len)
    246			set var $c = $dict[$idx]
    247			if ($c == '\0')
    248				loop_break
    249			else
    250				if ($c < ' ' || $c >= 127 || $c == '\\')
    251					printf "\\x%02x", $c
    252				else
    253					printf "%c", $c
    254				end
    255			end
    256			set var $idx = $idx + 1
    257		end
    258		printf "\n"
    259	end
    260
    261	set var $dict = &$info->dev_info.device[0]
    262	set var $dict_len = sizeof($info->dev_info.device)
    263	if ($dict[0] != '\0')
    264		printf " DEVICE="
    265		set var $idx = 0
    266		while ($idx < $dict_len)
    267			set var $c = $dict[$idx]
    268			if ($c == '\0')
    269				loop_break
    270			else
    271				if ($c < ' ' || $c >= 127 || $c == '\\')
    272					printf "\\x%02x", $c
    273				else
    274					printf "%c", $c
    275				end
    276			end
    277			set var $idx = $idx + 1
    278		end
    279		printf "\n"
    280	end
    281end
    282document dump_record
    283	Dump a single record. The first parameter is the descriptor,
    284	the second parameter is the info, the third parameter is
    285	optional and specifies the previous record's flags, used for
    286	properly formatting continued lines.
    287end
    288
    289define dmesg
    290	# definitions from kernel/printk/printk_ringbuffer.h
    291	set var $desc_committed = 1
    292	set var $desc_finalized = 2
    293	set var $desc_sv_bits = sizeof(long) * 8
    294	set var $desc_flags_shift = $desc_sv_bits - 2
    295	set var $desc_flags_mask = 3 << $desc_flags_shift
    296	set var $id_mask = ~$desc_flags_mask
    297
    298	set var $desc_count = 1U << prb->desc_ring.count_bits
    299	set var $prev_flags = 0
    300
    301	set var $id = prb->desc_ring.tail_id.counter
    302	set var $end_id = prb->desc_ring.head_id.counter
    303
    304	while (1)
    305		set var $desc = &prb->desc_ring.descs[$id % $desc_count]
    306		set var $info = &prb->desc_ring.infos[$id % $desc_count]
    307
    308		# skip non-committed record
    309		set var $state = 3 & ($desc->state_var.counter >> $desc_flags_shift)
    310		if ($state == $desc_committed || $state == $desc_finalized)
    311			dump_record $desc $info $prev_flags
    312			set var $prev_flags = $info->flags
    313		end
    314
    315		set var $id = ($id + 1) & $id_mask
    316		if ($id == $end_id)
    317			loop_break
    318		end
    319	end
    320end
    321document dmesg
    322	print the kernel ring buffer
    323end