This question is about determining the line number of the function >definition<
in its source file. Just to be clear:
It is NOT about determining the line number of a caller - been there, done that. It is NOT about determining the CURRENT line number - been there, done that. It is NOT about examining the source code for the function - been there, done that. It is NOT about finding the name/url of the file when a break occurs and the line number in that file of the offender at that time - been there done that. It is NOT about using Chrome/Firefox/DragonFly Dev Tools to locate the offender. It is NOT about PHP, etc. Original source code can not be modified - only the exception handler (or the constructor which is being passed the function/anonymous function).
Context - the code is already in a [dump information routine called from a] catch block. I am trying to dump the specific offending line.
I have the offending line number in the source file; I have the offending function's code parsed into lines/line numbers. Thus I have the offset INTO the function (which is often an anonymous function). If I can somehow determine the line number where a function was defined (without forcing another exception), then the offset allows me to dump the offending line.
But the rub is getting the origin from which to compute the offset into
the function.
Possibilities of execution context for determining this include:
1) when the (anonymous) function is referenced/defined as part of a constructor (note: referenced/defined, NOT called) - at which time, if the line number of the >definition< in its source can be determined, it can be saved in the object
being constructed and then used later in the exception handler.
2) in the exception handler.
Sorry about the verbiage, but there are a lot of answers out there which seemingly (via search heuristics) address this, but in fact, none of them address the specific problem here.
Any suggestions, any at all, or is this hunting for a unicorn?
Thx (1138)
There's nothing in the information available within a catch block that will tell you what line in the source file the function containing that catch block starts on. I'm afraid you are indeed hunting for a unicorn.
You could use a pre-processor on the code that would add that information for you, using a parser like Esprima or by writing yourself a Babel plugin to do it. They have access to the necessary semantic and textual information to inject the number of the source line starting the function into the call to your "dump information" function.
Related
JavaScript allows you to create new functions at runtime with the new Function(...) or eval. Is it possible for a function created in this way to set something like a source map? That is, set the name of the source file from which it was allegedly loaded, as well as different source line numbers.
If there is no general solution, then there may be particular solutions for specific JavaScript engines.
For eval'd code you can simply add:
//# sourceMappingURL=<url>
//# sourceURL=<filename.js>
To the bottom of the code you are evaluating. For the sourceMappingURL, you will send in a data url, since naturally you don't have an existing source map hosted somewhere and you will be dynamically generating it.
Place your original source in the sourcesContent field in the source map, set the file field in the source map to whatever you set in sourceURL, and you should be good to go.
My current attempts at getting this to work in Function constructors is failing, which is a shame- in this case, in both Edge and Chrome, the original source is correctly listed, but it appears that the line number information is broken (the instruction pointer always points to the last line). I am currently investigating this. However, the source map spec does allude to Function constructors containing sourcemaps:
If the generated code is being evaluated as a string with the eval() function or via new Function(), then the source origin will be the page’s origin.
This leads me to believe either I am doing something silly, or there is not great support for this feature.
I'm learning v8 now, but I have encountered some problems.
How to set a breakpoint a method's start address in memory if I want to debug a method's C++ implementation.
e.g. var a= new Array(0,1); a.indexOf(1) ; I want to set a breakpoint at slice's beginning, or are there other ways to track the assembler code ?
There are a lot of functions will be complied and writed into a file named snapshot.bin. so I can't set a breakpoint at the beginning of these functions.
You need to check the source code and find the implementation of slice. Then set a gdb/lldb break point in that .cc file: byiltins-typedarray.cc
A lot of functions are defined as builtin or runtime functions.
It depends on the kind of function you want to inspect.
You can compile without snapshot to get around snapshot-related debugging difficulties (at the cost of making startup quite a bit slower: several seconds in Debug mode).
You can modify the respective code generator to emit a break instruction at the beginning of the function. For the example of Array.indexOf, that's probably the easiest solution; the CodeStubAssembler instruction is called DebugBreak().
You can break somewhere else using GDB, find your way to the function in question (e.g. via isolate->builtins), and set a breakpoint on the address of its entry. (This requires a bit of V8 knowledge and/or code reading skills, but it's not difficult.)
You can use various --print-*-code flags to print code to stdout (without breaking on it).
As noted in Where to write and store mongoDB map/reduce functions in java project - Eclipse doesn't like a JavaScript (.js) file to only contain the following:
function(doc) {
if(doc.somekey) emit(doc._id, doc);
}
The keyword function is marked with an error:
Syntax error on token "function", Identifier expected after this token
This form is used in MapReduce, but perhaps it's not exactly valid JavaScript (I'm not a lawyer). Is there any way to allow this form?
edit it looks like it's a function expression instead of a function statement. ( MDN, ECMA-262 )
Non-solution: "Just add a function name" according to https://stackoverflow.com/a/11258388/185799 it seems that it's not important to economize on the size of these functions. However, adding a function name results in: {"error":"compilation_error","reason":"Compilation of the map function in the 'myView' view failed: Expression does not eval to a function."}
Possible solution? Add a function name or "module.exports = " at the top, and then remove it during a build phase, using grunt/gulp/yeoman or something related.
For now, what I am actually doing is using the literal form function anonymous(... and then doing a string replace just before calling synchronizeWithDb() to replace function anonymous( with function(. This doesn't answer my question, but works around it.
You have three bad options:
You can ignore the error since CouchDB can process this file (it will wrap it later to make it valid).
You can change the file extension but then you lose syntax highlight, code completion and error checks.
You can delete the error in the error view. It will stay deleted until you change the file the next time or you do a full build.
You may be able to configure Eclipse to stop validating the file.
There are two ways to implement #4:
You can ignore the resource. That makes this file invisible to Eclipse and all plugins. Which means you can't edit it anymore inside of Eclipse. Use Resource Filters for that.
You can check the per-project preferences for Validation rules for JavaScript. Maybe you can exclude the file.
Does anyone have any ideas how to do error handling on lazy loaded javascript? I am using an approach in which an ajax request is called and the code is eval'd in global scope. When a runtime error is struck, it spits out the filename as my lazy loading script and the line number is the error line plus the line number of my eval in my loading script. This wouldn't be so bad except all the javascript files get combined into modules for sections of the site. A try catch around the javascript file itself wont catch runtime errors of the functions. Any ideas? Window.onerror doesn't provide the correct filename so it is out of the question. I need to catch it before it is hit.
I was thinking maybe I could programmatically include try catches around all the functions within the eval'd code (which is ugly), but since it is done at the window level I am not sure how to access the eval'd code specifically and dynamically. Sure if the javascript is an object named "Bob" I can access window.Bob but I need to do it dynamically.
I solved the issue, however it is not the most elegant solution. Essentially what I do is this:
1. After the site loads I look at all the objects that are in window and push them into an array. This basically says to my code, ignore these objects.
When I modularize my code I keep track of the length of the files and fileNames being place into a module.
The last line of the modulizer takes the fileLength array and lineLengths and calls a function in my error handling object;
The error handling code finds new objects in window. If they exist, set a property to match fileLengths and fileNames;
Recurse through the new objects and add decorate the functions to have try catches around them.
When one of those catches is hit, traverse upward and find the properties.
Calculate the file and line number based on the properties.
Output the new error based on the correct file and line number;
Yes ugly... but it works.
I've built a custom logging utility which displays a Log Message and the DateTime. I would like to add the line number in the source code which called the function.
Is there a way to determine which line of the HTML source a particular javascript function was fired?
Having written a logging library (log4javascript) myself, I've considered this same problem and here are my thoughts:
The problem is that in order to get the information you want, you need an Error object that was created on the line in question. Creating an Error within your logging utility will only directly give you the filename and line number for the particular line in your logging utility code rather than for the line of code that made the logging call. The only way round this I can think of is parsing the stack property of the Error (or the message property in Opera), which has several problems:
the stack trace is only available in Mozilla, recent WebKit and Opera browsers
the stack trace is a string that varies from browser to browser, and may change format again without notice in future browsers, thus breaking the parsing code
throwing an Error and parsing its stack trace for every log call will add a significant performance overhead.
For the purposes of log4javascript, I decided it wasn't worth implementing, but for your own needs you may decide it's worthwhile.