编辑:警告 - 我现在意识到以下技术通常被认为是一个坏主意,因为它为了看起来整洁而创建隐藏的依赖项.
我最近发现您可以使用StackTrace来推断有关方法调用者的信息.
这使您可以创建一个看似"酷"的API,您只需调用一个方法而无需将任何显式参数传递给它,并且该方法可以根据StackTrace计算出该做什么.
这是一件坏事,如果是这样,为什么?
例:
public class Cache {
public Object CheckCache()
{
Object valueToReturn = null;
string key = GenerateCacheKeyFromMethodPrototype(new StackTrace().GetFrame(1).GetMethod()); //frame 1 contains caller
if(key is in cache) valueToReturn = itemFromCache;
return valueToReturn;
}
}
public class Foo {
private static Cache cache = new Cache();
public Blah MethodFoo(param1, param2...)
{
Blah valueToReturn = cache.CheckCache(); //seems cool!
if(valueToReturn == null)
{
valueToReturn = result of some calculation;
//populate cache
}
return valueToReturn;
}
}
Run Code Online (Sandbox Code Playgroud)
我确定上面的伪代码有错误,但你得到了我的漂移.
编辑:感谢大家的回复.
我得到一个"对象引用没有设置为对象的实例"错误,日志中的堆栈顶部有以下内容(C#ASP.NET应用程序):
@Web.UI.UserBrochurePage.Page_Load(Object,EventArgs)+25 Line: 0
@System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr,Object,Object,EventArgs)+0 Line: 0
@System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object,EventArgs)+26 Line: 0
@System.Web.UI.Control.OnLoad(EventArgs)+38 Line: 0
@System.Web.UI.Control.LoadRecursive()+35 Line: 0
@System.Web.UI.Page.ProcessRequestMain(Boolean,Boolean)+1160 Line: 0
Run Code Online (Sandbox Code Playgroud)
我不明白的事情:
这是一个处于发布模式的生产系统,但我仍然可以从堆栈跟踪对象中获取行号.在这种情况下,遗憾的是,错误不会在我们的调试系统上重现,因此我坚持不懈地使用它.
任何意见,将不胜感激.
谢谢,汤姆
数据库服务器从 12.5x 版迁移到 15.03 版 Sybase.Data.AseClient 版 - 1.15.50.0
当我通过 .Net 应用程序运行几个存储过程时,我遇到了异常(使用 AseClient)
内部错误:30016 Unknown Dataitem Dataitem 堆栈跟踪 - 在 Sybase.Data.AseClient.AseDataReader.CheckResult(Int32 res) 在 Sybase.Data.AseClient.AseDataReader.RetrieveNextResult() 在 Sybase.Data.AseClient.AseDataReader.GetNextResult() 在 Sybase.Data.AseClient.AseDataReader.NextResult() 在 Sybase.Data.AseClient.AseDataReader.CloseUrsHandle() 在 Sybase.Data.AseClient.AseDataReader.Close() 在 Sybase.Data.AseClient.AseDataReader.Dispose(Boolean disposing) 在 Sybase.Data.AseClient.AseDataReader.Dispose() 在 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand 命令, CommandBehavior 行为) 在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand 命令, CommandBehavior 行为) 在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable) 在 HSBC.STPMapper.SybaseDAL.Utilities.SybaseHelper.ExecuteDataset(CommandType commandType, String commandText, DataSet dataset, String table, AseParameter[] …
我正在分析java中的堆栈跟踪转储,并且不知道我怎么知道哪些线程实际上正在运行.我看到一个线程的方式是运行,等待锁,睡觉或等待安排.
在我的堆栈跟踪中,我看到以下状态
java.lang.Thread.State: WAITING (on object monitor)
java.lang.Thread.State: RUNNABLE
java.lang.Thread.State: TIMED_WAITING (sleeping)
java.lang.Thread.State: WAITING (parking)
java.lang.Thread.State: TIMED_WAITING (parking)
Run Code Online (Sandbox Code Playgroud)
首先,这些状态到底意味着什么?
其次,我有11个线程,runnable其中两个正在等待条件.这是否意味着9个线程同时运行?这似乎不可能,因为我的机器没有那么多的核心.
我有一个Foo带有方法的类SomeMethod()。在SomeMethod()我跑:Bar bar = new Bar(); bar.BBQ();。在其中BBQ(),我调用了Name(n)引发异常消息的私有方法new StackTrace().GetFrame(n).GetMethod().Name。
我的意图是将 1 传递给 Name(n),以便它返回值“BBQ”。但是,Name(0) 返回“Name”,Name(1) 返回“SomeMethod”。在抛出异常导致的堆栈跟踪中,它也读起来好像 Name 是由 SomeMethod 直接调用的(没有提到 BBQ)。
有没有解决的办法?有谁知道是什么导致了这个错误?是否有更好的方法来完成从 Name 中获取值“BBQ”?
[TestClass]
public class Foo
{
public Foo()
{
}
[TestMethod]
public void SomeMethod()
{
Bar bar = new Bar();
bar.BBQ();
}
}
public class Bar
{
public Bar()
{
}
public void BBQ()
{
Name( 1 );
}
private void Name( int n )
{ …Run Code Online (Sandbox Code Playgroud) 我有一个python脚本工作在无限循环,脚本做了几件事,并使用类中的几个方法,将信息记录到我拥有的几个记录器,并与SQS亚马逊队列一起使用.像这样的东西:
A = ClassA()
B = ClassB()
C = ClassC()
while True:
# pull messages from SQS
messages = sqs.pull_messages()
logger.info('Pulled messages from SQS')
A.do_something(messages)
logger.info('Doing something on class A')
# download something from the internet
data = B.download_something()
logger.info('Downloaded something')
C.insert_to_database()
Run Code Online (Sandbox Code Playgroud)
该脚本可以正常工作几天而不会耗尽内存或退出脚本因为回溯,我在我的Linux框中启动了这样的脚本:
python script.py &
Run Code Online (Sandbox Code Playgroud)
几天之后,我可以回到盒子里,发现脚本仍在运行,但记录器记录的数据直到1天前,这不是常见的模式,有时脚本会在数小时后停止工作,有时会在几天后停止工作,但永远不会被杀死.
所以我的问题是,有没有一种方法我称之为杀死过程kill pid,看看发生了什么?启动验尸调试器会告诉我脚本正在做什么,或者在我杀死它之前它在哪一行?有没有办法接受这个?
我正在尝试在我的日志文件中打印整个堆栈跟踪。这是我为各种课程编写的示例代码。还给出了日志文件的输出。我希望将整个堆栈跟踪记录打印在日志中。
生成异常的第一个示例DAO:
public String getPasswordByEmail(String email) throws UserException {
try {
beginNewTransaction();
PreparedStatement stmt = getConnection().prepareStatement(GET_PASSWORD_BY_EMAIL);
stmt.setString(1, email);
log.debug("PrepareStatement for selecting user password by email " + stmt.toString());
ResultSet rs = stmt.executeQuery();
if(rs != null) {
rs.next();
}
return rs.getString("password");
}
catch(SQLException sqe) {
throw new UserException("Could not retrieve user details",sqe);
} catch (JiffieTransactionException jte) {
throw new UserException("Error while securing the database connection", jte);
}
}
Run Code Online (Sandbox Code Playgroud)
调用DAO的示例服务类:
public String getPasswordByEmail(String email) throws UserException{
UserDAO userDao = new UserDAO();
return …Run Code Online (Sandbox Code Playgroud) 这是一本书中的练习代码,我正在学习try/catch语句.
显示的第一种方法要求load方法检索两个图像.此代码中的错误是资源文件中第一个img的名称称为"welcome.png",但正如您所看到的,它显示为"welcomee.png"(欢迎结束时的额外e).当我运行代码时,它不会打印出catch语句中的代码.它确实显示了堆栈跟踪(因为无论如何都会这样做),但它不会打印出"读取时出错:文件名".为什么是这样?
public class Resources {
public static BufferedImage welcome, iconimage;
public static void load() {
welcome = loadImage("welcomee.png");
iconimage = loadImage("iconimage.png");
}
private static AudioClip loadSound(String filename) {
URL fileURL = Resources.class.getResource("/resources/" + filename);
return Applet.newAudioClip(fileURL);
}
private static BufferedImage loadImage(String filename) {
BufferedImage img = null;
try {
img = ImageIO.read(Resources.class.getResourceAsStream("/resources/" + filename));
} catch (IOException e) {
System.out.println("Error while reading: " + filename);
e.printStackTrace();
}
return img;
}
}
Run Code Online (Sandbox Code Playgroud) 支持哪些浏览器Error.stackTraceLimit,来自哪些版本?是否有任何替代 API 来限制堆栈跟踪长度?
AFAIK。IE10 和当前的 V8:Node、Chrome 都支持它,但我对此知之甚少。我想它与错误 API 的其他部分一样是非标准的。我没有找到任何关于在不同浏览器中设置跟踪长度的替代方法。所以我需要更多关于这个功能的信息,但我没有找到太多使用谷歌...
我熟悉Java异常的基本结构,但是我第一次注意到Class.forName stacktrace的奇怪之处:
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:195)
...
java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
为什么提到了两个forName实例,零表示什么?这是堆栈跟踪如何表示具有不同签名的多个同名方法吗?