GDB can not find line numbers - linux

I am using GDB for debugging a Linux kernel module.
After loading the module, i use add-symbol-file to add module symbols.
When i use list command in GDB to find a symbol in module, it will find it for example:
(gdb) list __do_restart
122 * would provide type of error or success. In the case of early restart support from
123 * cr_mods a signal will be posted at appropriate time.
124 *
125 * NOTE: This type of restarting could be used for migrating parallel processes.
126 */
127 int __do_restart(void *data){
128 struct siginfo info;
129 struct object_stored_data *sd;
130 struct crmod_clients *clt = get_client(data);
131 memset(&info, 0, sizeof(struct siginfo));
(gdb) b __do_restart
Breakpoint 1 at 0xe081740e: file /home/amrzar/Workspace/common/commod.c, line 130.
I can even set a breakpoint for it. But after the first interrupt in execution when i use list it says:
(gdb) list __do_restart
No line number known for __do_restart
It simply lost symbols! Why? (I am sure about presence of debugging information in object file)
Thanks

I do not really know what causes this problem but once I had same trouble using add-symbol-file but adding -readnow option solved it for me!

Related

How to suppress warnings messages in Rcpp/RcppArmadillo functions

I am using RcppArmadillo within an R package. I want to suppress a warning message that occurs in a C++ function due to numerical precision when a symmetric matrix fails a test of symmetry within eig_sym(). I am confident this is a precision issue as I have saved some of the matrices hitting this warning and tested them in R using isSymmetric() and they pass this.
I have tried including #define ARMA_WARN_LEVEL 0 at the top of the header file where the function with this issue is defined, but this does not solve my issue and I am told 'ARMA_WARN_LEVEL' macro redefined (presumably it is defined in the config file of RcppArmadillo).
Ideally I would suppress only errors associated with this call of eig_sym, but failing this I am content to suppress all warnings. If anyone can advise on how to effect this I would be very grateful.
Thank you.
Looking at Armadillo's config.hpp -- the first header file included by Armadillo -- we see that it starts with
#if !defined(ARMA_WARN_LEVEL)
#define ARMA_WARN_LEVEL 2
#endif
//// The level of warning messages printed to ARMA_CERR_STREAM.
//// Must be an integer >= 0. The default value is 2.
//// 0 = no warnings
//// 1 = only critical warnings about arguments and/or data which are likely to lead to incorrect results
//// 2 = as per level 1, and warnings about poorly conditioned systems (low rcond) detected by solve(), spsolve(), etc
//// 3 = as per level 2, and warnings about failed decompositions, failed saving/loading, etc
so a simple
#define ARMA_WARN_LEVEL 0
#include <RcppArmadillo.h>
should take care of things. We cannot "show" this as we have no reproducible example to work with.
Also note that there is a good reason why warnings are usually on. They signal something you as author should be aware of.

Extend section in Mach-O file

I am trying to extract libraries from the Dyld_shared_cache, and need to fix in external references.
For example, the pointers in the __DATA.__objc_selrefs section usually point to data outside the mach-o file, to fix that I would have to copy the corresponding c-string from the dyld and append it to the __TEXT.__objc_methname section.
Though from my understanding of the Mach-O file format, this extension of the __TEXT.__objc_methname would shift all the sections after it and would force me to fix all the offsets and pointers that reference them. Is there a way to add data to a section without breaking a lot of things?
Thanks!
Thanks to #Kamil.S for the idea about adding a new load command and section.
One way to achieve adding more data to a section is to create a duplicate segment and section and insert it before the __LINKEDIT segment.
Slide the __LINKEDIT segment so we have space to add the new section.
define the slide amount, this must be page-aligned, so I choose 0x4000.
add the slide amount to the relevant load commands, this includes but is not limited to:
__LINKEDIT segment (duh)
dyld_info_command
symtab_command
dysymtab_command
linkedit_data_commands
physically move the __LINKEDIT in the file.
duplicate the section and change the following1
size, should be the length of your new data.
addr, should be in the free space.
offset, should be in the free space.
duplicate the segment and change the following1
fileoff, should be the start of the free space.
vmaddr, should be the start of the free space.
filesize, anything as long as it is bigger than your data.
vmsize, must be identical to filesize.
nsects, change to reflect how many sections your adding.
cmdsize, change to reflect the size of the segment command and its section commands.
insert the duplicated segment and sections before the __LINKEDIT segment
update the mach_header
ncmds
sizeofcmds
physically write the extra data in the file.
you can optionally change the segname and sectname fields, though it isn't necessary. thanks Kamil.S!
UPDATE
After clarifing with OP that extension of __TEXT.__objc_methname would happen during Mach-O post processing of an existing executable I had a fresh look on the problem.
Another take would be to create a new load command LC_SEGMENT_64 with a new __TEXT_EXEC.__objc_methname segment / section entry (normally __TEXT_EXEC is used for some kernel stuff but essentially it's the same thing as __TEXT). Here's a quick POC to ilustrate the concept:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
printf("%lx",[NSObject new]);
}
return 0;
}
Compile like this:
gcc main.m -c -o main.o
ld main.o -rename_section __TEXT __objc_methname __TEXT_EXEC __objc_methname -lobjc -lc
Interestingly only ld up to High Sierra 10.14.6 generates __TEXT.__objc_methname, no trace of it on Catalina, it's done differently.
UPDATE2.
Playing around with it, I noticed execution rights for __TEXT segment (and __TEXT_EXEC for that matter) are not required for __objc_methname to work.
Even better specific segment & section names are not required:
I could pull off:
__DATA.__objc_methname
__DATA_CONST.__objc_methname
__ARBITRARY.__arbitrary
or in my case last __DATA section
__DATA.__objc_classrefs where the original the data got concatenated by the selector name.
It's all fine as long as a proper null terminated C-string with the selector name is there. If I intentionally break the "new\0" in hex editor or MachOView I'll get
"+[NSObject ne]: unrecognized selector sent to instance ..."
upon launching my POC executable so the value is used for sure.
So to sum __TEXT.__objc_methname section itself is likely some debugger hint made by the linker. The app runtime seems to only need selector names as char* anywhere in memory.

