Does any program compiled with the -g command have its source code available for gbd to list even if the source code files are unavailable?? Also when you set the breakpoints at a line in a program with a complicated multi source file structure do you need the names of the source code files??
OP's 1st Question:
Does any program compiled with the -g command have its source code available for gbd to list even if the source code files are unavailable??
No. If there is no path to the sources, then you will not see the source.
OP's 2nd Question:
[...] when you set the breakpoints at a line in a program with a complicated multi source file structure do you need the names of the source code files??
Not always. There are a few ways of setting breakpoints. The only two I remember are breaking on a line or breaking on a function. If you wanted to break on the first line of a function, use
break functionname
If the function lives in a module
break __modulename_MOD_functionname
The modulename and functionname should be lowercase, no matter how you've declared them in the code. Note the two underscores before the module name. If you are not sure, use nm on the executable to find out what the symbol is.
If you have the source code available and you are using a graphical environment, try ddd. It stops me swearing and takes a lot of guesswork out of gdb. If the source is available, it will show up straight away.
Related
I need to compile a Chicken Scheme project containing multiple source files, but I'm getting errors.
According to the manual and this SO answer, I need to put (declare)s in my sources. Why the compiler can't just see that I'm importing the other source is beyond me, but meh.
The problem is, even if I put the (declare)s in, the compiler complains about the (import)s and (use)s.
infinity.filesystem.scm:
(use bindings filepath posix)
(declare (uses infinity.general.scm))
(load-relative "infinity.general.scm")
(module infinity.filesystem (with-open-file make-absolute-path with-temporary-directory with-chdir)
(import scheme filepath posix infinity.general)
(begin-for-syntax
(use bindings chicken)
(import infinity.general))
...etc...
infinity.general.scm:
(declare (unit infinity.general.scm))
(require-extension srfi-1 srfi-13 format data-structures ansi-escape-sequences basic-sequences)
(module infinity.general (bind+ format-ansi repeat-string join-strings pop-chars! inc! dec!
take* drop* take-right* drop-right* ends-with? take-where)
(import scheme chicken srfi-1 srfi-13 data-structures ansi-escape-sequences basic-sequences bindings ports format)
...etc...
Command:
$ csc -uses bindings.o -uses infinity.general.o -c infinity.filesystem.scm -o infinity.filesystem.o
Compiler says:
Syntax error (import): cannot import from undefined module
and
unbound variable: use
If I just remove the import and use declarations for "infinity.general", the file compiles. However, I have two problems with this:
Will the resulting .o file actually work, in the absence of import and use clauses? Or will it complain about missing code at runtime?
csi requires that my code contains (import) and (use) declarations, whereas csc requires that it does not. I, however, require that my code works in both csi and csc!
How can I solve this, please?
Why the compiler can't just see that I'm importing the other source is beyond me, but meh.
Declares are used to determine dependencies: the compiler needs to know in what order (and if at all) to invoke a particular toplevel, to ensure the right code is initialized before any of the globals from that unit can be used. When everything is being compiled separately, the compiler wouldn't know when to insert calls to toplevels. The -uses switch you pass to csc is redundant: csc -uses foo is equivalent to putting (declare (uses foo)) in the source code. Passing -uses foo.o doesn't do anything with the file foo.o as far as I can tell.
In your code snippet, you're using load, which is not the correct way to include code at compile-time: load will read and evaluate the target file at run time. Instead, you should omit the load completely: the declare already takes care of the dependency; you just need to link them together.
Also, it's not very common to use filenames as module/unit names, though it should work.
If I just remove the import and use declarations for "infinity.general", the file compiles. However, I have two problems with this:
1) Will the resulting .o file actually work, in the absence of import and use clauses? Or will it complain about missing code at runtime?
You'll need to keep the import expressions, or the program shouldn't compile. If it does compile, there's something strange going on. You don't need use when you link everything together statically. If you're using dynamic linking, you will get a runtime error.
The error you get about unbound variable: use is because you're using use in a begin-for-syntax block. You'll probably just need to (import-for-syntax chicken), as per your other SO question.
2) csi requires that my code contains (import) and (use) declarations, whereas csc requires that it does not. I, however, require that my code works in both csi and csc!
It looks like you're approaching this too quickly: You are writing a complete program and at the same time trying to make it run compiled and interpreted, without first building an understanding of how the system works.
At this point, it's probably a good idea to experiment first with a tiny project consisting of two files. Then you can figure out how to compile an executable that works from code that also works in the interpreter. Then, use this knowledge to build the actual program. If at any point something breaks, you can always go back to the minimal case and figure out what you're doing differently.
This will also help in getting support, as you would be able to present a complete, but minimal set of files, and people will be able to tell you much quicker where you went wrong, or whether you've found a bug.
So, in Project AB I have FileA.fs and FileB.fs. FileB uses definitions from FileA, and both FileA and FileB use definitions from Project C (written in C#).
In FileA.FS, I have:
#if COMPILED
namespace ProjectAB
#else
#I "bin\debug"
#r "ProjectZ.dll"
#endif
...which works how it's supposed to -- I can run the whole file in F#-Interactive and it's great.
In FileB.fs, my header is:
#if COMPILED
module ProjectAB.ModuleB
#else
#load "FileA.fs"
#I "bin\debug"
#r "ProjectZ.dll"
#endif
But when I run this (from FileB), I get the error:
FileA.fs(6,1): error FS0222: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.
According to the fsi.exe reference, the #load directive "Reads a source file, compiles it, and runs it". But it seems like it must be doing so without the COMPILED directive defined, because it doesn't see the "namespace ProjectAB" declaration.
How can I set up my headers so that I can run either file in F#-interactive?
Edit Per latkin's answer below, I created a script as the last file in the project, _TestScript.fsx. I removed all the precompiler stuff from the other files and set this as the header of the .fsx file:
#if INTERACTIVE
#I "bin\debug"
#r "ProjectZ.dll"
#load "FileA.fs"
#load "FileB.fs"
#endif
When I run this in the interactive, it correctly loads ProjectZ, FileA, and FileB for me to access in the interactive window.
However, in _TestScript.fsx, I get squiggly red lines and no intellisense on any of the functions/types from the referenced files (including the "open" statements).
Is there something else I need to set up in the script file to make the intellisense work? (The answer might be pretty basic since I have not used .fsx files before.)
I don't think there is a way to do this smoothly. A few things to consider:
INTERACTIVE is always defined when you are being processed by fsi.exe, whether you are a .fsx, .fs, #load'ed, whatever. COMPILED is similarly always defined when you are being processed by fsc.exe. I can see how the quoted phrase from the docs maybe doesn't make this totally crystal clear.
You can only declare namespaces in fsi from a #load'ed file
So if you want your file to declare a namespace, and to work as the single file in interactive, then the namespace has to be #ifdef'ed out. But that also means the namespace will be #ifdef'ed out when the file is #load'ed...
You might be able to work around this by conditionally declaring it as a module, not a namespace. Or perhaps creating additional, more granular defines. It will be tricky.
Trying to get source files to work properly as part of a compiled library and simultaneously as single-file scripts is not easy, and I don't think the tooling was designed with this scenario in mind. More common is to have all of your library files behave purely as library files, then use dedicated standalone scripts which #loads the .fs files they need. This keeps the driving code and the library code separate, and things fit together more cleanly.
I've recently discovered clang++'s static analyzer feature, and it's fantastic for going over my code with a fine-toothed comb to find latent bugs. I just uncomment this line in my Makefile:
CXXFLAGS += --analyze -Xanalyzer -analyzer-output=text
et voila, I'm in deep-bug-checking mode.
One minor problem with this, however, is that whenever the analyzer does not find any problems in a particular .cpp file, doesn't produce any .o file.
Normally that wouldn't be a big deal (I can always re-comment the above line to build an actual executable), but usually when I see an analyzer-warning, the first thing I want to do is try to fix the underlying problem and then re-run make.
... which works, but since no .o files are being generated, make will start re-analyzing all the .cpp files again from the beginning, rather than just the .cpp files I actually modified since the previous run. This means I end up spending rather a lot of time re-checking .cpp files that haven't changed.
My question is, is there any way to get the static analyzer to output a .o file (it doesn't have to be a valid object file, just any file with an updated timestamp) so that Make will know that a "clean" .cpp file does not need to be re-processed? (i.e. make Make work the same way it does when doing a normal compile)
Check out the clang static analyzer page, and get the package there for download. You can use the included scan-build tool to do what you're trying.
The normal way to use is to get rid of the flags you have above and just run:
$ scan-build make whatever
And it should 'just work'. You might need to pass some more flags or set some environment variables if you don't use standard make variable names.
As we know, during debugging gdb could expand macro when special gcc options enabled.
But it is not convenient enough compared with debugging raw source code.
If there is a tool to expand macro in-place and replace the original source code for gcc to compile, that would be cool
If there is no such a tool, I'm going to create one and here are some rough ideas for your comments
Using "gcc -E" to compile the source code with macros and output the result to some temporary files, make some smart diff/compare between pre-processed file with original source file to extract the expanded source code and build a final source code whose macros have been expanded
One idea would be to use gcc -E, then edit the resulting .i file and remove the #line directives around the affected area. Then compile the .i file.
gcc+gdb could be made to debug macros as if they were inline functions, but I think that would be a fair amount of work in gcc.
Can any one tell me which function in gcc source code is responsible for finding a macro in C file and repalce it with actual value ?
I want to know the function as I have to take log by making changes to it, so that at the end my log file will contain where all macro is used and its line number .
It's done by the preprocessor, prior to generating the output file. If you want to see what it is doing, try gcc -E
From man gcc:
-E Stop after the preprocessing stage; do not run the compiler proper.
The output is in the form of preprocessed source code, which is sent to
the standard output.
I recommend using clang for this type of task. It is pretty well documented and you don't need to change its source, as it's extendable with a plugin system.
In your case you create a plugin based on the PPCallbacks class and override its MacroExpanded method, and any other method you find useful. This is an easy starting point.