Windbg stacktrace shows line numbers before or after macro expansion - c

I have a C file with several macros.
The exe generated from the file crashes several times reporting events in the Windows event viewer. Upon taking a dump of the process and analyzing it using WinDbg with the correct pdb files for the symbols, we get the stacktrace and know the function which is causing the problem.
The stacktrace shows the line number of our function code which called other functions one of which led to the crash-
08 msvcr80!fwrite(void * buffer = 0x00000000`01ded180, unsigned int64 size =
0x1fff38, unsigned int64 count = 0x524fe123, struct _iobuf * stream =
0x00000000`00000000)+0x5f [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\fwrite.c
# 77]
09 <function name>(void * param = 0x00000000`02d15a00)+0xb02
[<path to file> # 1516]
Our function called fwrite, which is shown to be at line 1516. However, there is no call to fwrite at 1516. (The crash happens because the stream argument to fwrite is 0x0)
I was wondering if these line numbers correspond to the source file after the macros are expanded ? What could be the reason for a possibly wrong line number ?
EDIT : The exe here is a debug build and was compiled with optimizations disabled.
I loaded the dump again in WinDbg but also linked in the source file to WinDbg itself this time. It points to line 1516 and upon viewing that in the source from WinDbg, it points to a line where there is no call to fwrite. However, there is such a call a few lines above.

Well i do not have direct answer to question here :(
But i would make a COD file. a file that maps source code to assembly code. Then see the assembly code generated for the function of interest. Specifically related to line 1516.
Am hoping that would give a fair insight as to whats going on behind the scene. You may want to give a quick try.
You just need to turn on a compiler flag to generate COD file. More can be read here

Related

Writing in the executable while running the program

I'm writing a C program and I would like to be able to store data inside the executable file.
I tried making a function to write a single byte at the end of the file but it looks like it can't open the file because it reaches the printf and then gives "segmentation fault".
void writeByte(char c){
FILE *f;
f = fopen("game","wb");
if(f == 0)
printf("\nFile not found\n");
fseek(f,-1,SEEK_END);
fwrite(&c,1,sizeof(char),f);
fclose(f);
}
The file is in the correct directory and the name is correct. When I try to read the last byte instead of writing it works without problems.
Edit: I know I should abort the program instead of trying to write anyway but my main problem is that the program can't open the file despite being in the same directory.
There are several unrelated problems in your code and the problem you're trying to solve.
First you lack proper error handling. If any function that can fail (like e.g. fopen) fails, you should act accordingly. If, for example you did
#include <error.h>
#include <errno.h>
...
f = fopen("game","wb");
if ( f == NULL ) {
error(1,errno,"File could not be opened");
}
...
You would have recieved an useful error message like
./game: File could not be opened: Text file busy
You printed a message, which is not even correct (the file not beeing able to be opened is somthing different, than not beeing found) and continued the program which resulted in a segmentation fault because you dereferenced the NULL pointer stored in f after the failure of fopen.
Second As the message tells us (at least on my linux machine), the file is busy. That means, that my operating system does not allow me to open the executable I'm running in write mode. The answers to this question lists numerous source of the explanation of this error message. There might be ways to get around this and open a running executable in write mode, but I doubt this is easy and I doubt that this would solve your problem because:...
Third Executable files are stored in a special binary format (usually ELF on Linux). They are not designed to be manually modified. I don't know what happens if you just append data to it, but you could run into serious problems if your not very careful and know what you're doing.
If you just try to store data, use another plain and fresh file. If you're hoping to append code to an executable, you really should gather some background information about ELF files (e.g. from man elf) before continuing.

Is it possible to create an executable file with just copying the text segment?

When you run a C program, is it possible to get its binary code (which you execute with ./foo) from its TEXT segment? If I just copy all the TEXT segment to a file, then can I execute it and run the same program? I am working with Ubuntu.
is it possible to get it binary code
If you run your program under the debugger, then you can copy the bytes from anywhere in the process space, being data or code.
then i can execute it and run the same program?
Simple answer: No!
An executable file is a lot more than just a memory dump.
If your program is static-linked and position-dependent and has no global data (note: the last is not true with any non-toy libc implementation), then in theory the text segment is sufficient to run it. However, you would need an appropriate loader to do so. Normal operating systems' executable file loaders do not load this kind of "raw text segment" as an executable because (1) is has no header information to indicate that that's what it is, or even where to start execution at (i.e. what's the entry point), and (2) it's not generally useful to do so. DOS had something akin to this with .COM files, and uClinux had FLAT binaries that were close to this but with some minimal header, but those are the closest you'll find to a "raw text segment" binary in the past 3-4 decades.
there is the link with familiar question
Is it possible to dissembler running process in Linux?
char *comp = "objdump -d /proc/1234/exe";
fflush(NULL); // always useful before system(3)
int nok = system(comp);
if (nok) {
fprintf(stderr, "compilation %s failed with %d\n", comp, nok);
exit(EXIT_FAILURE);
}
So what i want is a /proc/<PID>/exe file.

using GDB with arguments

For a class assignment we needed to write a compiler. This includes an optimizer portion. In other words, we take in a file with some "code". An output file is generated. In the second step we take in the outputted code and remove any "dead" code and re-output to a second file. I have some problems with the optimizer portion and would like to use gdb. But I can't get gdb to operate properly with the input and output files arguments. The way we would normally run the optimizer is:
./optimize <tinyL.out> optimized.out
where tinyL.out is the file outputted in the first step and optimized.out is the file I want to output with the new optimized and compiled code.
I have searched Google for the solution and the tips I have found do not seem to work for my situation. Most people seem to want to only accept an input file and not output a separate file as I need to do.
Any help is appreciated (of course)
I'm not exactly sure what you're asking. But since I'm not yet able to comment everywhere, I write this answer with a guess and edit/delete if necessary.
When GDB is started and before you start the program you wish to debug, set the arguments you want to use with set args.
A reference to the documentation.
You just need to do the file redirection within gdb.
gdb ./optimize
(gdb) run < tinyL.out > optimized.out
https://stackoverflow.com/a/2388594/5657035

Eclipse CDT: Mapping console output to source file and line

While debugging code it helps to have source filename and line number on console output. I already use FILE and LINE macros. But it would be great if double clicking a line in the console output would take me to the exact source line which was responsible for outputting that line of log. Can eclipse parse console output and do something like this? It need not work all the time, only when the log line is in a specific format and the source filename and line number are valid.
It's possible to use a workaround if you add the pydev plugin and a few lines of python to call your main function. You can find the needed code here: https://github.com/oct15demo/python_calls_cpp
As noted there, I posted a query on the Eclipse forum to find out the status of any ongoing effort or obstacles to implement within Eclipse.
I could not find out any further information on the feature, if it's there, it's well hidden.
Update March 17, 2022, I shall be working on the feature for Eclipse, don't have an estimate of time yet.

#ifdef KERNEL2x & file_operations(..,..,..,..) , ssize_t function,printk()

Hi I have several questions. I will be glad if someone will answer :)
I'm trying to compile linux driver for an lcd 16X2 module.
I'm trying to use in my code the struct file_operations();
1. I notice by other codes that they add #ifdef KERNEL21 to compile. I tryed to this and I got much less errors. why it's work this way. im using kernel 2.6.18-128.4.1.el5.. soo do I need to change to #ifdef KERNEL26? I get more errors if I try to do soo.
2.some of the file_operation arguments are function the rtuen ssize_t. what is this mean? in other code eample there is also "#ifdef KERNEL21" but still I get an error:
"lcd_module.c:74: error: expected identifier or ג(ג before ג{ג token"
3.last qustion, I worked with a Makfile example and I get .o file and not .ko that im use to work with. how do I run the module with the .o file?
thank on advance :)
ssize_t is basically a signed size_t and is widely used in the kernel because values less than zero are used to return errors in places where an unsigned size is expected. For example, the read file operation is expected to return the number of bytes read, but in case of insufficient memory you can return -ENOMEM and errno will be set appropriately in the user-space program.
With the 2.6 kernel you are supposed to use the Makefile from the kernel-headers package rather than a hand-crafted one, and it produces a .ko file rather than an .o. Further reading here: http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html

Resources