Include binary file in as86/bin86

I have written a bit of code in i8086 assembler that is supposed to put a 80x25 image into the VRAM and show it on screen.
entry start
start:
mov di,#0xb800 ; Point ES:DI at VRAM
mov es,di
mov di,#0x0000
mov si,#image ; And DS:SI at Image
mov cx,#0x03e8 ; Image is 1000 bytes
mov bl,#0x20 ; Print spaces
; How BX is used:
; |XXXX XXXX XXXXXXXX|
; ^^^^^^^^^ BL contains ascii whitespace
; ^^^^ BH higher 4 bits contain background color
; ^^^^ BH lower 4 bits contain unused foreground color
img_loop:
seg ds ; Load color
mov bh,[si]
seg es ; Write a whitespace and color to VRAM
mov [di],bx
add di,#2 ; Advance one 'pixel'
sal bh,#4 ; Shift the unused lower 4-bits so that they become background color for the 2nd pixel
seg es
mov [di],bx
add di,#2
add si,#1
sub cx,#1 ; Repeat until 1 KiB is read
jnz img_loop
endless:
jmp endless
image:
GET splash.bin
The problem is that I cannot get the as86 assembler to include the binary data from the image file. I have looked at the the man page but I could not find anything that works.
If I try to build above code it gives me no error, but the output file produced by the linker is only 44 bytes in size, so clearly it did not bother to put in the 1000 byte image.
Can anybody help me with that? What am I doing wrong?
I am not certain that this will help you, as I have never tried it for 8086 code. But you might be able to make it work.
The objcopy program can convert binary objects to various different formats. Like this example from the man objcopy page:
objcopy -I binary -O <output_format> -B <architecture> \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
<input_binary_file> <output_object_file>
So from that you'd have an object file with your <input_binary_file> in a section named .rodata. But you could name it whatever you wanted. Then use a linker to link your machine code to the image data.
The symbol names are created for you too. Also from the man page:
-B
--binary-architecture=bfdarch
Useful when transforming a architecture-less input file into an object file. In this case the output architecture can be set to
bfdarch. This option will be ignored if the input file has a known
bfdarch. You can access this binary data inside a program by
referencing the special symbols that are created by the conversion
process. These symbols are called _binary_objfile_start,
_binary_objfile_end and _binary_objfile_size. e.g. you can transform a picture file into an object file and then access it in your code using
these symbols.
If your whole code is pure code (no executable headers, no relocation...) you can just manually concatenate the image at the end of the code (and of course remove GET splash.bin). In Linux for example you can do cat code-binary image-binary > final-binary.
Thank you everybody else trying to help me. Unfortunately I did not get the objcopy to work (maybe I am just too stupid, who knows) and while I actually used cat at first, I had to include multiple binary files soon, which should still be accessible via labels in my assembler code, so that was not a solution either.
What I ended up doing was the following: You reserve the exact amount of bytes in your assembler source code directly after the label you wanna put in your binary file, i.e.:
splash_img:
.SPACE 1000
snake_pit:
.SPACE 2000
Then you assemble your source code creating a symbol table by adding the -s option, i.e. -s snake.symbol to your call to as86. The linker call does not change. Now you have a binary file that has a bunch of zeroes at the position you wanna have your binary data, and you have a symbol table that should look similar to this:
0 00000762 ---R- snake_pit
0 0000037A ---R- splash_img
All you gotta do now is get a program to override the binary file created by the linker with your binary include file starting at the addresses found in the symbol table. It is up to you how you wanna do it, there are a lot of ways, I ended up writing a small C program that does this.
Then I just call ./as86_binin snake snake.symbols splash_img splash.bin and it copies the binary include into my linked assembler program.
I am sorry for answering my own question now, but I felt like this is the best way to do it. It is quite unfortunate bin86 doesn't have a simple binary include macro on its own. If anybody else runs into this problem in the future, I hope this will help you.

