Memory leak debugging with windbg without user stack trace - windows

I have a full memory dump but in this instance I don't have a user stack trace database to go with it, I have up to date symbols and the original binaries that go with the dump, normally, I've been able to use the !heap -p -a address to view the call stack at the moment of allocation but this won't work without the user stack trace database.
My question is whether there's another way (albeit less direct approach) to get at the source of this memory leak.
LFH Key : 0x0000005c2dc22701
Termination on corruption : ENABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-------------------------------------------------------------------------------------
00000000002e0000 00000002 3125248 3122792 3125248 282 378 197 0 7 LFH
0000000000010000 00008000 64 4 64 1 1 1 0 0
0000000000530000 00001002 1088 416 1088 51 10 2 0 0 LFH
0000000000490000 00001002 512 284 512 5 5 1 0 0 LFH
0000000000af0000 00001002 1088 248 1088 2 2 2 0 0 LFH
0000000000c00000 00001002 64 8 64 3 1 1 0 0
0000000000de0000 00001002 512 8 512 3 1 1 0 0
0000000000ac0000 00001002 31616 30356 31616 1810 42 6 0 0 LFH
00000000012c0000 00001002 512 8 512 2 1 1 0 0
0000000002140000 00001003 512 88 512 49 7 1 0 N/A
0000000001ab0000 00001003 512 8 512 5 1 1 0 N/A
00000000022f0000 00001003 512 8 512 5 1 1 0 N/A
0000000002490000 00001003 512 8 512 5 1 1 0 N/A
0000000000d40000 00001003 512 8 512 5 1 1 0 N/A
0000000002690000 00001003 512 8 512 5 1 1 0 N/A
0000000002860000 00001003 512 8 512 5 1 1 0 N/A
0000000002e90000 00001002 512 8 512 2 2 1 0 0
0000000002e10000 00001002 1536 556 1536 40 6 2 0 0 LFH
0000000001b90000 00011002 512 8 512 3 2 1 0 0
00000000033e0000 00001002 512 8 512 3 2 1 0 0
-------------------------------------------------------------------------------------
As you can see from this heap summary (!heap -s), heap 00000000002e0000 has grown pretty large, on closer inspection is can see that 70% of the data is allocated in blocks of size 0x4058, 0x23d1 and 0x10d1 (which is definitely some kind of pattern) so I'm pretty sure I want to investigate that further.
heap # 00000000002e0000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
4058 1ea - 7b2870 (39.56)
23d1 1dc - 42989c (21.39)
10d1 1ed - 20627d (10.40)
c51 1f4 - 180e34 (7.73)
307 25b - 7217d (2.29)
378 1f9 - 6d7b8 (2.20)
188 40e - 63570 (1.99)
c0 59f - 43740 (1.35)
30 12c7 - 38550 (1.13)
28 147e - 333b0 (1.03)
140 22a - 2b480 (0.87)
138 231 - 2abb8 (0.86)
2340 11 - 25740 (0.75)
100 244 - 24400 (0.73)
120 1ea - 22740 (0.69)
78 456 - 20850 (0.65)
1010 12 - 12120 (0.36)
10188 1 - 10188 (0.32)
10008 1 - 10008 (0.32)
4000 4 - 10000 (0.32)
My problem is that I don't know where to go from here, previously I've followed the instructions found here with great success but this time around I don't have a user stack trace database and I can't easily reproduce this pattern but I know the memory dump contains a lot of useful information I'm just not sure how to go about getting at something meaningful from here. Windbg experts? Memory dump analysts? Please advice.
Some blocks, first couple of bytes
0:000> dc 0000000005254b80
00000000`05254b80 52474d45 00000000 050f1c40 00000000 EMGR....#.......
00000000`05254b90 00000000 00000000 00000001 00000001 ................
00000000`05254ba0 00000400 000003ff 0001d4c0 00000001 ................
00000000`05254bb0 524d4954 00000000 051fcd10 00000000 TIMR............
00000000`05254bc0 f7b315d0 000007fe 05254b80 00000000 .........K%.....
00000000`05254bd0 00000000 00000000 05254bd8 00000000 .........K%.....
00000000`05254be0 05254bd8 00000000 05254be8 00000000 .K%......K%.....
00000000`05254bf0 05254be8 00000000 05254bf8 00000000 .K%......K%.....
0:000> dc 00000000051ce640
00000000`051ce640 52474d45 00000000 04f1ab00 00000000 EMGR............
00000000`051ce650 00000000 00000000 00000001 00000001 ................
00000000`051ce660 00000400 000003ff 0001d4c0 00000001 ................
00000000`051ce670 524d4954 00000000 05037070 00000000 TIMR....pp......
00000000`051ce680 f7b315d0 000007fe 051ce640 00000000 ........#.......
00000000`051ce690 00000000 00000000 051ce698 00000000 ................
00000000`051ce6a0 051ce698 00000000 051ce6a8 00000000 ................
00000000`051ce6b0 051ce6a8 00000000 051ce6b8 00000000 ................
0:000> dc 0000000004fdb1f0
00000000`04fdb1f0 52474d45 00000000 04f1b570 00000000 EMGR....p.......
00000000`04fdb200 00000000 00000000 00000001 00000001 ................
00000000`04fdb210 00000400 000003ff 0001d4c0 00000001 ................
00000000`04fdb220 524d4954 00000000 04ed6ba0 00000000 TIMR.....k......
00000000`04fdb230 f7b315d0 000007fe 04fdb1f0 00000000 ................
00000000`04fdb240 00000000 00000000 04fdb248 00000000 ........H.......
00000000`04fdb250 04fdb248 00000000 04fdb258 00000000 H.......X.......
00000000`04fdb260 04fdb258 00000000 04fdb268 00000000 X.......h.......
0:000> dc 0000000001e649b0
00000000`01e649b0 52474d45 00000000 00351270 00000000 EMGR....p.5.....
00000000`01e649c0 00000000 00000000 00000001 00000001 ................
00000000`01e649d0 00000400 000003ff 0001d4c0 00000001 ................
00000000`01e649e0 524d4954 00000000 01e64130 00000000 TIMR....0A......
00000000`01e649f0 f7b315d0 000007fe 01e649b0 00000000 .........I......
00000000`01e64a00 00000000 00000000 01e64a08 00000000 .........J......
00000000`01e64a10 01e64a08 00000000 01e64a18 00000000 .J.......J......
00000000`01e64a20 01e64a18 00000000 01e64a28 00000000 .J......(J......

Use the !heap -flt s on the offending size(s) (with logging to file)
Then manually dump the contents on some of them and try to guess what kind of data they contain.
If you are lucky it’s C++ objects with a vtable address in first DWORD which make them “easy” to recognize.
If not, use dc , dds commands and try to figure out what the contents is.
Another approach is to find types which have corresponding size to those you suspect leaking.
============================Find symbols of spesific size===================================
0:011> dt -v -s a4 <MyDll>!*
Enumerating symbols matching <MyDll>!*, Size = 0xa4
Address Size Symbol
0a4 <MyDll>!NMDATETIMEFORMATW
0a4 <MyDll>!CWinApp
0a4 <MyDll>!CWinApp
==> Check all modules
!for_each_module ".echo ##ModuleName;dt -v -s a4 ${##ModuleName}!*"
You can also try to find heap blocks which has a pointer to a leak suspect
0:008> !heap -srch 09C07058
_HEAP # 02C90000
in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
0B7DA920: 002c : 002c [01] - 0B7DA928 (00000158) - (busy)
diasymreader!Mod1::`vftable'

Related

Why is the objdump binary size so much larger than the actual ELF size?

I have an ELF file which we then convert to a binary format:
arm-none-eabi-objcopy -O binary MyElfFile.elf MyBinFile.bin
The ELF file is just under 300KB, but the binary output file is 446-times larger: 134000KB, or 130MB! How is this possible when the whole point of a binary is to remove symbols and section tables and debug info?
Looking at Reddit and SO it looks like the binary image should be smaller than the ELF, not larger.
so.s
b .
.section .data
.word 0x12345678
arm-none-eabi-as so.s -o so.o
arm-none-eabi-objdump -D so.o
so.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <.text>:
0: eafffffe b 0 <.text>
Disassembly of section .data:
00000000 <.data>:
0: 12345678 eorsne r5, r4, #120, 12 ; 0x78
arm-none-eabi-readelf -a so.o
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000004 00 AX 0 0 4
[ 2] .data PROGBITS 00000000 000038 000004 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 00003c 000000 00 WA 0 0 1
[ 4] .ARM.attributes ARM_ATTRIBUTES 00000000 00003c 000012 00 0 0 1
[ 5] .symtab SYMTAB 00000000 000050 000060 10 6 6 4
[ 6] .strtab STRTAB 00000000 0000b0 000004 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 0000b4 00003c 00 0 0 1
so my "binary" has 8 bytes total. In two sections.
-rw-rw-r-- 1 oldtimer oldtimer 560 Oct 12 16:32 so.o
8 bytes relative to 560 for the object.
Link it.
MEMORY
{
one : ORIGIN = 0x00001000, LENGTH = 0x1000
two : ORIGIN = 0x00002000, LENGTH = 0x1000
}
SECTIONS
{
.text : { (.text) } > one
.data : { (.data) } > two
}
arm-none-eabi-ld -T so.ld so.o -o so.elf
arm-none-eabi-objdump -D so.elf
so.elf: file format elf32-littlearm
Disassembly of section .text:
00001000 <.text>:
1000: eafffffe b 1000 <.text>
Disassembly of section .data:
00002000 <.data>:
2000: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
arm-none-eabi-readelf -a so.elf
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00001000 001000 000004 00 AX 0 0 4
[ 2] .data PROGBITS 00002000 002000 000004 00 WA 0 0 1
[ 3] .ARM.attributes ARM_ATTRIBUTES 00000000 002004 000012 00 0 0 1
[ 4] .symtab SYMTAB 00000000 002018 000070 10 5 7 4
[ 5] .strtab STRTAB 00000000 002088 00000c 00 0 0 1
[ 6] .shstrtab STRTAB 00000000 002094 000037 00 0 0 1
Now...we need 4 bytes at 0x1000 and 4 bytes at 0x2000, if we want to use the -O binary objcopy that means it is going to take the entire memory space and start the file with the lowest address thing and end with the highest address thing. With this link the lowest thing is 0x1000 and highest is 0x2003, a total span of 0x1004 bytes:
arm-none-eabi-objcopy -O binary so.elf so.bin
ls -al so.bin
-rwxrwxr-x 1 oldtimer oldtimer 4100 Oct 12 16:40 so.bin
4100 = 0x1004 bytes
hexdump -C so.bin
00000000 fe ff ff ea 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000 78 56 34 12 |xV4.|
00001004
The assumption here is the user knows that the base address is 0x1000 as there is no address info in the file format. And that this is a continuous memory image so that the four bytes also land at 0x2000. So -O binary pads the file to fill everything in.
If I change to this
MEMORY
{
one : ORIGIN = 0x00000000, LENGTH = 0x1000
two : ORIGIN = 0x10000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > one
.data : { *(.data*) } > two
}
You can easily see where this is headed.
ls -al so.bin
-rwxrwxr-x 1 oldtimer oldtimer 268435460 Oct 12 16:43 so.bin
So my elf does not change size, but the -O binary format is 0x10000004 bytes in size, there are only 8 bytes I care about but the nature of objcopy -O binary has to pad the middle.
Since the sizes and spaces of things vary specific to your project and your linker script, no generic statements can be made relative to the size of the elf file and the size of an -O binary file.
ls -al so.elf
-rwxrwxr-x 1 oldtimer oldtimer 131556 Oct 12 16:49 so.elf
arm-none-eabi-strip so.elf
ls -al so.elf
-rwxrwxr-x 1 oldtimer oldtimer 131336 Oct 12 16:50 so.elf
arm-none-eabi-as -g so.s -o so.o
ls -al so.o
-rw-rw-r-- 1 oldtimer oldtimer 1300 Oct 12 16:51 so.o
arm-none-eabi-ld -T so.ld so.o -o so.elf
ls -al so.elf
-rwxrwxr-x 1 oldtimer oldtimer 132088 Oct 12 16:51 so.elf
arm-none-eabi-strip so.elf
ls -al so.elf
-rwxrwxr-x 1 oldtimer oldtimer 131336 Oct 12 16:52 so.elf
The elf binary file format does not have absolute rules on content, the consumer of the file can have rule as to what you have to put where, if any specific names of items have to be there, etc. It is a somewhat open file format, it is a container like a cardboard box, and you can fill it to some extent how you like. You cannot fit a cruise ship in it, but you can put books or toys and you can choose how you put the books or toys in it sometimes.
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 010000 000004 00 AX 0 0 4
[ 2] .data PROGBITS 10000000 020000 000004 00 WA 0 0 1
[ 3] .ARM.attributes ARM_ATTRIBUTES 00000000 020004 000012 00 0 0 1
[ 4] .shstrtab STRTAB 00000000 020016 000027 00 0 0 1
Even after stripping there is still extra stuff there, if you study the file format you have a header, relatively small with number of program headers and number of section headers and then that many program headers and that many section headers. Depending on the consumer(s) of the file you may for example only need the main header stuff and two program headers in this case and that is it, a much smaller file (as you can see with the object version of the file).
arm-none-eabi-as so.s -o so.o
ls -al so.o
-rw-rw-r-- 1 oldtimer oldtimer 560 Oct 12 16:57 so.o
arm-none-eabi-strip so.o
ls -al so.o
-rw-rw-r-- 1 oldtimer oldtimer 364 Oct 12 16:57 so.o
readelf that
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 6
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000004 00 AX 0 0 4
[ 2] .data PROGBITS 00000000 000038 000004 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 00003c 000000 00 WA 0 0 1
[ 4] .ARM.attributes ARM_ATTRIBUTES 00000000 00003c 000012 00 0 0 1
[ 5] .shstrtab STRTAB 00000000 00004e 00002c 00 0 0 1
Extra section headers we don't need which maybe can be removed in the linker script. But I assume for some consumers all you would need is the two program headers
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Plus the 8 bytes and any padding for this file format.
Also note
arm-none-eabi-objcopy --only-section=.text -O binary so.elf text.bin
arm-none-eabi-objcopy --only-section=.data -O binary so.elf data.bin
ls -al text.bin
-rwxrwxr-x 1 oldtimer oldtimer 4 Oct 12 17:03 text.bin
ls -al data.bin
-rwxrwxr-x 1 oldtimer oldtimer 4 Oct 12 17:03 data.bin
hexdump -C text.bin
00000000 fe ff ff ea |....|
00000004
hexdump -C data.bin
00000000 78 56 34 12 |xV4.|
00000004

Conversion from .elf to .bin increases file size

When we covert a .elf file generated from arm-gcc toolchain to .bin file, its size increases from 40kB to 1.1Gb.
For conversion we are using :
./arm-none-eabi-objcopy -O binary test.elf test.bin
It might be because of non-contiguous memory map and the gaps between the memory regions are just being filled with zeros.
What options can be used in objcopy? Or is there any other method to convert?
Following is the elf information:
Tag_CPU_name: "Cortex-M7" Tag_CPU_arch: v7E-M
Tag_CPU_arch_profile: Microcontroller Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: FPv5/FP-D16 for ARMv8 Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754 Tag_ABI_align_needed: 8-byte
Tag_ABI_enum_size: small Tag_ABI_VFP_args: VFP registers
Tag_ABI_optimization_goals: Aggressive Debug
Tag_CPU_unaligned_access: v6
The listing of sections contained in the ELF file is - there are 25 section headers, starting at offset 0x3e982c:
Section Headers:
[Nr] Name
Type Addr Off Size ES Lk Inf Al
Flags
[ 0]
NULL 00000000 000000 000000 00 0 0 0
[00000000]:
[ 1] .flash_config
PROGBITS 60000000 020000 000200 00 0 0 4
[00000002]: ALLOC
[ 2] .ivt
PROGBITS 60001000 021000 000030 00 0 0 4
[00000002]: ALLOC
[ 3] .interrupts
PROGBITS 60002000 022000 000400 00 0 0 4
[00000002]: ALLOC
[ 4] .text
PROGBITS 60002400 022400 312008 00 0 0 16
[00000006]: ALLOC, EXEC
[ 5] .ARM
ARM_EXIDX 60314408 334408 000008 00 4 0 4
[00000082]: ALLOC, LINK ORDER
[ 6] .init_array
INIT_ARRAY 60314410 334410 000004 04 0 0 4
[00000003]: WRITE, ALLOC
[ 7] .fini_array
FINI_ARRAY 60314414 334414 000004 04 0 0 4
[00000003]: WRITE, ALLOC
[ 8] .interrupts_ram
PROGBITS 20200000 380000 000000 00 0 0 1
[00000001]: WRITE
[ 9] .data
PROGBITS 20200000 340000 014bd0 00 0 0 8
[00000007]: WRITE, ALLOC, EXEC
[10] .ncache.init
PROGBITS 20214bd0 354bd0 011520 00 0 0 4
[00000003]: WRITE, ALLOC
[11] .ncache
NOBITS 20226100 366100 0021d8 00 0 0 64
[00000003]: WRITE, ALLOC
[12] .bss
NOBITS 20229000 369000 077ce8 00 0 0 4096
[00000003]: WRITE, ALLOC
[13] .NVM_TABLE
PROGBITS 20000000 010000 00000c 00 0 0 4
[00000003]: WRITE, ALLOC
[14] .heap
NOBITS 2000000c 01000c 000404 00 0 0 1
[00000003]: WRITE, ALLOC
[15] .stack
NOBITS 20000410 01000c 000400 00 0 0 1
[00000003]: WRITE, ALLOC
[16] .NVM
PROGBITS 60570000 370000 010000 00 0 0 1
[00000003]: WRITE, ALLOC
[17] .ARM.attributes
ARM_ATTRIBUTES 00000000 380000 00002e 00 0 0 1
[00000000]:
[18] .comment
PROGBITS 00000000 38002e 00004c 01 0 0 1
[00000030]: MERGE, STRINGS
[19] .debug_frame
PROGBITS 00000000 38007c 001174 00 0 0 4
[00000000]:
[20] .stab
PROGBITS 00000000 3811f0 0000cc 0c 21 0 4
[00000000]:
[21] .stabstr
STRTAB 00000000 3812bc 0001b9 00 0 0 1
[00000000]:
[22] .symtab
SYMTAB 00000000 381478 046620 10 23 13540 4
[00000000]:
[23] .strtab
STRTAB 00000000 3c7a98 021cb2 00 0 0 1
[00000000]:
[24] .shstrtab
STRTAB 00000000 3e974a 0000df 00 0 0 1
[00000000]:
so.s
.thumb
nop
.data
.word 0x11223344
so.ld
MEMORY
{
one : ORIGIN = 0x00000000, LENGTH = 0x1000
two : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > one
.data : { *(.data*) } > two
}
build
arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -T so.ld so.o -o so.elf
arm-none-eabi-objdump -D so.elf
arm-none-eabi-objcopy -O binary so.elf so.bin
536870916 Apr 28 15:23 so.bin
131556 Apr 28 15:23 so.elf
from readelf
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00000000 0x00000000 0x00002 0x00002 R E 0x10000
LOAD 0x020000 0x20000000 0x20000000 0x00004 0x00004 RW 0x10000
now so.ld
MEMORY
{
one : ORIGIN = 0x00000000, LENGTH = 0x1000
two : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > one
.bss : { *(.bss*) } > two AT > one
.data : { *(.data*) } > two AT > one
}
it is actually .bss that is doing the magic here, that is some other research project, I could have started with a .C file but tried asm...
6 Apr 28 15:30 so.bin
131556 Apr 28 15:29 so.elf
and now it is the possibly desired 6 bytes without padding, but of course you have to add labels in the linker script and use them in the bootstrap code to move .data to ram and zero .bss and such.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00000000 0x00000000 0x00002 0x00002 R E 0x10000
LOAD 0x020000 0x20000000 0x00000002 0x00004 0x00004 RW 0x10000
Notice how now the physical is in the 0x00000000 range, it was tacked at the end of the space used by .text. but the virtual (where it wants to live, needs to live, do not think mmu here or anything like that just think the two address spaces (on flash and where it is used)).
In case this is not clear:
MEMORY
{
one : ORIGIN = 0xE0000000, LENGTH = 0x1000
two : ORIGIN = 0xE0000100, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > one
.data : { *(.data*) } > two
}
260 Apr 28 15:46 so.bin
66276 Apr 28 15:46 so.elf
objcopy starts the binary file at the lowest defined (loadable) address and not zero...The file size is the difference, inclusive, of the lowest addressed byte and the highest.
I have same problem with you, and I finally find it's not objcopy's problem, I just change my compile command and it work. At first, I just use gcc only, and I face the problem like you, then I try use gcc -c and ld(just separate this two steps), and the file is smaller in magically. so maybe the problem is in gcc, not objcopy. you can try like me, and my compile command now is:
gcc-4.8 -g -e boot_start -fno-builtin -Ttext 0x7C00 -nostdlib -m32 -c bootloader.S -o bootasm.o
gcc-4.8 -Os -fno-builtin -nostdlib -m32 -c bootloader.c -o bootc.o
ld -m elf_i386 -e boot_start -nostdlib -N bootasm.o bootc.o -o bootloader.o
objcopy -S -O binary bootloader.o bootloader.bin
hope it can help you...

ORA-01092 Oracle Instance terminated. disconnected forced

I am trying to start an Oracle 11g database but it is failing with ORA-01092 and ORA-00600 errors:
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
C:\Users\Administrator>sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on Wed Sep 11 15:21:30 2019
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup upgrade
ORACLE instance started.
Total System Global Area 430075904 bytes
Fixed Size 2176448 bytes
Variable Size 356518464 bytes
Database Buffers 67108864 bytes
Redo Buffers 4272128 bytes
Database mounted.
ORA-01092: ORACLE instance terminated. Disconnection forced
ORA-00600: internal error code, arguments: [4194], [], [], [], [], [], [], [],
[], [], [], []
Process ID: 5044
Session ID: 1 Serial number: 5
SQL> conn
Enter user-name: delhipilot
Enter password:
ERROR:
ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
Process ID: 0
Session ID: 0 Serial number: 0
SQL>
How can I start my database properly?
Here is an example of patching the system rollback segment header to avoid errors ORA-600 [4193] and ORA-600 [4194] during startup. Note that in this example the segment header is located in file 1 block 9 and the example in note 452620.1 is using file 1 block 2 as the segment header.
parnassusdata can also provide the recovery service.
It is a partial block dump for system rbs segment header file 1 block 9:
TRN CTL:: seq: 0x003a chd: 0x0017 ctl: 0x0052 inc: 0x00000000 nfb: 0x0001
mgc: 0x8002 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x00400197.003a.02 scn: 0x0000.004fbbf0
Version: 0x01
FREE BLOCK POOL::
uba: 0x00400197.003a.02 ext: 0x4 spc: 0x1dd2
uba: 0x00000000.0037.05 ext: 0x1 spc: 0x1d6c
uba: 0x00000000.0035.37 ext: 0x5 spc: 0x538
uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0
1. Generate the bbed executable:
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk `pwd`/bbed
mv bbed $ORACLE_HOME/bin
2. Create file file.lis with the datafile where the system rollback segment header is stored:
file.lis has:
<relative file#> <datafile name> <size in bytes: v$datafile.bytes>
In our session file.lis contains:
1 /oradata/s102/system01.dbf 524288000
3. Create file bbed.par
bbed.par has:
MODE=EDIT
LISTFILE=<File name created in step2>
BLOCKSIZE=<db_block_size>
In our session bbed.par contains
MODE=EDIT
LISTFILE=file.lis
BLOCKSIZE=8192
4. Run bbed. Use password blockedit:
$ bbed parfile=bbed.par
Password:
BBED: Release 2.0.0.0.0 - Limited Production on Thu Sep 27 10:06:25 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED>
5. Go to Block where the system rollback segment header is stored. In our example it is block 9:
BBED> set block 9
BLOCK# 9
6. Run map to see the C structures for the block and the DBA:
BBED> map
File: /oradata/s102/system01.dbf (1)
Block: 9 Dba:0x00400009
------------------------------------------------------------
Unlimited Undo Segment Header
struct kcbh, 20 bytes #0
struct ktech, 72 bytes #20
struct ktemh, 16 bytes #92
struct ktetb[6], 48 bytes #108
struct ktuxc, 104 bytes #4148
struct ktuxe[255], 10200 bytes #4252
ub4 tailchk #8188
Note that dba=0x00400009 is file 1 block 9, so we are positioned in the correct block.
7. Print the structure ktuxc:
BBED> print ktuxc
struct ktuxc, 104 bytes #4148
struct ktuxcscn, 8 bytes #4148
ub4 kscnbas #4148 0x004fbbf1
ub2 kscnwrp #4152 0x0000
struct ktuxcuba, 8 bytes #4156
ub4 kubadba #4156 0x00400197
ub2 kubaseq #4160 0x003a
ub1 kubarec #4162 0x03
sb2 ktuxcflg #4164 1 (KTUXCFSK)
ub2 ktuxcseq #4166 0x003a
sb2 ktuxcnfb #4168 1
ub4 ktuxcinc #4172 0x00000000
sb2 ktuxcchd #4176 6
sb2 ktuxcctl #4178 23
ub2 ktuxcmgc #4180 0x8002
ub4 ktuxcopt #4188 0x7ffffffe
struct ktuxcfbp[0], 12 bytes #4192
struct ktufbuba, 8 bytes #4192
ub4 kubadba #4192 0x00400197
ub2 kubaseq #4196 0x003a
ub1 kubarec #4198 0x0c
sb2 ktufbext #4200 4
sb2 ktufbspc #4202 5630
8. Modify ktuxc.ktuxcnfb to 0x0000
BBED> set offset ktuxc.ktuxcnfb
OFFSET 4168
BBED> print
ktuxc.ktuxcnfb
--------------
sb2 ktuxcnfb #4168 1
BBED> modify 0x0000
File: /oradata/s102/system01.dbf (1)
Block: 9 Offsets: 4168 to 4679 Dba:0x00400009
------------------------------------------------------------------------
00000000 00000000 06001700 02800100 68000000 feffff7f 97014000 3a000c00
0400fe15 00000000 37000500 01006c1d 00000000 35003700 05003805 00000000
00000000 00000000 00000000 00000000 00000000 30000000 93014000 191f5300
00000000 09005f00 00000000 00000000 00000000 01000000 00000000 31000000
96014000 a03e5b00 00000000 09005c00 00000000 00000000 00000000 01000000
00000000 31000000 96014000 9e3e5b00 00000000 09000e00 00000000 00000000
00000000 01000000 00000000 30000000 93014000 f4bb4f00 00000000 09001600
00000000 00000000 00000000 01000000 00000000 31000000 96014000 c13a5b00
00000000 09004800 00000000 00000000 00000000 01000000 00000000 31000000
96014000 983e5b00 00000000 09006000 00000000 00000000 00000000 01000000
00000000 30000000 93014000 f2bb4f00 00000000 09001400 00000000 00000000
00000000 01000000 00000000 31000000 96014000 933e5b00 00000000 09006100
00000000 00000000 00000000 01000000 00000000 31000000 96014000 8d3e5b00
00000000 09004700 00000000 00000000 00000000 01000000 00000000 30000000
94014000 87d15900 00000000 09002100 00000000 00000000 00000000 01000000
00000000 30000000 94014000 211f5300 00000000 09001d00 00000000 00000000
<32 bytes per line>
9. Modify ktuxc.ktuxcfbp[0].ktufbuba to 0x00000000
BBED> set offset ktuxc.ktuxcfbp[0].ktufbuba
OFFSET 4192
BBED> print
ktuxc.ktuxcfbp[0].ktufbuba.kubadba
----------------------------------
ub4 kubadba #4192 0x00400197
BBED> modify 0x00000000
File: /oradata/s102/system01.dbf (1)
Block: 9 Offsets: 4192 to 4703 Dba:0x00400009
------------------------------------------------------------------------
00000000 3a000c00 0400fe15 00000000 37000500 01006c1d 00000000 35003700
05003805 00000000 00000000 00000000 00000000 00000000 00000000 30000000
93014000 191f5300 00000000 09005f00 00000000 00000000 00000000 01000000
00000000 31000000 96014000 a03e5b00 00000000 09005c00 00000000 00000000
00000000 01000000 00000000 31000000 96014000 9e3e5b00 00000000 09000e00
00000000 00000000 00000000 01000000 00000000 30000000 93014000 f4bb4f00
00000000 09001600 00000000 00000000 00000000 01000000 00000000 31000000
96014000 c13a5b00 00000000 09004800 00000000 00000000 00000000 01000000
00000000 31000000 96014000 983e5b00 00000000 09006000 00000000 00000000
00000000 01000000 00000000 30000000 93014000 f2bb4f00 00000000 09001400
00000000 00000000 00000000 01000000 00000000 31000000 96014000 933e5b00
00000000 09006100 00000000 00000000 00000000 01000000 00000000 31000000
96014000 8d3e5b00 00000000 09004700 00000000 00000000 00000000 01000000
00000000 30000000 94014000 87d15900 00000000 09002100 00000000 00000000
00000000 01000000 00000000 30000000 94014000 211f5300 00000000 09001d00
00000000 00000000 00000000 01000000 00000000 30000000 93014000 0d1f5300
<32 bytes per line>
BBED>
10. Disable the block Checksum by changing the kcbh.flg_kcbh-4 and kcbh.chkval_kcbh to 0x0000:
BBED> map
File: /oradata/s102/system01.dbf (1)
Block: 9 Dba:0x00400009
------------------------------------------------------------
Unlimited Undo Segment Header
struct kcbh, 20 bytes #0
struct ktech, 72 bytes #20
struct ktemh, 16 bytes #92
struct ktetb[6], 48 bytes #108
struct ktuxc, 104 bytes #4148
struct ktuxe[255], 10200 bytes #4252
ub4 tailchk #8188
BBED> print kcbh
struct kcbh, 20 bytes #0
ub1 type_kcbh #0 0x0e
ub1 frmt_kcbh #1 0xa2
ub1 spare1_kcbh #2 0x00
ub1 spare2_kcbh #3 0x00
ub4 rdba_kcbh #4 0x00400009
ub4 bas_kcbh #8 0x005b3f76
ub2 wrp_kcbh #12 0x0000
ub1 seq_kcbh #14 0x01
ub1 flg_kcbh #15 0x04 (KCBHFCKV)
ub2 chkval_kcbh #16 0xe264
ub2 spare3_kcbh #18 0x0000
BBED> set offset kcbh.flg_kcbh
OFFSET 15
BBED> print
kcbh.flg_kcbh
-------------
ub1 flg_kcbh #15 0x04 (KCBHFCKV)
BBED> modify 0x00
File: /oradata/s102/system01.dbf (1)
Block: 9 Offsets: 15 to 526 Dba:0x00400009
------------------------------------------------------------------------
0064e200 00000000 00000000 00000000 00000000 00060000 002f0000 00201000
00040000 00060000 00080000 00970140 00000000 00040000 00000000 00000000
00000000 00000000 00000000 00060000 00000000 00000000 00000000 400a0040
00070000 00110040 00080000 00810140 00080000 00890140 00080000 00910140
00080000 00990140 00080000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
BBED> set offset kcbh.chkval_kcbh
OFFSET 16
BBED> print
kcbh.chkval_kcbh
----------------
ub2 chkval_kcbh #16 0xe264
BBED> modify 0x0000
File: /oradata/s102/system01.dbf (1)
Block: 9 Offsets: 16 to 527 Dba:0x00400009
------------------------------------------------------------------------
00000000 00000000 00000000 00000000 00000000 06000000 2f000000 20100000
04000000 06000000 08000000 97014000 00000000 04000000 00000000 00000000
00000000 00000000 00000000 06000000 00000000 00000000 00000040 0a004000
07000000 11004000 08000000 81014000 08000000 89014000 08000000 91014000
08000000 99014000 08000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
11. Verify the the block has no corruptions:
BBED> verify
DBVERIFY - Verification starting
FILE = /oradata/s102/system01.dbf
BLOCK = 9
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
12. exit, open the database and shrink the system rollback segment:
BBED> exit
[oracle#arem example]$ sqlplus / as sysdba
SQL*Plus: Release 10.2.0.3.0 - Production on Thu Sep 27 10:28:00 2007
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1260696 bytes
Variable Size 62915432 bytes
Database Buffers 100663296 bytes
Redo Buffers 2932736 bytes
Database mounted.
Database opened.
SQL> alter rollback segment system shrink;
Rollback segment altered.
SQL>

RISC-V: Size of code size in an object file which is not linked

I have a .i file which I have compiled but not linked using the SiFive risc-v compiler as follows:
../riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc clock.i
However when I do a readelf -S on the compiled object file the .text section is 0 bytes:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .text.getTime PROGBITS 00000000 000034 00003a 00 AX 0 0 2
[ 5] .rela.text.ge RELA 00000000 000484 0000c0 0c I 18 4 4
[ 6] .text.timeGap PROGBITS 00000000 00006e 00002e 00 AX 0 0 2
[ 7] .rela.text.ti RELA 00000000 000544 000024 0c I 18 6 4
[ 8] .text.applyTO PROGBITS 00000000 00009c 000038 00 AX 0 0 2
[ 9] .rela.text.ap RELA 00000000 000568 0000c0 0c I 18 8 4
[10] .text.clearTO PROGBITS 00000000 0000d4 000038 00 AX 0 0 2
[11] .rela.text.cl RELA 00000000 000628 0000c0 0c I 18 10 4
[12] .rodata.getTi PROGBITS 00000000 00010c 00000c 01 AMS 0 0 4
[13] .rodata.__func__. PROGBITS 00000000 000118 00000c 00 A 0 0 4
[14] .rodata.__func__. PROGBITS 00000000 000124 00000c 00 A 0 0 4
[15] .rodata.__func__. PROGBITS 00000000 000130 00000c 00 A 0 0 4
[16] .comment PROGBITS 00000000 00013c 000029 01 MS 0 0 1
[17] .riscv.attributes LOPROC+0x3 00000000 000165 00001f 00 0 0 1
[18] .symtab SYMTAB 00000000 000184 000240 10 19 31 4
[19] .strtab STRTAB 00000000 0003c4 0000be 00 0 0 1
[20] .shstrtab STRTAB 00000000 0006e8 000100 00 0 0 1
If I do a size on the compiled object file I get a size of 264 bytes:
text data bss dec hex filename
264 0 0 264 108 clock.o
If I do an nm --print-size I get the following:
U __assert_func
00000000 0000000c r __func__.3507
00000000 0000000c r __func__.3518
00000000 0000000c r __func__.3522
0000000c t .L11
00000036 t .L12
00000034 t .L14
00000036 t .L18
00000034 t .L2
00000034 t .L20
00000032 t .L3
0000001e t .L8
00000000 r .LANCHOR0
00000000 r .LANCHOR1
00000000 r .LANCHOR2
00000000 r .LC0
00000004 r .LC1
00000000 00000038 T applyTO
00000000 00000038 T clearTO
00000000 0000003a T getTime
00000000 0000002e T timeGap
Which to me the size would be 0x38 + 0x38 + 0x3A + 0x2E = 0xD8 (216) bytes.
How can I calculate the size of a compiled object file?
Your object file is compiled with -ffunction-sections, a special flag which allocates each function to it's dedicated section. You can see individual .texts for each function in readelf's output:
[ 4] .text.getTime PROGBITS 00000000 000034 00003a 00 AX 0 0 2
...
[ 6] .text.timeGap PROGBITS 00000000 00006e 00002e 00 AX 0 0 2
...
To get full code size you'll need to sum sizes for each section starting with ".text". A Perl one-liner:
$ readelf ... | perl -ne 'if(/ \.text/) { s/^.*\] *//; $sz += hex((split(/ +/))[4]); print "$sz\n"; }' 0
58
104
160
216 <-- Full size

Force GCC to keep section when using link time optimization

I have a C struct that is compiled by GCC into a special section and placed at the beginning of an output binary via a linker script. It contains file metadata, including a magic value at the beginning.
Here's a simplified example using just a string as the struct.
const char __magic_value[9] __attribute__((section(".the_header"))) = "MAGICVAL";
GCC places this value into its own section, as we can see with readelf -S:
There are 10 section headers, starting at offset 0x190:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .the_header PROGBITS 00000000 000034 000009 00 A 0 0 1
[ 5] .comment PROGBITS 00000000 00003d 00001e 01 MS 0 0 1
[ 6] .ARM.attributes ARM_ATTRIBUTES 00000000 00005b 000033 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 00008e 000051 00 0 0 1
[ 8] .symtab SYMTAB 00000000 0000e0 000090 10 9 8 4
[ 9] .strtab STRTAB 00000000 000170 00001e 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
(Note section #4.)
Now, if I specify -flto to the GCC invocation, this section is no longer emitted!
There are 19 section headers, starting at offset 0x730:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .gnu.lto_.profile PROGBITS 00000000 000034 00000f 00 E 0 0 1
[ 5] .gnu.lto_.icf.93e PROGBITS 00000000 000043 000017 00 E 0 0 1
[ 6] .gnu.lto_.jmpfunc PROGBITS 00000000 00005a 00000f 00 E 0 0 1
[ 7] .gnu.lto_.inline. PROGBITS 00000000 000069 00000f 00 E 0 0 1
[ 8] .gnu.lto_.purecon PROGBITS 00000000 000078 00000f 00 E 0 0 1
[ 9] .gnu.lto_.symbol_ PROGBITS 00000000 000087 000022 00 E 0 0 1
[10] .gnu.lto_.refs.93 PROGBITS 00000000 0000a9 00000f 00 E 0 0 1
[11] .gnu.lto_.decls.9 PROGBITS 00000000 0000b8 000239 00 E 0 0 1
[12] .gnu.lto_.symtab. PROGBITS 00000000 0002f1 00001d 00 E 0 0 1
[13] .gnu.lto_.opts PROGBITS 00000000 00030e 0000e8 00 E 0 0 1
[14] .comment PROGBITS 00000000 0003f6 00001e 01 MS 0 0 1
[15] .ARM.attributes ARM_ATTRIBUTES 00000000 000414 000033 00 0 0 1
[16] .shstrtab STRTAB 00000000 000447 00018c 00 0 0 1
[17] .symtab SYMTAB 00000000 0005d4 000130 10 18 17 4
[18] .strtab STRTAB 00000000 000704 00002c 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
My linker script does not find the .the_header section, resulting in a corrupt binary.
I have tried specifying __attribute__((used)) for the header variable, with no effect.
Here's the relevant part of the linker script:
ENTRY(main)
MEMORY
{
APP (rwx) : ORIGIN = 0, LENGTH = 65536
}
SECTIONS
{
.header :
{
KEEP(*(.the_header))
} > APP
...
}
How do I tell GCC to emit .the_header into the final binary when using link time optimization and the above linker script snippet?

Resources