forked from Minki/linux
s390/docs: Break long lines in Debugging390.txt
There are a lot of lines that are longer than 80 columns in this file, rendering it hard to read in a terminal window. This patch fixes most of these long lines, and while we're at it, also makes some sentences more readable, e.g. by replacing "&" with "and", adding proper punctuation, removing superfluous clauses, etc. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
d97d929f06
commit
bae2a3cc4f
@ -1,14 +1,14 @@
|
||||
|
||||
Debugging on Linux for s/390 & z/Architecture
|
||||
by
|
||||
Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
|
||||
Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
|
||||
Best viewed with fixed width fonts
|
||||
|
||||
Debugging on Linux for s/390 & z/Architecture
|
||||
by
|
||||
Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
|
||||
Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
|
||||
Best viewed with fixed width fonts
|
||||
|
||||
Overview of Document:
|
||||
=====================
|
||||
This document is intended to give a good overview of how to debug
|
||||
Linux for s/390 & z/Architecture. It isn't intended as a complete reference & not a
|
||||
This document is intended to give a good overview of how to debug Linux for
|
||||
s/390 and z/Architecture. It is not intended as a complete reference and not a
|
||||
tutorial on the fundamentals of C & assembly. It doesn't go into
|
||||
390 IO in any detail. It is intended to complement the documents in the
|
||||
reference section below & any other worthwhile references you get.
|
||||
@ -44,18 +44,20 @@ Register Set
|
||||
============
|
||||
The current architectures have the following registers.
|
||||
|
||||
16 General propose registers, 32 bit on s/390 64 bit on z/Architecture, r0-r15 or gpr0-gpr15 used for arithmetic & addressing.
|
||||
16 General propose registers, 32 bit on s/390 and 64 bit on z/Architecture,
|
||||
r0-r15 (or gpr0-gpr15), used for arithmetic and addressing.
|
||||
|
||||
16 Control registers, 32 bit on s/390 64 bit on z/Architecture, ( cr0-cr15 kernel usage only ) used for memory management,
|
||||
interrupt control,debugging control etc.
|
||||
16 Control registers, 32 bit on s/390 and 64 bit on z/Architecture, cr0-cr15,
|
||||
kernel usage only, used for memory management, interrupt control, debugging
|
||||
control etc.
|
||||
|
||||
16 Access registers ( ar0-ar15 ) 32 bit on s/390 & z/Architecture
|
||||
not used by normal programs but potentially could
|
||||
be used as temporary storage. Their main purpose is their 1 to 1
|
||||
association with general purpose registers and are used in
|
||||
the kernel for copying data between kernel & user address spaces.
|
||||
Access register 0 ( & access register 1 on z/Architecture ( needs 64 bit
|
||||
pointer ) ) is currently used by the pthread library as a pointer to
|
||||
16 Access registers (ar0-ar15), 32 bit on both s/390 and z/Architecture,
|
||||
normally not used by normal programs but potentially could be used as
|
||||
temporary storage. These registers have a 1:1 association with general
|
||||
purpose registers and are designed to be used in the so-called access
|
||||
register mode to select different address spaces.
|
||||
Access register 0 (and access register 1 on z/Architecture, which needs a
|
||||
64 bit pointer) is currently used by the pthread library as a pointer to
|
||||
the current running threads private area.
|
||||
|
||||
16 64 bit floating point registers (fp0-fp15 ) IEEE & HFP floating
|
||||
@ -90,18 +92,19 @@ s/390 z/Architecture
|
||||
|
||||
6 6 Input/Output interrupt Mask
|
||||
|
||||
7 7 External interrupt Mask used primarily for interprocessor signalling &
|
||||
clock interrupts.
|
||||
7 7 External interrupt Mask used primarily for interprocessor
|
||||
signalling and clock interrupts.
|
||||
|
||||
8-11 8-11 PSW Key used for complex memory protection mechanism not used under linux
|
||||
8-11 8-11 PSW Key used for complex memory protection mechanism
|
||||
(not used under linux)
|
||||
|
||||
12 12 1 on s/390 0 on z/Architecture
|
||||
|
||||
13 13 Machine Check Mask 1=enable machine check interrupts
|
||||
|
||||
14 14 Wait State set this to 1 to stop the processor except for interrupts & give
|
||||
time to other LPARS used in CPU idle in the kernel to increase overall
|
||||
usage of processor resources.
|
||||
14 14 Wait State. Set this to 1 to stop the processor except for
|
||||
interrupts and give time to other LPARS. Used in CPU idle in
|
||||
the kernel to increase overall usage of processor resources.
|
||||
|
||||
15 15 Problem state ( if set to 1 certain instructions are disabled )
|
||||
all linux user programs run with this bit 1
|
||||
@ -165,21 +168,23 @@ s/390 z/Architecture
|
||||
when loading the address with LPSWE otherwise a
|
||||
specification exception occurs, LPSW is fully backward
|
||||
compatible.
|
||||
|
||||
|
||||
|
||||
|
||||
Prefix Page(s)
|
||||
--------------
|
||||
--------------
|
||||
This per cpu memory area is too intimately tied to the processor not to mention.
|
||||
It exists between the real addresses 0-4096 on s/390 & 0-8192 z/Architecture & is exchanged
|
||||
with a 1 page on s/390 or 2 pages on z/Architecture in absolute storage by the set
|
||||
prefix instruction in linux'es startup.
|
||||
This page is mapped to a different prefix for each processor in an SMP configuration
|
||||
( assuming the os designer is sane of course :-) ).
|
||||
Bytes 0-512 ( 200 hex ) on s/390 & 0-512,4096-4544,4604-5119 currently on z/Architecture
|
||||
are used by the processor itself for holding such information as exception indications &
|
||||
entry points for exceptions.
|
||||
Bytes after 0xc00 hex are used by linux for per processor globals on s/390 & z/Architecture
|
||||
( there is a gap on z/Architecture too currently between 0xc00 & 1000 which linux uses ).
|
||||
It exists between the real addresses 0-4096 on s/390 and between 0-8192 on
|
||||
z/Architecture and is exchanged with one page on s/390 or two pages on
|
||||
z/Architecture in absolute storage by the set prefix instruction during Linux
|
||||
startup.
|
||||
This page is mapped to a different prefix for each processor in an SMP
|
||||
configuration (assuming the OS designer is sane of course).
|
||||
Bytes 0-512 (200 hex) on s/390 and 0-512, 4096-4544, 4604-5119 currently on
|
||||
z/Architecture are used by the processor itself for holding such information
|
||||
as exception indications and entry points for exceptions.
|
||||
Bytes after 0xc00 hex are used by linux for per processor globals on s/390 and
|
||||
z/Architecture (there is a gap on z/Architecture currently between 0xc00 and
|
||||
0x1000, too, which is used by Linux).
|
||||
The closest thing to this on traditional architectures is the interrupt
|
||||
vector table. This is a good thing & does simplify some of the kernel coding
|
||||
however it means that we now cannot catch stray NULL pointers in the
|
||||
@ -192,26 +197,26 @@ Address Spaces on Intel Linux
|
||||
|
||||
The traditional Intel Linux is approximately mapped as follows forgive
|
||||
the ascii art.
|
||||
0xFFFFFFFF 4GB Himem *****************
|
||||
* *
|
||||
* Kernel Space *
|
||||
* *
|
||||
***************** ****************
|
||||
User Space Himem (typically 0xC0000000 3GB )* User Stack * * *
|
||||
***************** * *
|
||||
* Shared Libs * * Next Process *
|
||||
***************** * to *
|
||||
* * <== * Run * <==
|
||||
* User Program * * *
|
||||
* Data BSS * * *
|
||||
* Text * * *
|
||||
* Sections * * *
|
||||
0x00000000 ***************** ****************
|
||||
0xFFFFFFFF 4GB Himem *****************
|
||||
* *
|
||||
* Kernel Space *
|
||||
* *
|
||||
***************** ****************
|
||||
User Space Himem * User Stack * * *
|
||||
(typically 0xC0000000 3GB ) ***************** * *
|
||||
* Shared Libs * * Next Process *
|
||||
***************** * to *
|
||||
* * <== * Run * <==
|
||||
* User Program * * *
|
||||
* Data BSS * * *
|
||||
* Text * * *
|
||||
* Sections * * *
|
||||
0x00000000 ***************** ****************
|
||||
|
||||
Now it is easy to see that on Intel it is quite easy to recognise a kernel address
|
||||
as being one greater than user space himem ( in this case 0xC0000000).
|
||||
& addresses of less than this are the ones in the current running program on this
|
||||
processor ( if an smp box ).
|
||||
Now it is easy to see that on Intel it is quite easy to recognise a kernel
|
||||
address as being one greater than user space himem (in this case 0xC0000000),
|
||||
and addresses of less than this are the ones in the current running program on
|
||||
this processor (if an smp box).
|
||||
If using the virtual machine ( VM ) as a debugger it is quite difficult to
|
||||
know which user process is running as the address space you are looking at
|
||||
could be from any process in the run queue.
|
||||
@ -247,8 +252,8 @@ Our addressing scheme is basically as follows:
|
||||
Himem 0x7fffffff 2GB on s/390 ***************** ****************
|
||||
currently 0x3ffffffffff (2^42)-1 * User Stack * * *
|
||||
on z/Architecture. ***************** * *
|
||||
* Shared Libs * * *
|
||||
***************** * *
|
||||
* Shared Libs * * *
|
||||
***************** * *
|
||||
* * * Kernel *
|
||||
* User Program * * *
|
||||
* Data BSS * * *
|
||||
@ -301,10 +306,10 @@ Virtual Addresses on s/390 & z/Architecture
|
||||
===========================================
|
||||
|
||||
A virtual address on s/390 is made up of 3 parts
|
||||
The SX ( segment index, roughly corresponding to the PGD & PMD in linux terminology )
|
||||
being bits 1-11.
|
||||
The PX ( page index, corresponding to the page table entry (pte) in linux terminology )
|
||||
being bits 12-19.
|
||||
The SX (segment index, roughly corresponding to the PGD & PMD in Linux
|
||||
terminology) being bits 1-11.
|
||||
The PX (page index, corresponding to the page table entry (pte) in Linux
|
||||
terminology) being bits 12-19.
|
||||
The remaining bits BX (the byte index are the offset in the page )
|
||||
i.e. bits 20 to 31.
|
||||
|
||||
@ -368,9 +373,9 @@ each processor as follows.
|
||||
* ( 8K ) *
|
||||
16K aligned ************************
|
||||
|
||||
What this means is that we don't need to dedicate any register or global variable
|
||||
to point to the current running process & can retrieve it with the following
|
||||
very simple construct for s/390 & one very similar for z/Architecture.
|
||||
What this means is that we don't need to dedicate any register or global
|
||||
variable to point to the current running process & can retrieve it with the
|
||||
following very simple construct for s/390 & one very similar for z/Architecture.
|
||||
|
||||
static inline struct task_struct * get_current(void)
|
||||
{
|
||||
@ -403,8 +408,8 @@ Note: To follow stackframes requires a knowledge of C or Pascal &
|
||||
limited knowledge of one assembly language.
|
||||
|
||||
It should be noted that there are some differences between the
|
||||
s/390 & z/Architecture stack layouts as the z/Architecture stack layout didn't have
|
||||
to maintain compatibility with older linkage formats.
|
||||
s/390 and z/Architecture stack layouts as the z/Architecture stack layout
|
||||
didn't have to maintain compatibility with older linkage formats.
|
||||
|
||||
Glossary:
|
||||
---------
|
||||
@ -440,7 +445,7 @@ The code generated by the compiler to return to the caller.
|
||||
|
||||
frameless-function
|
||||
A frameless function in Linux for s390 & z/Architecture is one which doesn't
|
||||
need more than the register save area ( 96 bytes on s/390, 160 on z/Architecture )
|
||||
need more than the register save area (96 bytes on s/390, 160 on z/Architecture)
|
||||
given to it by the caller.
|
||||
A frameless function never:
|
||||
1) Sets up a back chain.
|
||||
@ -588,8 +593,8 @@ A sample program with comments.
|
||||
|
||||
Comments on the function test
|
||||
-----------------------------
|
||||
1) It didn't need to set up a pointer to the constant pool gpr13 as it isn't used
|
||||
( :-( ).
|
||||
1) It didn't need to set up a pointer to the constant pool gpr13 as it is not
|
||||
used ( :-( ).
|
||||
2) This is a frameless function & no stack is bought.
|
||||
3) The compiler was clever enough to recognise that it could return the
|
||||
value in r2 as well as use it for the passed in parameter ( :-) ).
|
||||
@ -743,35 +748,34 @@ Debugging under VM
|
||||
Notes
|
||||
-----
|
||||
Addresses & values in the VM debugger are always hex never decimal
|
||||
Address ranges are of the format <HexValue1>-<HexValue2> or <HexValue1>.<HexValue2>
|
||||
e.g. The address range 0x2000 to 0x3000 can be described as 2000-3000 or 2000.1000
|
||||
Address ranges are of the format <HexValue1>-<HexValue2> or
|
||||
<HexValue1>.<HexValue2>
|
||||
For example, the address range 0x2000 to 0x3000 can be described as 2000-3000
|
||||
or 2000.1000
|
||||
|
||||
The VM Debugger is case insensitive.
|
||||
|
||||
VM's strengths are usually other debuggers weaknesses you can get at any resource
|
||||
no matter how sensitive e.g. memory management resources,change address translation
|
||||
in the PSW. For kernel hacking you will reap dividends if you get good at it.
|
||||
VM's strengths are usually other debuggers weaknesses you can get at any
|
||||
resource no matter how sensitive e.g. memory management resources, change
|
||||
address translation in the PSW. For kernel hacking you will reap dividends if
|
||||
you get good at it.
|
||||
|
||||
The VM Debugger displays operators but not operands, probably because some
|
||||
of it was written when memory was expensive & the programmer was probably proud that
|
||||
it fitted into 2k of memory & the programmers & didn't want to shock hardcore VM'ers by
|
||||
changing the interface :-), also the debugger displays useful information on the same line &
|
||||
the author of the code probably felt that it was a good idea not to go over
|
||||
the 80 columns on the screen.
|
||||
|
||||
As some of you are probably in a panic now this isn't as unintuitive as it may seem
|
||||
as the 390 instructions are easy to decode mentally & you can make a good guess at a lot
|
||||
of them as all the operands are nibble ( half byte aligned ) & if you have an objdump listing
|
||||
also it is quite easy to follow, if you don't have an objdump listing keep a copy of
|
||||
the s/390 Reference Summary & look at between pages 2 & 7 or alternatively the
|
||||
s/390 principles of operation.
|
||||
The VM Debugger displays operators but not operands, and also the debugger
|
||||
displays useful information on the same line as the author of the code probably
|
||||
felt that it was a good idea not to go over the 80 columns on the screen.
|
||||
This isn't as unintuitive as it may seem as the s/390 instructions are easy to
|
||||
decode mentally and you can make a good guess at a lot of them as all the
|
||||
operands are nibble (half byte aligned).
|
||||
So if you have an objdump listing by hand, it is quite easy to follow, and if
|
||||
you don't have an objdump listing keep a copy of the s/390 Reference Summary
|
||||
or alternatively the s/390 principles of operation next to you.
|
||||
e.g. even I can guess that
|
||||
0001AFF8' LR 180F CC 0
|
||||
is a ( load register ) lr r0,r15
|
||||
|
||||
Also it is very easy to tell the length of a 390 instruction from the 2 most significant
|
||||
bits in the instruction ( not that this info is really useful except if you are trying to
|
||||
make sense of a hexdump of code ).
|
||||
Also it is very easy to tell the length of a 390 instruction from the 2 most
|
||||
significant bits in the instruction (not that this info is really useful except
|
||||
if you are trying to make sense of a hexdump of code).
|
||||
Here is a table
|
||||
Bits Instruction Length
|
||||
------------------------------------------
|
||||
@ -780,9 +784,6 @@ Bits Instruction Length
|
||||
10 4 Bytes
|
||||
11 6 Bytes
|
||||
|
||||
|
||||
|
||||
|
||||
The debugger also displays other useful info on the same line such as the
|
||||
addresses being operated on destination addresses of branches & condition codes.
|
||||
e.g.
|
||||
@ -853,8 +854,8 @@ Displaying & modifying Registers
|
||||
--------------------------------
|
||||
D G will display all the gprs
|
||||
Adding a extra G to all the commands is necessary to access the full 64 bit
|
||||
content in VM on z/Architecture obviously this isn't required for access registers
|
||||
as these are still 32 bit.
|
||||
content in VM on z/Architecture. Obviously this isn't required for access
|
||||
registers as these are still 32 bit.
|
||||
e.g. DGG instead of DG
|
||||
D X will display all the control registers
|
||||
D AR will display all the access registers
|
||||
@ -870,10 +871,11 @@ Displaying Memory
|
||||
-----------------
|
||||
To display memory mapped using the current PSW's mapping try
|
||||
D <range>
|
||||
To make VM display a message each time it hits a particular address & continue try
|
||||
To make VM display a message each time it hits a particular address and
|
||||
continue try
|
||||
D I<range> will disassemble/display a range of instructions.
|
||||
ST addr 32 bit word will store a 32 bit aligned address
|
||||
D T<range> will display the EBCDIC in an address ( if you are that way inclined )
|
||||
D T<range> will display the EBCDIC in an address (if you are that way inclined)
|
||||
D R<range> will display real addresses ( without DAT ) but with prefixing.
|
||||
There are other complex options to display if you need to get at say home space
|
||||
but are in primary space the easiest thing to do is to temporarily
|
||||
@ -884,8 +886,8 @@ restore it.
|
||||
|
||||
Hints
|
||||
-----
|
||||
If you want to issue a debugger command without halting your virtual machine with the
|
||||
PA1 key try prefixing the command with #CP e.g.
|
||||
If you want to issue a debugger command without halting your virtual machine
|
||||
with the PA1 key try prefixing the command with #CP e.g.
|
||||
#cp tr i pswa 2000
|
||||
also suffixing most debugger commands with RUN will cause them not
|
||||
to stop just display the mnemonic at the current instruction on the console.
|
||||
@ -903,9 +905,10 @@ This sends a message to your own console each time do_signal is entered.
|
||||
script with breakpoints on every kernel procedure, this isn't a good idea
|
||||
because there are thousands of these routines & VM can only set 255 breakpoints
|
||||
at a time so you nearly had to spend as long pruning the file down as you would
|
||||
entering the msg's by hand ),however, the trick might be useful for a single object file.
|
||||
On linux'es 3270 emulator x3270 there is a very useful option under the file ment
|
||||
Save Screens In File this is very good of keeping a copy of traces.
|
||||
entering the msgs by hand), however, the trick might be useful for a single
|
||||
object file. In the 3270 terminal emulator x3270 there is a very useful option
|
||||
in the file menu called "Save Screen In File" - this is very good for keeping a
|
||||
copy of traces.
|
||||
|
||||
From CMS help <command name> will give you online help on a particular command.
|
||||
e.g.
|
||||
@ -920,7 +923,8 @@ SET PF9 IMM B
|
||||
This does a single step in VM on pressing F8.
|
||||
SET PF10 ^
|
||||
This sets up the ^ key.
|
||||
which can be used for ^c (ctrl-c),^z (ctrl-z) which can't be typed directly into some 3270 consoles.
|
||||
which can be used for ^c (ctrl-c),^z (ctrl-z) which can't be typed directly
|
||||
into some 3270 consoles.
|
||||
SET PF11 ^-
|
||||
This types the starting keystrokes for a sysrq see SysRq below.
|
||||
SET PF12 RETRIEVE
|
||||
@ -1014,8 +1018,8 @@ Tracing Program Exceptions
|
||||
--------------------------
|
||||
If you get a crash which says something like
|
||||
illegal operation or specification exception followed by a register dump
|
||||
You can restart linux & trace these using the tr prog <range or value> trace option.
|
||||
|
||||
You can restart linux & trace these using the tr prog <range or value> trace
|
||||
option.
|
||||
|
||||
|
||||
The most common ones you will normally be tracing for is
|
||||
@ -1057,9 +1061,10 @@ TR GOTO INITIAL
|
||||
|
||||
Tracing linux syscalls under VM
|
||||
-------------------------------
|
||||
Syscalls are implemented on Linux for S390 by the Supervisor call instruction (SVC) there 256
|
||||
possibilities of these as the instruction is made up of a 0xA opcode & the second byte being
|
||||
the syscall number. They are traced using the simple command.
|
||||
Syscalls are implemented on Linux for S390 by the Supervisor call instruction
|
||||
(SVC). There 256 possibilities of these as the instruction is made up of a 0xA
|
||||
opcode and the second byte being the syscall number. They are traced using the
|
||||
simple command:
|
||||
TR SVC <Optional value or range>
|
||||
the syscalls are defined in linux/arch/s390/include/asm/unistd.h
|
||||
e.g. to trace all file opens just do
|
||||
@ -1070,12 +1075,12 @@ SMP Specific commands
|
||||
---------------------
|
||||
To find out how many cpus you have
|
||||
Q CPUS displays all the CPU's available to your virtual machine
|
||||
To find the cpu that the current cpu VM debugger commands are being directed at do
|
||||
Q CPU to change the current cpu VM debugger commands are being directed at do
|
||||
To find the cpu that the current cpu VM debugger commands are being directed at
|
||||
do Q CPU to change the current cpu VM debugger commands are being directed at do
|
||||
CPU <desired cpu no>
|
||||
|
||||
On a SMP guest issue a command to all CPUs try prefixing the command with cpu all.
|
||||
To issue a command to a particular cpu try cpu <cpu number> e.g.
|
||||
On a SMP guest issue a command to all CPUs try prefixing the command with cpu
|
||||
all. To issue a command to a particular cpu try cpu <cpu number> e.g.
|
||||
CPU 01 TR I R 2000.3000
|
||||
If you are running on a guest with several cpus & you have a IO related problem
|
||||
& cannot follow the flow of code but you know it isn't smp related.
|
||||
@ -1101,10 +1106,10 @@ D TX0.100
|
||||
|
||||
Alternatively
|
||||
=============
|
||||
Under older VM debuggers ( I love EBDIC too ) you can use this little program I wrote which
|
||||
will convert a command line of hex digits to ascii text which can be compiled under linux &
|
||||
you can copy the hex digits from your x3270 terminal to your xterm if you are debugging
|
||||
from a linuxbox.
|
||||
Under older VM debuggers (I love EBDIC too) you can use following little
|
||||
program which converts a command line of hex digits to ascii text. It can be
|
||||
compiled under linux and you can copy the hex digits from your x3270 terminal
|
||||
to your xterm if you are debugging from a linuxbox.
|
||||
|
||||
This is quite useful when looking at a parameter passed in as a text string
|
||||
under VM ( unless you are good at decoding ASCII in your head ).
|
||||
@ -1114,14 +1119,14 @@ TR SVC 5
|
||||
We have stopped at a breakpoint
|
||||
000151B0' SVC 0A05 -> 0001909A' CC 0
|
||||
|
||||
D 20.8 to check the SVC old psw in the prefix area & see was it from userspace
|
||||
( for the layout of the prefix area consult P18 of the s/390 390 Reference Summary
|
||||
if you have it available ).
|
||||
D 20.8 to check the SVC old psw in the prefix area and see was it from userspace
|
||||
(for the layout of the prefix area consult the "Fixed Storage Locations"
|
||||
chapter of the s/390 Reference Summary if you have it available).
|
||||
V00000020 070C2000 800151B2
|
||||
The problem state bit wasn't set & it's also too early in the boot sequence
|
||||
for it to be a userspace SVC if it was we would have to temporarily switch the
|
||||
psw to user space addressing so we could get at the first parameter of the open in
|
||||
gpr2.
|
||||
psw to user space addressing so we could get at the first parameter of the open
|
||||
in gpr2.
|
||||
Next do a
|
||||
D G2
|
||||
GPR 2 = 00014CB4
|
||||
@ -1208,9 +1213,9 @@ Here are the tricks I use 9 out of 10 times it works pretty well,
|
||||
|
||||
When your backchain reaches a dead end
|
||||
--------------------------------------
|
||||
This can happen when an exception happens in the kernel & the kernel is entered twice
|
||||
if you reach the NULL pointer at the end of the back chain you should be
|
||||
able to sniff further back if you follow the following tricks.
|
||||
This can happen when an exception happens in the kernel and the kernel is
|
||||
entered twice. If you reach the NULL pointer at the end of the back chain you
|
||||
should be able to sniff further back if you follow the following tricks.
|
||||
1) A kernel address should be easy to recognise since it is in
|
||||
primary space & the problem state bit isn't set & also
|
||||
The Hi bit of the address is set.
|
||||
@ -1260,8 +1265,8 @@ V000FFFD0 00010400 80010802 8001085A 000FFFA0
|
||||
|
||||
our 3rd return address is 8001085A
|
||||
|
||||
as the 04B52002 looks suspiciously like rubbish it is fair to assume that the kernel entry routines
|
||||
for the sake of optimisation don't set up a backchain.
|
||||
as the 04B52002 looks suspiciously like rubbish it is fair to assume that the
|
||||
kernel entry routines for the sake of optimisation don't set up a backchain.
|
||||
|
||||
now look at System.map to see if the addresses make any sense.
|
||||
|
||||
@ -1289,67 +1294,75 @@ Congrats you've done your first backchain.
|
||||
s/390 & z/Architecture IO Overview
|
||||
==================================
|
||||
|
||||
I am not going to give a course in 390 IO architecture as this would take me quite a
|
||||
while & I'm no expert. Instead I'll give a 390 IO architecture summary for Dummies if you have
|
||||
the s/390 principles of operation available read this instead. If nothing else you may find a few
|
||||
useful keywords in here & be able to use them on a web search engine like altavista to find
|
||||
more useful information.
|
||||
I am not going to give a course in 390 IO architecture as this would take me
|
||||
quite a while and I'm no expert. Instead I'll give a 390 IO architecture
|
||||
summary for Dummies. If you have the s/390 principles of operation available
|
||||
read this instead. If nothing else you may find a few useful keywords in here
|
||||
and be able to use them on a web search engine to find more useful information.
|
||||
|
||||
Unlike other bus architectures modern 390 systems do their IO using mostly
|
||||
fibre optics & devices such as tapes & disks can be shared between several mainframes,
|
||||
also S390 can support up to 65536 devices while a high end PC based system might be choking
|
||||
with around 64. Here is some of the common IO terminology
|
||||
fibre optics and devices such as tapes and disks can be shared between several
|
||||
mainframes. Also S390 can support up to 65536 devices while a high end PC based
|
||||
system might be choking with around 64.
|
||||
|
||||
Here is some of the common IO terminology:
|
||||
|
||||
Subchannel:
|
||||
This is the logical number most IO commands use to talk to an IO device there can be up to
|
||||
0x10000 (65536) of these in a configuration typically there is a few hundred. Under VM
|
||||
for simplicity they are allocated contiguously, however on the native hardware they are not
|
||||
they typically stay consistent between boots provided no new hardware is inserted or removed.
|
||||
Under Linux for 390 we use these as IRQ's & also when issuing an IO command (CLEAR SUBCHANNEL,
|
||||
HALT SUBCHANNEL,MODIFY SUBCHANNEL,RESUME SUBCHANNEL,START SUBCHANNEL,STORE SUBCHANNEL &
|
||||
TEST SUBCHANNEL ) we use this as the ID of the device we wish to talk to, the most
|
||||
important of these instructions are START SUBCHANNEL ( to start IO ), TEST SUBCHANNEL ( to check
|
||||
whether the IO completed successfully ), & HALT SUBCHANNEL ( to kill IO ), a subchannel
|
||||
can have up to 8 channel paths to a device this offers redundancy if one is not available.
|
||||
|
||||
This is the logical number most IO commands use to talk to an IO device. There
|
||||
can be up to 0x10000 (65536) of these in a configuration, typically there are a
|
||||
few hundred. Under VM for simplicity they are allocated contiguously, however
|
||||
on the native hardware they are not. They typically stay consistent between
|
||||
boots provided no new hardware is inserted or removed.
|
||||
Under Linux for s390 we use these as IRQ's and also when issuing an IO command
|
||||
(CLEAR SUBCHANNEL, HALT SUBCHANNEL, MODIFY SUBCHANNEL, RESUME SUBCHANNEL,
|
||||
START SUBCHANNEL, STORE SUBCHANNEL and TEST SUBCHANNEL). We use this as the ID
|
||||
of the device we wish to talk to. The most important of these instructions are
|
||||
START SUBCHANNEL (to start IO), TEST SUBCHANNEL (to check whether the IO
|
||||
completed successfully) and HALT SUBCHANNEL (to kill IO). A subchannel can have
|
||||
up to 8 channel paths to a device, this offers redundancy if one is not
|
||||
available.
|
||||
|
||||
Device Number:
|
||||
This number remains static & Is closely tied to the hardware, there are 65536 of these
|
||||
also they are made up of a CHPID ( Channel Path ID, the most significant 8 bits )
|
||||
& another lsb 8 bits. These remain static even if more devices are inserted or removed
|
||||
from the hardware, there is a 1 to 1 mapping between Subchannels & Device Numbers provided
|
||||
devices aren't inserted or removed.
|
||||
This number remains static and is closely tied to the hardware. There are 65536
|
||||
of these, made up of a CHPID (Channel Path ID, the most significant 8 bits) and
|
||||
another lsb 8 bits. These remain static even if more devices are inserted or
|
||||
removed from the hardware. There is a 1 to 1 mapping between subchannels and
|
||||
device numbers, provided devices aren't inserted or removed.
|
||||
|
||||
Channel Control Words:
|
||||
CCWS are linked lists of instructions initially pointed to by an operation request block (ORB),
|
||||
which is initially given to Start Subchannel (SSCH) command along with the subchannel number
|
||||
for the IO subsystem to process while the CPU continues executing normal code.
|
||||
These come in two flavours, Format 0 ( 24 bit for backward )
|
||||
compatibility & Format 1 ( 31 bit ). These are typically used to issue read & write
|
||||
( & many other instructions ) they consist of a length field & an absolute address field.
|
||||
For each IO typically get 1 or 2 interrupts one for channel end ( primary status ) when the
|
||||
channel is idle & the second for device end ( secondary status ) sometimes you get both
|
||||
concurrently, you check how the IO went on by issuing a TEST SUBCHANNEL at each interrupt,
|
||||
from which you receive an Interruption response block (IRB). If you get channel & device end
|
||||
status in the IRB without channel checks etc. your IO probably went okay. If you didn't you
|
||||
probably need a doctor to examine the IRB & extended status word etc.
|
||||
CCWs are linked lists of instructions initially pointed to by an operation
|
||||
request block (ORB), which is initially given to Start Subchannel (SSCH)
|
||||
command along with the subchannel number for the IO subsystem to process
|
||||
while the CPU continues executing normal code.
|
||||
CCWs come in two flavours, Format 0 (24 bit for backward compatibility) and
|
||||
Format 1 (31 bit). These are typically used to issue read and write (and many
|
||||
other) instructions. They consist of a length field and an absolute address
|
||||
field.
|
||||
Each IO typically gets 1 or 2 interrupts, one for channel end (primary status)
|
||||
when the channel is idle, and the second for device end (secondary status).
|
||||
Sometimes you get both concurrently. You check how the IO went on by issuing a
|
||||
TEST SUBCHANNEL at each interrupt, from which you receive an Interruption
|
||||
response block (IRB). If you get channel and device end status in the IRB
|
||||
without channel checks etc. your IO probably went okay. If you didn't you
|
||||
probably need to examine the IRB, extended status word etc.
|
||||
If an error occurs, more sophisticated control units have a facility known as
|
||||
concurrent sense this means that if an error occurs Extended sense information will
|
||||
be presented in the Extended status word in the IRB if not you have to issue a
|
||||
subsequent SENSE CCW command after the test subchannel.
|
||||
concurrent sense. This means that if an error occurs Extended sense information
|
||||
will be presented in the Extended status word in the IRB. If not you have to
|
||||
issue a subsequent SENSE CCW command after the test subchannel.
|
||||
|
||||
|
||||
TPI( Test pending interrupt) can also be used for polled IO but in multitasking multiprocessor
|
||||
systems it isn't recommended except for checking special cases ( i.e. non looping checks for
|
||||
pending IO etc. ).
|
||||
TPI (Test pending interrupt) can also be used for polled IO, but in
|
||||
multitasking multiprocessor systems it isn't recommended except for
|
||||
checking special cases (i.e. non looping checks for pending IO etc.).
|
||||
|
||||
Store Subchannel & Modify Subchannel can be used to examine & modify operating characteristics
|
||||
of a subchannel ( e.g. channel paths ).
|
||||
Store Subchannel and Modify Subchannel can be used to examine and modify
|
||||
operating characteristics of a subchannel (e.g. channel paths).
|
||||
|
||||
Other IO related Terms:
|
||||
Sysplex: S390's Clustering Technology
|
||||
QDIO: S390's new high speed IO architecture to support devices such as gigabit ethernet,
|
||||
this architecture is also designed to be forward compatible with up & coming 64 bit machines.
|
||||
QDIO: S390's new high speed IO architecture to support devices such as gigabit
|
||||
ethernet, this architecture is also designed to be forward compatible with
|
||||
upcoming 64 bit machines.
|
||||
|
||||
|
||||
General Concepts
|
||||
@ -1406,37 +1419,40 @@ sometimes called Bus-and Tag & sometimes Original Equipment Manufacturers
|
||||
Interface (OEMI).
|
||||
|
||||
This byte wide Parallel channel path/bus has parity & data on the "Bus" cable
|
||||
& control lines on the "Tag" cable. These can operate in byte multiplex mode for
|
||||
sharing between several slow devices or burst mode & monopolize the channel for the
|
||||
whole burst. Up to 256 devices can be addressed on one of these cables. These cables are
|
||||
about one inch in diameter. The maximum unextended length supported by these cables is
|
||||
125 Meters but this can be extended up to 2km with a fibre optic channel extended
|
||||
such as a 3044. The maximum burst speed supported is 4.5 megabytes per second however
|
||||
some really old processors support only transfer rates of 3.0, 2.0 & 1.0 MB/sec.
|
||||
and control lines on the "Tag" cable. These can operate in byte multiplex mode
|
||||
for sharing between several slow devices or burst mode and monopolize the
|
||||
channel for the whole burst. Up to 256 devices can be addressed on one of these
|
||||
cables. These cables are about one inch in diameter. The maximum unextended
|
||||
length supported by these cables is 125 Meters but this can be extended up to
|
||||
2km with a fibre optic channel extended such as a 3044. The maximum burst speed
|
||||
supported is 4.5 megabytes per second. However, some really old processors
|
||||
support only transfer rates of 3.0, 2.0 & 1.0 MB/sec.
|
||||
One of these paths can be daisy chained to up to 8 control units.
|
||||
|
||||
|
||||
ESCON if fibre optic it is also called FICON
|
||||
Was introduced by IBM in 1990. Has 2 fibre optic cables & uses either leds or lasers
|
||||
for communication at a signaling rate of up to 200 megabits/sec. As 10bits are transferred
|
||||
for every 8 bits info this drops to 160 megabits/sec & to 18.6 Megabytes/sec once
|
||||
control info & CRC are added. ESCON only operates in burst mode.
|
||||
Was introduced by IBM in 1990. Has 2 fibre optic cables and uses either leds or
|
||||
lasers for communication at a signaling rate of up to 200 megabits/sec. As
|
||||
10bits are transferred for every 8 bits info this drops to 160 megabits/sec
|
||||
and to 18.6 Megabytes/sec once control info and CRC are added. ESCON only
|
||||
operates in burst mode.
|
||||
|
||||
ESCONs typical max cable length is 3km for the led version & 20km for the laser version
|
||||
known as XDF ( extended distance facility ). This can be further extended by using an
|
||||
ESCON director which triples the above mentioned ranges. Unlike Bus & Tag as ESCON is
|
||||
serial it uses a packet switching architecture the standard Bus & Tag control protocol
|
||||
is however present within the packets. Up to 256 devices can be attached to each control
|
||||
unit that uses one of these interfaces.
|
||||
ESCONs typical max cable length is 3km for the led version and 20km for the
|
||||
laser version known as XDF (extended distance facility). This can be further
|
||||
extended by using an ESCON director which triples the above mentioned ranges.
|
||||
Unlike Bus & Tag as ESCON is serial it uses a packet switching architecture,
|
||||
the standard Bus & Tag control protocol is however present within the packets.
|
||||
Up to 256 devices can be attached to each control unit that uses one of these
|
||||
interfaces.
|
||||
|
||||
Common 390 Devices include:
|
||||
Network adapters typically OSA2,3172's,2116's & OSA-E gigabit ethernet adapters,
|
||||
Consoles 3270 & 3215 ( a teletype emulated under linux for a line mode console ).
|
||||
Consoles 3270 & 3215 (a teletype emulated under linux for a line mode console).
|
||||
DASD's direct access storage devices ( otherwise known as hard disks ).
|
||||
Tape Drives.
|
||||
CTC ( Channel to Channel Adapters ),
|
||||
ESCON or Parallel Cables used as a very high speed serial link
|
||||
between 2 machines. We use 2 cables under linux to do a bi-directional serial link.
|
||||
between 2 machines.
|
||||
|
||||
|
||||
Debugging IO on s/390 & z/Architecture under VM
|
||||
@ -1475,9 +1491,9 @@ or the halt subchannels
|
||||
or TR HSCH 7C08-7C09
|
||||
MSCH's ,STSCH's I think you can guess the rest
|
||||
|
||||
Ingo's favourite trick is tracing all the IO's & CCWS & spooling them into the reader of another
|
||||
VM guest so he can ftp the logfile back to his own machine.I'll do a small bit of this & give you
|
||||
a look at the output.
|
||||
A good trick is tracing all the IO's and CCWS and spooling them into the reader
|
||||
of another VM guest so he can ftp the logfile back to his own machine. I'll do
|
||||
a small bit of this and give you a look at the output.
|
||||
|
||||
1) Spool stdout to VM reader
|
||||
SP PRT TO (another vm guest ) or * for the local vm guest
|
||||
@ -1593,8 +1609,8 @@ undisplay : undo's display's
|
||||
|
||||
info breakpoints: shows all current breakpoints
|
||||
|
||||
info stack: shows stack back trace ( if this doesn't work too well, I'll show you the
|
||||
stacktrace by hand below ).
|
||||
info stack: shows stack back trace (if this doesn't work too well, I'll show
|
||||
you the stacktrace by hand below).
|
||||
|
||||
info locals: displays local variables.
|
||||
|
||||
@ -1619,7 +1635,8 @@ next: like step except this will not step into subroutines
|
||||
stepi: steps a single machine code instruction.
|
||||
e.g. stepi 100
|
||||
|
||||
nexti: steps a single machine code instruction but will not step into subroutines.
|
||||
nexti: steps a single machine code instruction but will not step into
|
||||
subroutines.
|
||||
|
||||
finish: will run until exit of the current routine
|
||||
|
||||
@ -1721,7 +1738,8 @@ e.g.
|
||||
outputs:
|
||||
$1 = 11
|
||||
|
||||
You might now be thinking that the line above didn't work, something extra had to be done.
|
||||
You might now be thinking that the line above didn't work, something extra had
|
||||
to be done.
|
||||
(gdb) call fflush(stdout)
|
||||
hello world$2 = 0
|
||||
As an aside the debugger also calls malloc & free under the hood
|
||||
@ -1804,26 +1822,17 @@ man gdb or info gdb.
|
||||
core dumps
|
||||
----------
|
||||
What a core dump ?,
|
||||
A core dump is a file generated by the kernel ( if allowed ) which contains the registers,
|
||||
& all active pages of the program which has crashed.
|
||||
From this file gdb will allow you to look at the registers & stack trace & memory of the
|
||||
program as if it just crashed on your system, it is usually called core & created in the
|
||||
current working directory.
|
||||
This is very useful in that a customer can mail a core dump to a technical support department
|
||||
& the technical support department can reconstruct what happened.
|
||||
Provided they have an identical copy of this program with debugging symbols compiled in &
|
||||
the source base of this build is available.
|
||||
In short it is far more useful than something like a crash log could ever hope to be.
|
||||
|
||||
In theory all that is missing to restart a core dumped program is a kernel patch which
|
||||
will do the following.
|
||||
1) Make a new kernel task structure
|
||||
2) Reload all the dumped pages back into the kernel's memory management structures.
|
||||
3) Do the required clock fixups
|
||||
4) Get all files & network connections for the process back into an identical state ( really difficult ).
|
||||
5) A few more difficult things I haven't thought of.
|
||||
|
||||
|
||||
A core dump is a file generated by the kernel (if allowed) which contains the
|
||||
registers and all active pages of the program which has crashed.
|
||||
From this file gdb will allow you to look at the registers, stack trace and
|
||||
memory of the program as if it just crashed on your system. It is usually
|
||||
called core and created in the current working directory.
|
||||
This is very useful in that a customer can mail a core dump to a technical
|
||||
support department and the technical support department can reconstruct what
|
||||
happened. Provided they have an identical copy of this program with debugging
|
||||
symbols compiled in and the source base of this build is available.
|
||||
In short it is far more useful than something like a crash log could ever hope
|
||||
to be.
|
||||
|
||||
Why have I never seen one ?.
|
||||
Probably because you haven't used the command
|
||||
@ -1868,7 +1877,7 @@ Breakpoint 2 at 0x4d87a4: file top.c, line 2609.
|
||||
#3 0x5167e6 in readline_internal_char () at readline.c:454
|
||||
#4 0x5168ee in readline_internal_charloop () at readline.c:507
|
||||
#5 0x51692c in readline_internal () at readline.c:521
|
||||
#6 0x5164fe in readline (prompt=0x7ffff810 "\177ÿøx\177ÿ÷Ø\177ÿøxÀ")
|
||||
#6 0x5164fe in readline (prompt=0x7ffff810)
|
||||
at readline.c:349
|
||||
#7 0x4d7a8a in command_line_input (prompt=0x564420 "(gdb) ", repeat=1,
|
||||
annotation_suffix=0x4d6b44 "prompt") at top.c:2091
|
||||
@ -1929,8 +1938,8 @@ cat /proc/sys/net/ipv4/ip_forward
|
||||
On my machine now outputs
|
||||
1
|
||||
IP forwarding is on.
|
||||
There is a lot of useful info in here best found by going in & having a look around,
|
||||
so I'll take you through some entries I consider important.
|
||||
There is a lot of useful info in here best found by going in and having a look
|
||||
around, so I'll take you through some entries I consider important.
|
||||
|
||||
All the processes running on the machine have their own entry defined by
|
||||
/proc/<pid>
|
||||
@ -2060,7 +2069,8 @@ if the device doesn't say up
|
||||
try
|
||||
/etc/rc.d/init.d/network start
|
||||
( this starts the network stack & hopefully calls ifconfig tr0 up ).
|
||||
ifconfig looks at the output of /proc/net/dev & presents it in a more presentable form
|
||||
ifconfig looks at the output of /proc/net/dev and presents it in a more
|
||||
presentable form.
|
||||
Now ping the device from a machine in the same subnet.
|
||||
if the RX packets count & TX packets counts don't increment you probably
|
||||
have problems.
|
||||
|
Loading…
Reference in New Issue
Block a user