Segmentation fault opening a file in ADA

I have to port some legacy software written in ADA from Windows to Linux. The program compiles fine, but terminates with a segmentation fault when executed.
The segfault occurs when the program tries to open a file (the file exists ;). Strange to say, the program succeeds in opening another file earlier in the execution without an error. Both files are binary files.
Stepping through the program with gdb, I could track down the last line executed to
DIO.Open (FP (File), To_FCB (Mode), Name, Form);
which is defined in a-direio.adb, line 167.
How can I further investigate the cause of the fault? The values of the parameters to DIO.Open look OK (they are the same as for the previous successful call to DIO.Open, except for the file name). Any hints are appreciated.
Edit
Here is the code that eventually calls DIO.Open:
procedure Open
(The_File : in out File_Type;
The_Mode : in A_DB_Mode := DBS_Database_Types.InOut_DB;
The_Name : in String;
The_Form : in String := "") is
begin
Ada_File_IO.Open
(File => The_File,
Mode => DB_Mode_To_File_Mode(The_Mode),
Name => The_Name,
Form => The_Form);
exception
when Ada_File_IO.Status_Error => raise Status_Error;
when Ada_File_IO.Name_Error => raise Name_Error;
when Ada_File_IO.Use_Error => raise Use_Error;
end Open;
where ADA_File_IO is declared as
package Ada_File_IO is
new Ada.Direct_IO(Element_Type => GNL_Universal_Representation.An_Item);
GNL_Universal_Representation.An_Item resolves to
subtype An_Item is GNL_Basic_Types.A_Byte;
type A_Byte is mod 2**Byte_Size;
and DB_Mode_To_File_Mode(The_Mode) resolves to Ada_File_IO.In_File.
Edit (2)
This is the gdb output with some filenames (as suggested by Brian)
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb563db40 (LWP 9887)]
0x081053af in system.file_io.open ()
(gdb) bt
#0 0x081053af in system.file_io.open ()
#1 0x080fd447 in system.direct_io.open ()
#2 0x08066182 in dbs_file.ada_file_io.open (file=0x0, mode=in_file, name=...,
form=...)
at /media/chmiwah/ADA/lib/gcc/i686-pc-linux-gnu/4.7.4/adainclude/a-direio.adb:167
#3 0x080665cc in dbs_file.open (the_file=0x0, the_mode=in_db, the_name=...,
the_form=...)
at /media/chmiwah/GISMO/bbp-benchmark/code/rebsys/src/dbs/ntv/bdy/dbs_file.adb:108
#4 0x080631b0 in dbs_database.open (the_database=0xb5500468, the_mode=in_db,
the_name=..., the_form=..., using_the_definition=0xb5646008)
at /media/chmiwah/GISMO/bbp-benchmark/code/rebsys/src/dbs/gnc/bdy/dbs_database.adb:363
I see you are using a multi-threaded program. When using gdb, note that 'bt' will not be terribly useful, as it only shows one thread (I can't rememeber if this is the main thread or the current thread).
Instead, using the following:
thread apply all bt
or
thread apply all bt full
Also, using strace -f -e trace=file your_program args will be useful to determine if the fault comes before or after the system call to open.
It would be quite useful to know what version of the compiler you are using, and what options were used to build it (esp. if any warnings were disabled).
Are the filename encoding anything more or less than US-ASCII?

New syscall not found (linux kernel 3.0.0) where should I start looking?

I created two new syscalls, but when I try to test them I get the following error:
matt#ubuntu:~/test$ gcc test.c
test.c: In function ‘newcall’:
test.c:6:17: error: ‘sys_get_slob_amnt_free’ undeclared (first use in this function)
test.c:6:17: note: each undeclared identifier is reported only once for each function it appears in
matt#ubuntu:~/test$
I also tried this with syscall(sys_get_slob_amnt_free) with the same result.
Here is the test code:
#include <unistd.h>
#include <stdio.h>
unsigned long newcall()
{
return syscall(__NR_get_slob_amnt_free);
}
int main()
{
printf("%d\n", newcall());
return 0;
}
In order to add these I put them in the syscall table
(/usr/src/linux-3.0/include/asm-generic/unistd.h)
#define __NR_sendmmsg 269
__SC_COMP(__NR_sendmmsg, sys_ sendmmsg, compat_sys_sendmmsg)
/** my changes here **/
#define __NR_get_slob_amnt_free 270
__SYSCALL(__NR__get_slob_amnt_free, sys_get_slob_amnt_free)
#define __NR_get_slob_amnt_claimed 271)
__SYSCALL(__NR_get_slob_amnt_claimed, sys_get_slob_amnt_claimed)
/** /my changes **/
#undef __NR_syscalls
#define __NR_syscalls 272
And here is the code for the calls themselves (../linux-3.0/mm/slob.c)
asmlinkage unsigned int sys_get_slob_amnt_claimed()
{
return memClaimed;
}
asmlinkage unsigned int sys_get_slob_amnt_free()
{
return memClaimed - memUsed;
}
I'm trying to figure out whether I'm botching the test code (maybe I need to include something more? or link something?) Or if I've overlooked something in adding the syscall in the first place. With the amount of time it takes to recompile the kernel, it would really help me out to know where to start looking.
Admittedly, this is related to a homework assignment. The assignment is about modifying slob.c, which I have a pretty good handle on. I'm just doing this to get a peek at whether the modifications I've made so far are going anywhere. I appreciate any guidance you can give. Thanks!
Edit: Solved (or at least solved enough for me).
Many thanks to bdonlan! Although syscall(270) didn't do it directly, it jogged my memory--there is another set of relevant numbers that I was neglecting entirely. The file /linux-3.0/arch/x86/kernel/syscall_table_32.c needed to be modified as well in order to properly add the syscall.
Once I added .long sys_get_slob_amnt_free and .long sys_get_slob_amnt_claimed to that file and rebuilt the kernel, I could hit my syscalls by using syscall(###) where ### is the numbering in syscall_table_32.c (not the numbering in unistd.h). I feel like they should match--but since this is just glorified debug information I think I'll leave that mystery for another time and just call it good.
There is another set of relevant numbers that I was needed to add. The file /linux-3.0/arch/x86/kernel/syscall_table_32.c needed to be modified as well in order to properly add the syscall.
Once I added .long sys_get_slob_amnt_free and .long sys_get_slob_amnt_claimed to that file and rebuilt the kernel, I could hit my syscalls by using syscall(###) where ### is the numbering in syscall_table_32.c (not the numbering in unistd.h)

Resources