I tested my application with FastMM and FullDebugMode turned on, since I had some shutdown problems.
After solving bunch of my own problems FastMM started to complain about calling virtual method on a freed object in TPopupList. I tried to move the menus unit as early as possible in uses so that it would be finalized last, but it didn't help. Is this real problem, a bug in vcl or false alarm from FastMM?
Here's the full report from FastMM:
FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.
Freed object class: TPopupList
Virtual method: Offset +16
Virtual method address: 4714E4
The allocation number was: 220
The object was allocated by thread 0x1CC0, and the stack trace (return addresses) at the time was:
403216 [sys\system.pas][System][System.#GetMem][2654]
404A4F [sys\system.pas][System][System.TObject.NewInstance][8807]
404E16 [sys\system.pas][System][System.#ClassCreate][9472]
404A84 [sys\system.pas][System][System.TObject.Create][8822]
7F2602 [Menus.pas][Menus][Menus.Menus][4223]
40570F [sys\system.pas][System][System.InitUnits][11397]
405777 [sys\system.pas][System][System.#StartExe][11462]
40844F [SysInit.pas][SysInit][SysInit.#InitExe][663]
7F6368 [PCCSServer.dpr][PCCSServer][PCCSServer.PCCSServer][148]
7C90DCBA [ZwSetInformationThread]
7C817077 [Unknown function at RegisterWaitForInputIdle]
The object was subsequently freed by thread 0x1CC0, and the stack trace (return addresses) at the time was:
403232 [sys\system.pas][System][System.#FreeMem][2699]
404A6D [sys\system.pas][System][System.TObject.FreeInstance][8813]
404E61 [sys\system.pas][System][System.#ClassDestroy][9513]
428D15 [common\Classes.pas][Classes][Classes.TList.Destroy][2914]
404AB3 [sys\system.pas][System][System.TObject.Free][8832]
472091 [Menus.pas][Menus][Menus.Finalization][4228]
4056A7 [sys\system.pas][System][System.FinalizeUnits][11256]
4056BF [sys\system.pas][System][System.FinalizeUnits][11261]
7C9032A8 [RtlConvertUlongToLargeInteger]
7C90327A [RtlConvertUlongToLargeInteger]
7C92AA0F [Unknown function at towlower]
The current thread ID is 0x1CC0, and the stack trace (return addresses) leading to this error is:
4714B8 [Menus.pas][Menus][Menus.TPopupList.MainWndProc][3779]
435BB2 [common\Classes.pas][Classes][Classes.StdWndProc][11583]
7E418734 [Unknown function at GetDC]
7E418816 [Unknown function at GetDC]
7E428EA0 [Unknown function at DefWindowProcW]
7E428EEC [Unknown function at DefWindowProcW]
7C90E473 [KiUserCallbackDispatcher]
7E42B1A8 [DestroyWindow]
47CE31 [Controls.pas][Controls][Controls.TWinControl.DestroyWindowHandle][6857]
493BE4 [Forms.pas][Forms][Forms.TCustomForm.DestroyWindowHandle][4564]
4906D9 [Forms.pas][Forms][Forms.TCustomForm.Destroy][2929]
Current memory dump of 256 bytes starting at pointer address 7FF9CFF0:
2C FE 82 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 C4 A3 2D 0C 00 00 00 00 B1 D0 F9 7F
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 00 00 00 16 32 40 00 9D 5B 40 00 C8 5B 40 00
CE 82 40 00 3C 40 91 7C B0 B1 94 7C 0A 77 92 7C 84 77 92 7C 7C F0 96 7C 94 B3 94 7C 84 77 92 7C
C0 1C 00 00 32 32 40 00 12 5B 40 00 EF 69 40 00 BA 20 47 00 A7 56 40 00 BF 56 40 00 A8 32 90 7C
7A 32 90 7C 0F AA 92 7C 0A 77 92 7C 84 77 92 7C C0 1C 00 00 0E 00 00 00 00 00 00 00 C7 35 65 59
2C FE 82 00 80 80 80 80 80 80 80 80 80 80 38 CA 9A A6 80 80 80 80 80 80 00 00 00 00 51 D1 F9 7F
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 00 00 00 16 32 40 00 9D 5B 40 00 C8 5B 40 00
CE 82 40 00 3C 40 91 7C B0 B1 94 7C 0A 77 92 7C 84 77 92 7C 7C F0 96 7C 94 B3 94 7C 84 77 92 7C
, þ ‚ . € € € € € € € € € € € € € € € € Ä £ - . . . . . ± Ð ù
. . . . . . . . . . . . . . . . À . . . . 2 # . [ # . È [ # .
Î ‚ # . < # ‘ | ° ± ” | . w ’ | „ w ’ | | ð – | ” ³ ” | „ w ’ |
À . . . 2 2 # . . [ # . ï i # . º G . § V # . ¿ V # . ¨ 2 |
z 2 | . ª ’ | . w ’ | „ w ’ | À . . . . . . . . . . . Ç 5 e Y
, þ ‚ . € € € € € € € € € € 8 Ê š ¦ € € € € € € . . . . Q Ñ ù
. . . . . . . . . . . . . . . . Á . . . . 2 # . [ # . È [ # .
Î ‚ # . < # ‘ | ° ± ” | . w ’ | „ w ’ | | ð – | ” ³ ” | „ w ’ |
I'm using Delphi 2007 and FastMM 4.97.
Edit1: I think the main problem here is why does Classes.StdWndProc call Menus.TPopupList? Digging the call stack inside debugger shows that System.FinalizeUnit is called three times, then it goes to SysUtils.ShowException, which tries to display MessageBox and after bunch of user32.dll calls we end up to classes.StdWndProc.
Edit2: I had problem with interfaces, fixing that made this problem go away. The object with interface was freed, but the reference was released later on. When the interface was released, occured an exception which I initially somehow ignored. Releasing the interface probably corrupted something which caused all other problems.
That situation can happens when a unit finalize after another unit it indirectly depends on.
For exemple, take the following unit:
unit Unit1;
interface
uses
Contnrs;
var
ItemHolder : TObjectList;
implementation
initialization
ItemHolder := TObjectList.Create(True);
finalization
ItemHolder.Free;
end.
That unit only directly depends on Contnrs. For that reason, delphi will ensure that this unit is finalized before Contnrs is. If the ObjectList contains TForms, Delphi won't ensure that Unit1 is finalized before unit Forms. If there are still some forms left while closing the application, TObjectList (Since it owns the object) will free the items it contains(Call TForm.Free). But since Unit1 doesn't depends on TForm, it's possible that the unit Forms is already finalized and that TForm.Destroy isn't in memory anymore.
This is why you need to be very carefull about what you do in finalization sections.
I'm not sure it's the source of your problem, but I would look that way first.
I've seen such problems with Delphi 2007 before. Sometimes the compiler gets confused and generates incorrect initialization or finalization order. Sadly, I was never able to create a reproducible test case to send to the CodeGear/Embarcadero people.
Whenever that happened, a full rebuild helped.
Make sure that FastMM4 is the FIRST line in your project file's uses clause (project|View source). If its not there, then add it.
It looks like one of your forms is getting destroyed after Menus.pas has been finalized. If your form has a menu on it, it would probably have to have Menus in its uses list in the interface section, which should make this impossible.
The only time I've seen issues like this pop up (no pun intended) is when using packages. Are you perhaps using a DPK with a plugin that adds a popup menu or menu items to your program? Package finalization can do some strange things to your program if you're not careful.
Either way, the solution is probably to dispose of the menu yourself before menus.pas finalizes. When it's time for the program to shut down, call Free on your popup menu and see if that solves the problem.
Update: this is only partial workaround
Workaround:
In main form of your application write
finalization
FreeAndNil(PopupList);
end.
this free PopupList and set to nil, so PopupList.Free in menus.pas will be OK.
Related
A sample TCP hexadecimal Wireshark capture shown below,
0000 6c 6a 77 8d 48 cf 96 38 a7 7d 02 de 08 00 45 28
0010 00 34 56 92 40 00 28 06 fa e9 a2 7d 13 09 c0 a8
0020 8a f1 01 bb df 84 20 00 27 8e e3 6f a9 7f 80 10
0030 00 7c 25 f3 00 00 01 01 08 0a 54 48 f8 cc 61 38
0040 eb 22
How to get to know TCP or UDP protocol from Wireshark pcap hexadecimal view ?.
Save the hex data, as shown, into a text file and then run text2pcap file.txt file.pcap. You can then load the file.pcap file into Wireshark. Run text2pcap -h for more help or refer to the text2pcap man page for more details about that tool.
0000 6c 6a 77 8d 48 cf 96 38 a7 7d 02 de 08 00 45 28
0010 00 34 56 92 40 00 28 06 fa e9 a2 7d 13 09 c0 a8
8th Byte in the second line we have to check. In here it's 06. So protocol number 06 is TCP. Like wise we can get to know the protocol number from hexadecimal view.
My Rails 4.2.1 app has to connect to a Microsoft SQL 2008 R2 database. I am using the tiny_tds gem version 1.0.4. FreeTDS v1.00.15 is installed on the production server running Ubuntu 14.04.
I run queries inside an each loop and I can't get the loop to complete, the process crashes before completion.
I tried playing with tiny_tds options without success.
Here's the code I am using to get the tiny_tds client (check tds_version and timeout options):
client = TinyTds::Client.new(username: db_conf['username'], password: db_conf['password'], host: db_conf['host'], port: db_conf['port'], database: db_conf['database'], tds_version: '7.3', timeout: 15000, appname: 'ERP')
Here's the FreeTDS log after such an error happens.
packet.c:741:Sending packet 0000 12 01 00 ce 00 00 00 00-16 03 01 00
86 10 00 00 |........ ........| 0010 82 00 80 6e d9 e2 dc 97-9d 77 59
9a 5b da e3 e2 |...n.... .wY.[...| 0020 8b aa 66 ed ec 5e e2 02-e5 6c
fd db e1 ef 47 1a |..f..^.. .l....G.| 0030 9d 63 03 ed 6d 3e 28 3b-b9
64 fd 92 71 34 ff ba |.c..m>(; .d..q4..| 0040 7d 3c 8d ee 7b 34 75
e9-d5 b7 c6 83 a9 7d e6 7f |}<..{4u. .....}..| 0050 71 7e 25 11 82 b8
76 b1-c6 ba 86 b4 c3 0a 47 f0 |q~%...v. ......G.| 0060 51 96 c7 e2 5f
ca 07 b2-95 53 b9 9e bb 2c e7 cb |Q..._... .S...,..| 0070 be 0a b5 eb
b0 f3 41 1d-cd 86 fc a6 53 08 5e 56 |......A. ....S.^V| 0080 29 85 79
14 dc 2b 74 7b-b2 43 2c e8 0e 87 60 e4 |).y..+t{ .C,....| 0090 10 ef
f8 14 03 01 00 01-01 16 03 01 00 30 c7 f0 |........ .....0..| 00a0 35
f5 2c 6e 79 8d 85 b9-bd 60 b7 09 8c 7e 29 18 |5.,ny... ....~).| 00b0
4a 56 ea c3 4e 13 bf e3-c5 8d f6 68 31 31 54 ee |JV..N... ...h11T.|
00c0 bf 2f 75 8d e9 9e c0 a9-d0 d2 9e 5b c9 92 |./u..... ...[..|
tls.c:105:in tds_pull_func_login query.c:3796:tds_disconnect()
util.c:165:Changed query state from IDLE to DEAD
util.c:322:tdserror(0x80b75e0, 0xa04ca80, 20017, 0)
dblib.c:7947:dbperror(0xae62780, 20017, 0) dblib.c:8015:dbperror:
Calling dblib_err_handler with msgno = 20017; msg->msgtext =
"Unexpected EOF from the server (192.168.32.105:1433)"
dblib.c:5777:dbgetuserdata(0xae62780) dblib.c:8037:dbperror:
dblib_err_handler for msgno = 20017; msg->msgtext = "Unexpected EOF
from the server (192.168.32.105:1433)" -- returns 2 (INT_CANCEL)
util.c:352:tdserror: client library returned TDS_INT_CANCEL(2)
util.c:375:tdserror: returning TDS_INT_CANCEL(2) util.c:375:tdserror:
returning TDS_INT_CANCEL(2) tls.c:942:handshake failed
login.c:530:login packet rejected util.c:322:tdserror(0x80b75e0,
0xa04ca80, 20002, 0) dblib.c:7947:dbperror(0xae62780, 20002, 0)
dblib.c:8015:dbperror: Calling dblib_err_handler with msgno = 20002;
msg->msgtext = "Adaptive Server connection failed"
And here's the output of tsql -C:
~$ tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v1.00.15
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: auto
iODBC: no
unixodbc: no
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes
GnuTLS: no
MARS: no
Any idea what I should do to fix those Unexpected EOF from the server errors?
In your FreeTDS configuration (often in /etc/freetds/freetds.conf as in your configuration), change the value of text size:
text size = 4294967295
That's the maximum value, IIRC. I believe with FreeTDS 0.91 that your default is probably 64512.
Looking at the SQL Profiler, I found out the Rails application was opening way too many connections on the MSSQL server. Upon reaching its max number of open connection, the MSSQL server refused opening any new connection, resulting in the Unexpected EOF from the server error.
To solve the issue, I had to reuse my open connection when sending queries instead of opening a new connection for each query. I guess this is the correct way to use the tiny_tds connector anyway.
Translated to code:
def self.get_pmi_client
if ##pmi_client.nil? or !##pmi_client.active?
db_conf = Rails.configuration.database_configuration["pmi_#{Rails.env}"]
##pmi_client = TinyTds::Client.new(username: db_conf['username'], password: db_conf['password'], host: db_conf['host'], port: db_conf['port'], database: db_conf['database'])
raise MSSQLConnectionError, t('erp.errors.pmi_connection_error') unless ##pmi_client.active?
end
return ##pmi_client
end
I'm trying to use Bosun to determine if certain processes are running and then eventually alert on if they are up or down. I'm probably misinterpreting the docs but I can't figure this out.
Bosun is running just fine. I have the scollector running on Ubuntu 14 LTS and using my config file correctly.
Here is what I have in my scollector.toml:
host="blah:8070"
hostname="cass01"
[[Process]]
command = "^.*(java).*(CassandraDaemon)$"
name = "Cassandra"
I would then expect to see in bosun under my host cass01 a metric title "cassandra" somewhere but it's nowhere to be seen. Other metrics are there.
Right now Command is a partial match on the process path to the binary, up to the first space delimiter. The Args parameter is a regex to differentiate between multiple instances of the process. So for a java process you would use something like:
[[Process]]
Command = "java"
Name = "Cassandra"
Args = "CassandraDaemon$"
This would match a command line like:
/usr/bin/java /usr/bin/CassandraDaemon
This assumes the /proc/<pid>/cmdline for that process ends in CassandraDaemon. If it doesn't end in that string you would need to change the Args to just "CassandraDaemon" which would match any java process that contains that string.
Also some processes change the cmdline to something other than a nul delimited string. In those cases the Command argument needs to be used to match as Args is expecting nul delimiters. Example:
cat /proc/80156/cmdline | hexdump -C
00000000 2f 75 73 72 2f 62 69 6e 2f 72 65 64 69 73 2d 73 |/usr/bin/redis-s|
00000010 65 72 76 65 72 20 2a 3a 36 33 37 39 00 00 00 00 |erver *:6379....|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 |.|
00000031
#Example for cmdline without NUL (00) delimiters between args
[[Process]]
Command = "redis-server *:6379"
Name = "redis-core"
Once these are in place with the correct matching values you should see metrics show up under linux.proc.* where the the name tag will match the name used in the TOML file.
here is the example
this is the captured packet data
00000000 00 6e 0b 00 .n..
00000004 4d 5a e8 00 00 00 00 5b 52 45 55 89 e5 81 c3 81 MZ.....[ REU.....
00000014 12 00 00 ff d3 89 c3 57 68 04 00 00 00 50 ff d0 .......W h....P..
00000024 68 f0 b5 a2 56 68 05 00 00 00 50 ff d3 00 00 00 h...Vh.. ..P.....
00000034 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00 ........ ........
00000044 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 ........ !..L.!Th
00000054 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is progr am canno
00000064 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 t be run in DOS
00000074 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 mode.... $.......
and i want only the hex part like this
00 6e 0b 00
4d 5a e8 00 00 00 00 5b 52 45 55 89 e5 81 c3 81
12 00 00 ff d3 89 c3 57 68 04 00 00 00 50 ff d0
I try right click on the packet and select copy -> bytes ->hex stream
but the hex data I got doesn't look like the above data at all
so How Can I copy hex data of captured packet form wireshark ?
thanks for reading
On the Wireshark "packet list" panel, right click the packet you want and:
1) if you select Copy->Bytes->Hex stream, you'll get the hex digits as one long string without white spaces
39cb08004528053f000000006f1105faac11745dac11740c039......
2) if you select Copy->Bytes->Offset Hex, you'll get the hex digits as displayed on the GUI , including the offset of each line starting byte (frame offset)
0010 05 3f 00 00 00 00 6f 11 05 fa ac 11 74 5d ac 11
0020 74 0c 03 9e 03 9d 05 2b 00 00 07 e0 8f ee 8f 1c
0030 ff 00 00 00 00 00 09 0f 00 58 39 cb 60 00 00 00
0040 11 80 08 00 73 00 02 44 00 00 00 00 03 dd de de
You can use TShark.
TShark is shipped with Wireshark.
Use command:
tshark -x -r dns.pcapng frame.number == 10
Output:
D:\Wireshark>tshark -r dns.pcapng frame.number == 10 -x
0000 00 25 9c ca 94 fe 90 e6 ba 71 70 03 08 00 45 00 .%.......qp...E.
0010 00 3f 6d 61 00 00 80 11 7d dc 0a 01 01 0a 11 22 .?ma....}......"
0020 33 44 f0 1d 00 35 00 2b be 3e 71 dd 01 00 00 01 3D...5.+.>q.....
0030 00 00 00 00 00 00 0d 73 74 61 63 6b 6f 76 65 72 .......stackover
0040 66 6c 6f 77 03 63 6f 6d 00 00 ff 00 01 flow.com.....
Copy and paste the hex part.
Hope this helps
If there are several packets you're interested in, you can export them to a file.
mark those packets (right click on each packet then Mark Packet (toggle) or Ctrl + M)
choose File > Export > File.... Make sure you select Marked packets.
if you're only interested in the hex data, make sure only Packet Bytes is checked in Packet Format
Note that when exporting you also have the choice with First to last marked as well as Range, if the interesting packets are next to each other.
I try to execute commands on redis but don't care for any response and don't even want any to minimize network traffic. One answer on stackoverflow said a Lua scripts that doesn't return anything could help to achieve that, but when I try it on the redis-cli and sniff my packages I still get the same number of packages transfered between client and server whether I have a script returning nothing or one that returns Integer 1.
The example Queries are:
EVAL "" 0
EVAL "return 1" 0
In both cases wireshark shows 4 packages exchanged. One [PSH, ACK] client to server, [ACK] from the server to the client, [PSH, ACK] from the server to the client and [ACK] back from the client to the server.
In the first case the [PSH, ACK] package that I expect to be the response from redis contains the following data:
0000 02 00 00 00 45 00 00 39 bc a8 40 00 40 06 00 00 ....E..9 ..#.#...
0010 7f 00 00 01 7f 00 00 01 18 eb e6 bb 03 4d 7c 9c ........ .....M|.
0020 e2 97 bf 53 80 18 23 df fe 2d 00 00 01 01 08 0a ...S..#. .-......
0030 11 cd c0 31 11 cd c0 31 24 2d 31 0d 0a ...1...1 $-1..
In the second case this package contains:
0000 02 00 00 00 45 00 00 38 fa 9f 40 00 40 06 00 00 ....E..8 ..#.#...
0010 7f 00 00 01 7f 00 00 01 18 eb e6 bb 03 4d 7c a1 ........ .....M|.
0020 e2 97 bf 76 80 18 23 dd fe 2c 00 00 01 01 08 0a ...v..#. .,......
0030 11 ce be 46 11 ce be 46 3a 31 0d 0a ...F...F :1..
For the second case the point is clear. :1 is the integer reply for 1. But for the first case I'm not sure. $ is the indicator for bulk reply and - the indicator for error. Does this mean that $-1 is the data for the (nil) that is shown in the redis-cli?
Or am I completely wrong there? And if I am right, is there a possibility to tell redis that I don't want any response at all (except the ACK for the command)? Or would I have to fork the redis code and implement this myself?
I really appreciate any hints on how to achieve getting no response at all without digging into the redis source code.
EVAL "" 0 returns $-1\r\n
EVAL "return 1" 0 returns :1\r\n
In the first case, $-1 is a specific bulk-reply to be used to represent the nil value (as described in the protocol specification)
AFAIK, there is no possibility to tell Redis it does not have to send a reply (even for an empty answer).
As explained by Marc Gravell, you can use Lua to bundle several operations and reduce the volume of the reply data. However, you will not avoid the minimal reply packet.
For instance you could run 100 operations in one Lua script and have one single minimal packet as a reply. However, this packet cannot be avoided IMO, except by altering Redis source code.